marketmyna 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. marketmyna/__init__.py +14 -0
  2. marketmyna/agent/__init__.py +8 -0
  3. marketmyna/agent/agents.py +543 -0
  4. marketmyna/agent/context.py +69 -0
  5. marketmyna/agent/dashboard.py +55 -0
  6. marketmyna/agent/orchestrator.py +153 -0
  7. marketmyna/agent/sentiment.py +150 -0
  8. marketmyna/agent/skills.py +119 -0
  9. marketmyna/ai/__init__.py +1 -0
  10. marketmyna/ai/portfolio_optimizer.py +330 -0
  11. marketmyna/analysis/__init__.py +6 -0
  12. marketmyna/analysis/fundamental.py +329 -0
  13. marketmyna/analysis/sip_optimizer.py +81 -0
  14. marketmyna/analysis/technical.py +321 -0
  15. marketmyna/api/__init__.py +1 -0
  16. marketmyna/api/app.py +209 -0
  17. marketmyna/api/deps.py +63 -0
  18. marketmyna/api/middlewares/__init__.py +0 -0
  19. marketmyna/api/middlewares/auth.py +116 -0
  20. marketmyna/api/middlewares/csrf.py +66 -0
  21. marketmyna/api/middlewares/error_handler.py +38 -0
  22. marketmyna/api/middlewares/slashes.py +27 -0
  23. marketmyna/api/v1/__init__.py +0 -0
  24. marketmyna/api/v1/endpoints/__init__.py +0 -0
  25. marketmyna/api/v1/endpoints/account.py +166 -0
  26. marketmyna/api/v1/endpoints/agent.py +114 -0
  27. marketmyna/api/v1/endpoints/bot.py +38 -0
  28. marketmyna/api/v1/endpoints/calendar.py +269 -0
  29. marketmyna/api/v1/endpoints/data_sources.py +174 -0
  30. marketmyna/api/v1/endpoints/health.py +10 -0
  31. marketmyna/api/v1/endpoints/listings.py +564 -0
  32. marketmyna/api/v1/endpoints/macro.py +163 -0
  33. marketmyna/api/v1/endpoints/portfolio.py +530 -0
  34. marketmyna/api/v1/endpoints/push.py +119 -0
  35. marketmyna/api/v1/endpoints/reports.py +49 -0
  36. marketmyna/api/v1/endpoints/scheduler.py +219 -0
  37. marketmyna/api/v1/endpoints/stocks.py +400 -0
  38. marketmyna/api/v1/endpoints/system_config.py +157 -0
  39. marketmyna/api/v1/endpoints/thesis.py +112 -0
  40. marketmyna/api/v1/endpoints/trade.py +709 -0
  41. marketmyna/api/v1/endpoints/updates.py +394 -0
  42. marketmyna/api/v1/endpoints/watchlists.py +179 -0
  43. marketmyna/api/v1/router.py +43 -0
  44. marketmyna/bot/__init__.py +14 -0
  45. marketmyna/bot/commands/__init__.py +0 -0
  46. marketmyna/bot/commands/analyze.py +40 -0
  47. marketmyna/bot/commands/ask.py +51 -0
  48. marketmyna/bot/commands/base.py +35 -0
  49. marketmyna/bot/commands/batch.py +53 -0
  50. marketmyna/bot/commands/common.py +84 -0
  51. marketmyna/bot/commands/help.py +43 -0
  52. marketmyna/bot/commands/markets.py +153 -0
  53. marketmyna/bot/commands/portfolio.py +145 -0
  54. marketmyna/bot/commands/research.py +323 -0
  55. marketmyna/bot/commands/status.py +48 -0
  56. marketmyna/bot/commands/trade.py +176 -0
  57. marketmyna/bot/dispatcher.py +95 -0
  58. marketmyna/bot/formatting.py +25 -0
  59. marketmyna/bot/models.py +27 -0
  60. marketmyna/bot/registry.py +50 -0
  61. marketmyna/bot/telegram_listener.py +227 -0
  62. marketmyna/cli/__init__.py +1 -0
  63. marketmyna/cli/scheduled_run.py +292 -0
  64. marketmyna/core/__init__.py +6 -0
  65. marketmyna/core/compliance.py +53 -0
  66. marketmyna/core/config.py +377 -0
  67. marketmyna/core/constants.py +69 -0
  68. marketmyna/core/home.py +22 -0
  69. marketmyna/core/numbers.py +28 -0
  70. marketmyna/core/secret_store.py +104 -0
  71. marketmyna/core/tenant.py +130 -0
  72. marketmyna/data/__init__.py +8 -0
  73. marketmyna/data/base.py +36 -0
  74. marketmyna/data/categories.py +272 -0
  75. marketmyna/data/china.py +360 -0
  76. marketmyna/data/crypto.py +200 -0
  77. marketmyna/data/ecb_fx.py +131 -0
  78. marketmyna/data/extra_sources.py +569 -0
  79. marketmyna/data/india.py +241 -0
  80. marketmyna/data/india_filings.py +343 -0
  81. marketmyna/data/listings.py +1314 -0
  82. marketmyna/data/mutual_funds.py +34 -0
  83. marketmyna/data/news.py +98 -0
  84. marketmyna/data/news_search.py +346 -0
  85. marketmyna/data/nse_deals.py +138 -0
  86. marketmyna/data/resilience.py +173 -0
  87. marketmyna/data/sec_facts.py +252 -0
  88. marketmyna/data/shariah.py +283 -0
  89. marketmyna/data/social/__init__.py +9 -0
  90. marketmyna/data/social/base.py +100 -0
  91. marketmyna/data/social/browser.py +92 -0
  92. marketmyna/data/social/hackernews.py +53 -0
  93. marketmyna/data/social/reddit.py +397 -0
  94. marketmyna/data/social/stocktwits.py +63 -0
  95. marketmyna/data/social/valuepickr.py +53 -0
  96. marketmyna/data/stocks.py +197 -0
  97. marketmyna/data/yahoo_price.py +48 -0
  98. marketmyna/launcher.py +71 -0
  99. marketmyna/llm/__init__.py +33 -0
  100. marketmyna/llm/backend_factory.py +51 -0
  101. marketmyna/llm/backend_registry.py +19 -0
  102. marketmyna/llm/channels.py +447 -0
  103. marketmyna/llm/json_reply.py +63 -0
  104. marketmyna/llm/litellm_backend.py +197 -0
  105. marketmyna/llm/model_catalog.py +166 -0
  106. marketmyna/llm/model_health.py +193 -0
  107. marketmyna/llm/protocol.py +111 -0
  108. marketmyna/llm/providers.py +128 -0
  109. marketmyna/llm/store.py +128 -0
  110. marketmyna/notifiers/__init__.py +35 -0
  111. marketmyna/notifiers/apprise_sender.py +43 -0
  112. marketmyna/notifiers/astrbot.py +47 -0
  113. marketmyna/notifiers/bark.py +24 -0
  114. marketmyna/notifiers/base.py +80 -0
  115. marketmyna/notifiers/dingtalk.py +54 -0
  116. marketmyna/notifiers/discord.py +39 -0
  117. marketmyna/notifiers/dispatcher.py +153 -0
  118. marketmyna/notifiers/email.py +99 -0
  119. marketmyna/notifiers/feishu.py +57 -0
  120. marketmyna/notifiers/googlechat.py +24 -0
  121. marketmyna/notifiers/gotify.py +36 -0
  122. marketmyna/notifiers/matrix.py +28 -0
  123. marketmyna/notifiers/ntfy.py +36 -0
  124. marketmyna/notifiers/pushbullet.py +24 -0
  125. marketmyna/notifiers/pushover.py +41 -0
  126. marketmyna/notifiers/pushplus.py +41 -0
  127. marketmyna/notifiers/serverchan3.py +40 -0
  128. marketmyna/notifiers/settings_schema.py +119 -0
  129. marketmyna/notifiers/signal_messenger.py +25 -0
  130. marketmyna/notifiers/slack.py +36 -0
  131. marketmyna/notifiers/teams.py +37 -0
  132. marketmyna/notifiers/telegram.py +81 -0
  133. marketmyna/notifiers/twilio.py +33 -0
  134. marketmyna/notifiers/webhook.py +44 -0
  135. marketmyna/notifiers/webpush.py +222 -0
  136. marketmyna/notifiers/wechat.py +40 -0
  137. marketmyna/notifiers/whatsapp.py +27 -0
  138. marketmyna/portfolio/__init__.py +6 -0
  139. marketmyna/portfolio/analytics.py +336 -0
  140. marketmyna/portfolio/manager.py +383 -0
  141. marketmyna/portfolio/models.py +155 -0
  142. marketmyna/portfolio/optimizers.py +88 -0
  143. marketmyna/portfolio/review.py +411 -0
  144. marketmyna/services/__init__.py +1 -0
  145. marketmyna/services/accounts.py +278 -0
  146. marketmyna/services/ai_access.py +94 -0
  147. marketmyna/services/analysis_run.py +491 -0
  148. marketmyna/services/big_trades.py +335 -0
  149. marketmyna/services/brokers/__init__.py +0 -0
  150. marketmyna/services/brokers/angel.py +271 -0
  151. marketmyna/services/brokers/finnhub.py +209 -0
  152. marketmyna/services/byok_detect.py +196 -0
  153. marketmyna/services/calendar.py +748 -0
  154. marketmyna/services/central_banks.py +202 -0
  155. marketmyna/services/commodities.py +134 -0
  156. marketmyna/services/compare.py +307 -0
  157. marketmyna/services/cot.py +148 -0
  158. marketmyna/services/country_macro.py +135 -0
  159. marketmyna/services/crude_sensitivity.py +239 -0
  160. marketmyna/services/crypto_mood.py +135 -0
  161. marketmyna/services/crypto_screens.py +226 -0
  162. marketmyna/services/data_export.py +91 -0
  163. marketmyna/services/dcf.py +220 -0
  164. marketmyna/services/dcf_model.py +194 -0
  165. marketmyna/services/delivery.py +142 -0
  166. marketmyna/services/discovery.py +146 -0
  167. marketmyna/services/dividends.py +95 -0
  168. marketmyna/services/earnings.py +305 -0
  169. marketmyna/services/econ_calendar.py +495 -0
  170. marketmyna/services/eia_stocks.py +115 -0
  171. marketmyna/services/estimates.py +109 -0
  172. marketmyna/services/etf.py +236 -0
  173. marketmyna/services/etf_rotation.py +193 -0
  174. marketmyna/services/etf_screens.py +196 -0
  175. marketmyna/services/financials.py +639 -0
  176. marketmyna/services/fund_ai.py +181 -0
  177. marketmyna/services/fund_analytics.py +371 -0
  178. marketmyna/services/fund_cost.py +147 -0
  179. marketmyna/services/fund_holdings.py +664 -0
  180. marketmyna/services/fund_peers.py +247 -0
  181. marketmyna/services/fund_rotation.py +206 -0
  182. marketmyna/services/fund_style.py +179 -0
  183. marketmyna/services/funds.py +70 -0
  184. marketmyna/services/hot_stocks.py +358 -0
  185. marketmyna/services/india_flows.py +263 -0
  186. marketmyna/services/india_rates.py +258 -0
  187. marketmyna/services/investor_lenses.py +271 -0
  188. marketmyna/services/leadership.py +165 -0
  189. marketmyna/services/live_market.py +497 -0
  190. marketmyna/services/live_quotes.py +295 -0
  191. marketmyna/services/macro.py +182 -0
  192. marketmyna/services/market_calendar.py +399 -0
  193. marketmyna/services/market_mood.py +168 -0
  194. marketmyna/services/market_valuation.py +231 -0
  195. marketmyna/services/mf_holdings.py +199 -0
  196. marketmyna/services/mf_insights.py +132 -0
  197. marketmyna/services/mf_lumpsum.py +587 -0
  198. marketmyna/services/mf_portfolio_ai.py +195 -0
  199. marketmyna/services/nse_events.py +98 -0
  200. marketmyna/services/overview.py +366 -0
  201. marketmyna/services/ownership.py +143 -0
  202. marketmyna/services/quality_scores.py +199 -0
  203. marketmyna/services/rates.py +335 -0
  204. marketmyna/services/reconcile.py +343 -0
  205. marketmyna/services/report.py +584 -0
  206. marketmyna/services/report_i18n.py +678 -0
  207. marketmyna/services/rotation.py +224 -0
  208. marketmyna/services/runtime_scheduler.py +548 -0
  209. marketmyna/services/schedule_config.py +251 -0
  210. marketmyna/services/schedule_time.py +39 -0
  211. marketmyna/services/screens.py +398 -0
  212. marketmyna/services/sec_mdna.py +173 -0
  213. marketmyna/services/shariah.py +246 -0
  214. marketmyna/services/sip.py +148 -0
  215. marketmyna/services/sip_days.py +362 -0
  216. marketmyna/services/smart_file.py +595 -0
  217. marketmyna/services/smart_pdf.py +425 -0
  218. marketmyna/services/smart_report.py +370 -0
  219. marketmyna/services/social_sentiment.py +511 -0
  220. marketmyna/services/thesis.py +328 -0
  221. marketmyna/services/translate.py +146 -0
  222. marketmyna/services/valuation.py +173 -0
  223. marketmyna/services/worker_pool.py +149 -0
  224. marketmyna/services/world_markets.py +208 -0
  225. marketmyna/storage.py +722 -0
  226. marketmyna/strategies/README.md +51 -0
  227. marketmyna/strategies/bottom_volume.yaml +49 -0
  228. marketmyna/strategies/box_oscillation.yaml +69 -0
  229. marketmyna/strategies/bull_trend.yaml +49 -0
  230. marketmyna/strategies/chan_theory.yaml +58 -0
  231. marketmyna/strategies/dragon_head.yaml +44 -0
  232. marketmyna/strategies/emotion_cycle.yaml +79 -0
  233. marketmyna/strategies/event_driven.yaml +54 -0
  234. marketmyna/strategies/expectation_repricing.yaml +54 -0
  235. marketmyna/strategies/growth_quality.yaml +54 -0
  236. marketmyna/strategies/hot_theme.yaml +54 -0
  237. marketmyna/strategies/ma_golden_cross.yaml +46 -0
  238. marketmyna/strategies/one_yang_three_yin.yaml +37 -0
  239. marketmyna/strategies/shrink_pullback.yaml +46 -0
  240. marketmyna/strategies/volume_breakout.yaml +47 -0
  241. marketmyna/strategies/wave_theory.yaml +64 -0
  242. marketmyna/trading/__init__.py +2 -0
  243. marketmyna/trading/alerts.py +356 -0
  244. marketmyna/trading/backtest.py +317 -0
  245. marketmyna/trading/charges.py +82 -0
  246. marketmyna/trading/chart.py +197 -0
  247. marketmyna/trading/indicators.py +303 -0
  248. marketmyna/trading/journal.py +74 -0
  249. marketmyna/trading/knn.py +164 -0
  250. marketmyna/trading/lots.py +109 -0
  251. marketmyna/trading/market_hours.py +66 -0
  252. marketmyna/trading/options.py +554 -0
  253. marketmyna/trading/pairs.py +94 -0
  254. marketmyna/trading/risk.py +170 -0
  255. marketmyna/trading/scanner.py +500 -0
  256. marketmyna/trading/volatility.py +163 -0
  257. marketmyna/utils/__init__.py +1 -0
  258. marketmyna/utils/deadline.py +36 -0
  259. marketmyna/utils/log_redact.py +52 -0
  260. marketmyna/utils/yahoo_gate.py +183 -0
  261. marketmyna/utils/yf_lock.py +12 -0
  262. marketmyna/web/apple-touch-icon.png +0 -0
  263. marketmyna/web/assets/Account-CA9NFDKO.js +1 -0
  264. marketmyna/web/assets/Analyze-uM0srB_U.js +7 -0
  265. marketmyna/web/assets/AreaChart-2i67V6Jf.js +1 -0
  266. marketmyna/web/assets/BarChart-_yngarVl.js +3 -0
  267. marketmyna/web/assets/Bot-E4gpf1qZ.js +1 -0
  268. marketmyna/web/assets/CandleChart-CioqTqMV.js +1 -0
  269. marketmyna/web/assets/Compare-D6_2CPl4.js +1 -0
  270. marketmyna/web/assets/ExportMenu-DaZ1xVmW.js +1 -0
  271. marketmyna/web/assets/LineChart-BaOkD1Ta.js +57 -0
  272. marketmyna/web/assets/Markets-BMw_M1sJ.js +1 -0
  273. marketmyna/web/assets/Portfolio-DQEdHVc2.js +1 -0
  274. marketmyna/web/assets/ReportView-BzhdcqSh.js +1 -0
  275. marketmyna/web/assets/Scheduler-I9PDKxTd.js +1 -0
  276. marketmyna/web/assets/Settings-DpXfHolW.js +3 -0
  277. marketmyna/web/assets/SipDays-C9q3bNSx.js +1 -0
  278. marketmyna/web/assets/SymbolSearch-CBOVPEk1.js +1 -0
  279. marketmyna/web/assets/Trade-_CM7HC4H.js +2 -0
  280. marketmyna/web/assets/TradeChart-ZjsycacC.js +1 -0
  281. marketmyna/web/assets/WatchButton-ComYW56_.js +1 -0
  282. marketmyna/web/assets/Watchlist-DAjLb0jd.js +1 -0
  283. marketmyna/web/assets/app-BP1o7WZS.js +1 -0
  284. marketmyna/web/assets/app-BkIUKdld.js +1 -0
  285. marketmyna/web/assets/app-CKeSYhEt.js +1 -0
  286. marketmyna/web/assets/app-CN1OERYX.js +1 -0
  287. marketmyna/web/assets/app-DIQllha5.js +1 -0
  288. marketmyna/web/assets/app-DeiAW0tX.js +1 -0
  289. marketmyna/web/assets/br-Cu5YU29T.svg +45 -0
  290. marketmyna/web/assets/browser-CR-ks2Fp.js +19 -0
  291. marketmyna/web/assets/browser-D5K_K_gj.js +1 -0
  292. marketmyna/web/assets/common-0wvpAVpd.js +1 -0
  293. marketmyna/web/assets/common-3ghy53Us.js +1 -0
  294. marketmyna/web/assets/common-Bib2unjX.js +1 -0
  295. marketmyna/web/assets/common-BvSJP0w_.js +1 -0
  296. marketmyna/web/assets/common-CSfyC0Sp.js +1 -0
  297. marketmyna/web/assets/common-C_t-iZPf.js +1 -0
  298. marketmyna/web/assets/compare-DMcsx70H.js +1 -0
  299. marketmyna/web/assets/es-d5m8M5h8.svg +544 -0
  300. marketmyna/web/assets/exporter-DiMg2O5d.js +3 -0
  301. marketmyna/web/assets/files-CpgiZRbN.js +1 -0
  302. marketmyna/web/assets/format-d8InM0Zw.js +9 -0
  303. marketmyna/web/assets/html2canvas-Bw0OShmD.js +5 -0
  304. marketmyna/web/assets/index-CKAnq-Or.js +12 -0
  305. marketmyna/web/assets/index-D4U8E6LH.css +2 -0
  306. marketmyna/web/assets/index.es-iBEw7jOv.js +5 -0
  307. marketmyna/web/assets/ir-cCIgaNf6.svg +219 -0
  308. marketmyna/web/assets/jspdf.es.min-C4285IdL.js +79 -0
  309. marketmyna/web/assets/jspdf.plugin.autotable-2eOJeXl-.js +2 -0
  310. marketmyna/web/assets/lightweight-charts.production-BF2noug5.js +1 -0
  311. marketmyna/web/assets/listings-BefgXpb1.js +1 -0
  312. marketmyna/web/assets/liveQuotes-CtSmCUFA.js +1 -0
  313. marketmyna/web/assets/markets-BI4AhI9W.js +1 -0
  314. marketmyna/web/assets/markets-BUHUdYpT.js +1 -0
  315. marketmyna/web/assets/markets-BqvN1Bvf.js +1 -0
  316. marketmyna/web/assets/markets-DPO40TTe.js +1 -0
  317. marketmyna/web/assets/markets-bsiPo-Tk.js +1 -0
  318. marketmyna/web/assets/markets-ff1e792u.js +1 -0
  319. marketmyna/web/assets/montecarlo-BsNlH2qe.js +1 -0
  320. marketmyna/web/assets/options-BYAZnwzW.js +1 -0
  321. marketmyna/web/assets/preload-helper-BLdHbfdN.js +1 -0
  322. marketmyna/web/assets/purify.es-Dqk5qvad.js +3 -0
  323. marketmyna/web/assets/rolldown-runtime-XKyaHtl9.js +1 -0
  324. marketmyna/web/assets/sa-Dh79zbT9.svg +25 -0
  325. marketmyna/web/assets/toast-DDradTZw.js +1 -0
  326. marketmyna/web/assets/trade-fndw1Ql3.js +1 -0
  327. marketmyna/web/assets/ui-gsFb8B2m.js +1 -0
  328. marketmyna/web/assets/watchlists-B6YqwUIk.js +1 -0
  329. marketmyna/web/brand/logo-mark.webp +0 -0
  330. marketmyna/web/favicon.png +0 -0
  331. marketmyna/web/icon-192.png +0 -0
  332. marketmyna/web/icon-512.png +0 -0
  333. marketmyna/web/index.html +34 -0
  334. marketmyna/web/manifest.webmanifest +28 -0
  335. marketmyna/web/robots.txt +2 -0
  336. marketmyna/web/sw.js +40 -0
  337. marketmyna/web/theme-init.js +37 -0
  338. marketmyna-0.2.0.dist-info/METADATA +345 -0
  339. marketmyna-0.2.0.dist-info/RECORD +344 -0
  340. marketmyna-0.2.0.dist-info/WHEEL +5 -0
  341. marketmyna-0.2.0.dist-info/entry_points.txt +2 -0
  342. marketmyna-0.2.0.dist-info/licenses/LICENSE +202 -0
  343. marketmyna-0.2.0.dist-info/licenses/NOTICE +22 -0
  344. marketmyna-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,678 @@
1
+ """Report translations.
2
+
3
+ Two tiers:
4
+ - BUILTIN languages have every fixed label of the report translated here,
5
+ so the report is readable in that language even with no AI configured.
6
+ - AI_ONLY languages have no built-in labels; the report is built in English
7
+ and the configured LLM translates it (marketmyna/services/report.py).
8
+
9
+ Free text (AI commentary, news headlines) is only translated when an LLM
10
+ is configured, for every language.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ # code -> (native name, English name)
16
+ BUILTIN_LANGUAGES: dict[str, tuple[str, str]] = {
17
+ "en": ("English", "English"),
18
+ "hi": ("हिन्दी", "Hindi"),
19
+ "ta": ("தமிழ்", "Tamil"),
20
+ "te": ("తెలుగు", "Telugu"),
21
+ "kn": ("ಕನ್ನಡ", "Kannada"),
22
+ "ml": ("മലയാളം", "Malayalam"),
23
+ "mr": ("मराठी", "Marathi"),
24
+ "bn": ("বাংলা", "Bengali"),
25
+ "gu": ("ગુજરાતી", "Gujarati"),
26
+ "pa": ("ਪੰਜਾਬੀ", "Punjabi"),
27
+ "ur": ("اردو", "Urdu"),
28
+ "or": ("ଓଡ଼ିଆ", "Odia"),
29
+ "zh": ("简体中文", "Chinese (Simplified)"),
30
+ "ja": ("日本語", "Japanese"),
31
+ "ko": ("한국어", "Korean"),
32
+ "es": ("Español", "Spanish"),
33
+ "fr": ("Français", "French"),
34
+ "de": ("Deutsch", "German"),
35
+ "pt": ("Português", "Portuguese"),
36
+ "ru": ("Русский", "Russian"),
37
+ "ar": ("العربية", "Arabic"),
38
+ "id": ("Bahasa Indonesia", "Indonesian"),
39
+ }
40
+
41
+ AI_ONLY_LANGUAGES: dict[str, tuple[str, str]] = {
42
+ "it": ("Italiano", "Italian"),
43
+ "nl": ("Nederlands", "Dutch"),
44
+ "tr": ("Türkçe", "Turkish"),
45
+ "vi": ("Tiếng Việt", "Vietnamese"),
46
+ "th": ("ไทย", "Thai"),
47
+ "pl": ("Polski", "Polish"),
48
+ "fa": ("فارسی", "Persian"),
49
+ "ms": ("Bahasa Melayu", "Malay"),
50
+ "zh-TW": ("繁體中文", "Chinese (Traditional)"),
51
+ "ne": ("नेपाली", "Nepali"),
52
+ }
53
+
54
+ LANGUAGES = {**BUILTIN_LANGUAGES, **AI_ONLY_LANGUAGES}
55
+
56
+ # Label keys, in English. {placeholders} are filled by the report builder.
57
+ _EN = {
58
+ "title": "MarketMyna daily report",
59
+ "analysis": "{mode} analysis",
60
+ "mode_quick": "Quick", "mode_standard": "Standard", "mode_full": "Full", "mode_specialist": "Specialist",
61
+ "calls": "Today's calls",
62
+ "buy": "Buy", "hold": "Hold", "sell": "Sell", "incomplete": "Incomplete",
63
+ "market_overview": "Market overview",
64
+ "price": "Price", "target": "Target", "stop": "Stop", "range_52w": "52-week range",
65
+ "ai_view": "AI view", "ai_unavailable": "AI summary unavailable",
66
+ "technical": "Technical", "indicators": "Indicators",
67
+ "fundamentals": "Fundamentals", "score": "Score", "valuation": "Valuation", "pe": "P/E",
68
+ "roe": "ROE", "health": "Financial health", "revenue_growth": "Revenue growth", "dividend_yield": "Dividend yield",
69
+ "risk": "Risk", "volatility": "Volatility", "drawdown": "Max drawdown",
70
+ "analysts": "Analysts", "avg_target": "avg target", "n_analysts": "{n} analysts",
71
+ "upcoming": "Upcoming", "earnings": "Earnings", "ex_dividend": "Ex-dividend",
72
+ "news": "News",
73
+ "funds": "Mutual funds", "nav": "NAV",
74
+ "smart_top": "Top {n} stocks to watch today", "full_report": "Full report for all {n} stocks",
75
+ "week": "1-week",
76
+ "disclaimer": "Not investment advice. Sent by MarketMyna.",
77
+ "normal": "Normal range",
78
+ "reading_positive": "bullish", "reading_mixed": "neutral", "reading_negative": "bearish",
79
+ "reading_note": "ℹ️ This shows what the data reads, not a buy or sell call. ▲ bullish / ▼ bearish "
80
+ "= how most indicators lean today.",
81
+ # Public (analytics) deploys: facts and comparisons, no calls (other languages fall back to these)
82
+ "movers": "Movers in your list",
83
+ "up_most": "Up most",
84
+ "down_most": "Down most",
85
+ "near_high": "Within 3% of 52-week high",
86
+ "near_low": "Within 3% of 52-week low",
87
+ "ai_summary": "AI summary",
88
+ "readings": "Technical readings",
89
+ "outlook": "AI outlook",
90
+ "consensus_src": "Broker consensus of third-party analysts",
91
+ "valuation_vs_sector": "Valuation vs sector",
92
+ "zone_below": "Below sector",
93
+ "zone_in_line": "In line with sector",
94
+ "zone_above": "Above sector",
95
+ "zone_below_personal": "Undervalued",
96
+ "zone_in_line_personal": "Fairly valued",
97
+ "zone_above_personal": "Overvalued",
98
+ "dip_check": "Dip check",
99
+ "lumpsum_strong": "Lumpsum opportunity",
100
+ "lumpsum_watch": "Worth watching for a lumpsum",
101
+ "english_note": "Some details are in English (set up an AI model to translate them).",
102
+ # Added 2026-10-09: trader / investor report sections
103
+ "support": "Support", "resistance": "Resistance", "normal_range": "Normal range", "week_range": "1-week range",
104
+ "today": "today", "total_gain": "Total gain",
105
+ "your_alerts": "Your alerts", "alerts_fired": "{n} fired since the last report",
106
+ "alerts_near": "Close to their trigger", "alerts_quiet": "{n} active, none close to triggering",
107
+ "hot_trade": "Hot for trading", "hot_invest": "Trending for investors",
108
+ }
109
+
110
+ # Words that appear as values (signals, levels, ratings).
111
+ # Labels added for public (analytics) deploys on 2026-10-03; until translated,
112
+ # every language shows these in English (t() falls back to _EN).
113
+ PENDING_TRANSLATION = {
114
+ "outlook", "movers", "up_most", "down_most", "near_high", "near_low", "ai_summary", "readings", "consensus_src",
115
+ "valuation_vs_sector", "zone_below", "zone_in_line", "zone_above",
116
+ "zone_below_personal", "zone_in_line_personal", "zone_above_personal",
117
+ "dip_check", "lumpsum_strong", "lumpsum_watch",
118
+ "support", "resistance", "normal_range", "week_range", "today", "total_gain",
119
+ "your_alerts", "alerts_fired", "alerts_near", "alerts_quiet", "hot_trade", "hot_invest",
120
+ }
121
+
122
+ _EN_VALUES = {
123
+ "bullish": "bullish", "bearish": "bearish", "neutral": "neutral",
124
+ "low": "low", "medium": "medium", "high": "high",
125
+ "strong_buy": "strong buy", "buy": "buy", "hold": "hold", "sell": "sell", "strong_sell": "strong sell",
126
+ "underperform": "underperform", "outperform": "outperform",
127
+ "undervalued": "undervalued", "fair": "fair", "overvalued": "overvalued",
128
+ "good": "good", "average": "average", "poor": "poor", "moderate": "moderate",
129
+ }
130
+
131
+ _STRINGS: dict[str, dict[str, str]] = {
132
+ "hi": {
133
+ "title": "MarketMyna दैनिक रिपोर्ट", "analysis": "{mode} विश्लेषण",
134
+ "mode_quick": "त्वरित", "mode_standard": "मानक", "mode_full": "पूर्ण", "mode_specialist": "विशेषज्ञ",
135
+ "calls": "आज की सलाह", "buy": "खरीदें", "hold": "होल्ड करें", "sell": "बेचें", "incomplete": "अधूरा",
136
+ "market_overview": "बाज़ार का हाल", "price": "भाव", "target": "लक्ष्य", "stop": "स्टॉप लॉस",
137
+ "range_52w": "52-सप्ताह दायरा", "ai_view": "AI की राय", "ai_unavailable": "AI निर्णय उपलब्ध नहीं",
138
+ "technical": "तकनीकी", "indicators": "संकेतक", "fundamentals": "फंडामेंटल्स", "score": "स्कोर",
139
+ "valuation": "मूल्यांकन", "pe": "P/E", "roe": "ROE", "health": "वित्तीय स्थिति",
140
+ "revenue_growth": "राजस्व वृद्धि", "dividend_yield": "लाभांश प्रतिफल", "risk": "जोखिम",
141
+ "volatility": "अस्थिरता", "drawdown": "अधिकतम गिरावट", "analysts": "विश्लेषक",
142
+ "avg_target": "औसत लक्ष्य", "n_analysts": "{n} विश्लेषक", "upcoming": "आगामी", "earnings": "नतीजे",
143
+ "ex_dividend": "एक्स-डिविडेंड", "news": "समाचार",
144
+ "funds": "म्यूचुअल फंड", "nav": "NAV",
145
+ "smart_top": "आज के शीर्ष {n} शेयर", "full_report": "सभी {n} शेयरों की पूरी रिपोर्ट", "week": "1 सप्ताह",
146
+ "disclaimer": "यह निवेश सलाह नहीं है। MarketMyna द्वारा भेजा गया।",
147
+ "normal": "सामान्य दायरा",
148
+ "reading_positive": "तेज़ी", "reading_mixed": "तटस्थ", "reading_negative": "मंदी",
149
+ "reading_note": "ℹ️ यह आंकड़ों की स्थिति बताता है, खरीदने या बेचने की सलाह नहीं। ▲ तेज़ी / ▼ मंदी = आज ज़्यादातर संकेतकों का झुकाव।",
150
+ "english_note": "कुछ विवरण अंग्रेज़ी में हैं (अनुवाद के लिए AI मॉडल सेट करें)।",
151
+ },
152
+ "ta": {
153
+ "title": "MarketMyna தினசரி அறிக்கை", "analysis": "{mode} பகுப்பாய்வு",
154
+ "mode_quick": "விரைவு", "mode_standard": "நிலையான", "mode_full": "முழு", "mode_specialist": "நிபுணர்",
155
+ "calls": "இன்றைய பரிந்துரைகள்", "buy": "வாங்கவும்", "hold": "வைத்திருக்கவும்", "sell": "விற்கவும்",
156
+ "incomplete": "முழுமையற்றது", "market_overview": "சந்தை நிலவரம்", "price": "விலை", "target": "இலக்கு",
157
+ "stop": "ஸ்டாப் லாஸ்", "range_52w": "52 வார வரம்பு", "ai_view": "AI பார்வை",
158
+ "ai_unavailable": "AI முடிவு கிடைக்கவில்லை", "technical": "தொழில்நுட்பம்", "indicators": "குறிகாட்டிகள்",
159
+ "fundamentals": "அடிப்படைகள்", "score": "மதிப்பெண்", "valuation": "மதிப்பீடு", "pe": "P/E", "roe": "ROE",
160
+ "health": "நிதி நிலை", "revenue_growth": "வருவாய் வளர்ச்சி", "dividend_yield": "ஈவுத்தொகை வருவாய்",
161
+ "risk": "அபாயம்", "volatility": "ஏற்ற இறக்கம்", "drawdown": "அதிகபட்ச வீழ்ச்சி", "analysts": "ஆய்வாளர்கள்",
162
+ "avg_target": "சராசரி இலக்கு", "n_analysts": "{n} ஆய்வாளர்கள்", "upcoming": "வரவிருப்பவை",
163
+ "earnings": "நிதி முடிவுகள்", "ex_dividend": "எக்ஸ்-டிவிடெண்ட்", "news": "செய்திகள்",
164
+ "funds": "மியூச்சுவல் ஃபண்டுகள்", "nav": "NAV",
165
+ "smart_top": "இன்று கவனிக்க வேண்டிய முதல் {n} பங்குகள்", "full_report": "அனைத்து {n} பங்குகளின் முழு அறிக்கை", "week": "1 வாரம்",
166
+ "disclaimer": "இது முதலீட்டு ஆலோசனை அல்ல. MarketMyna அனுப்பியது.",
167
+ "normal": "இயல்பான வரம்பு",
168
+ "reading_positive": "ஏற்றம்", "reading_mixed": "நடுநிலை", "reading_negative": "இறக்கம்",
169
+ "reading_note": "ℹ️ இது தரவு காட்டுவதை விவரிக்கிறது, வாங்க அல்லது விற்க பரிந்துரை அல்ல. ▲ ஏற்றம் / ▼ இறக்கம் = இன்று பெரும்பாலான குறிகாட்டிகளின் சாய்வு.",
170
+ "english_note": "சில விவரங்கள் ஆங்கிலத்தில் உள்ளன (மொழிபெயர்க்க AI மாதிரியை அமைக்கவும்).",
171
+ },
172
+ "te": {
173
+ "title": "MarketMyna రోజువారీ నివేదిక", "analysis": "{mode} విశ్లేషణ",
174
+ "mode_quick": "త్వరిత", "mode_standard": "ప్రామాణిక", "mode_full": "పూర్తి", "mode_specialist": "నిపుణ",
175
+ "calls": "నేటి సిఫార్సులు", "buy": "కొనండి", "hold": "ఉంచుకోండి", "sell": "అమ్మండి", "incomplete": "అసంపూర్ణం",
176
+ "market_overview": "మార్కెట్ స్థితి", "price": "ధర", "target": "లక్ష్యం", "stop": "స్టాప్ లాస్",
177
+ "range_52w": "52 వారాల పరిధి", "ai_view": "AI అభిప్రాయం", "ai_unavailable": "AI నిర్ణయం అందుబాటులో లేదు",
178
+ "technical": "టెక్నికల్", "indicators": "సూచికలు", "fundamentals": "ఫండమెంటల్స్", "score": "స్కోరు",
179
+ "valuation": "విలువ", "pe": "P/E", "roe": "ROE", "health": "ఆర్థిక స్థితి", "revenue_growth": "ఆదాయ వృద్ధి",
180
+ "dividend_yield": "డివిడెండ్ రాబడి", "risk": "రిస్క్", "volatility": "అస్థిరత", "drawdown": "గరిష్ఠ పతనం",
181
+ "analysts": "విశ్లేషకులు", "avg_target": "సగటు లక్ష్యం", "n_analysts": "{n} విశ్లేషకులు",
182
+ "upcoming": "రాబోయేవి", "earnings": "ఫలితాలు", "ex_dividend": "ఎక్స్-డివిడెండ్", "news": "వార్తలు",
183
+ "funds": "మ్యూచువల్ ఫండ్లు", "nav": "NAV",
184
+ "smart_top": "నేడు గమనించాల్సిన టాప్ {n} షేర్లు", "full_report": "మొత్తం {n} షేర్ల పూర్తి నివేదిక", "week": "1 వారం",
185
+ "disclaimer": "ఇది పెట్టుబడి సలహా కాదు. MarketMyna పంపింది.",
186
+ "normal": "సాధారణ పరిధి",
187
+ "reading_positive": "బుల్లిష్", "reading_mixed": "తటస్థం", "reading_negative": "బేరిష్",
188
+ "reading_note": "ℹ️ ఇది డేటా చూపేదాన్ని వివరిస్తుంది, కొనమని లేదా అమ్మమని సలహా కాదు. ▲ బుల్లిష్ / ▼ బేరిష్ = ఈరోజు చాలా సూచికల మొగ్గు.",
189
+ "english_note": "కొన్ని వివరాలు ఇంగ్లీష్‌లో ఉన్నాయి (అనువాదానికి AI మోడల్‌ను సెట్ చేయండి).",
190
+ },
191
+ "kn": {
192
+ "title": "MarketMyna ದೈನಂದಿನ ವರದಿ", "analysis": "{mode} ವಿಶ್ಲೇಷಣೆ",
193
+ "mode_quick": "ತ್ವರಿತ", "mode_standard": "ಪ್ರಮಾಣಿತ", "mode_full": "ಪೂರ್ಣ", "mode_specialist": "ತಜ್ಞ",
194
+ "calls": "ಇಂದಿನ ಶಿಫಾರಸುಗಳು", "buy": "ಖರೀದಿಸಿ", "hold": "ಇಟ್ಟುಕೊಳ್ಳಿ", "sell": "ಮಾರಾಟ ಮಾಡಿ", "incomplete": "ಅಪೂರ್ಣ",
195
+ "market_overview": "ಮಾರುಕಟ್ಟೆ ಸ್ಥಿತಿ", "price": "ಬೆಲೆ", "target": "ಗುರಿ", "stop": "ಸ್ಟಾಪ್ ಲಾಸ್",
196
+ "range_52w": "52 ವಾರಗಳ ವ್ಯಾಪ್ತಿ", "ai_view": "AI ಅಭಿಪ್ರಾಯ", "ai_unavailable": "AI ನಿರ್ಧಾರ ಲಭ್ಯವಿಲ್ಲ",
197
+ "technical": "ತಾಂತ್ರಿಕ", "indicators": "ಸೂಚಕಗಳು", "fundamentals": "ಮೂಲಭೂತ ಅಂಶಗಳು", "score": "ಅಂಕ",
198
+ "valuation": "ಮೌಲ್ಯಮಾಪನ", "pe": "P/E", "roe": "ROE", "health": "ಆರ್ಥಿಕ ಸ್ಥಿತಿ", "revenue_growth": "ಆದಾಯ ಬೆಳವಣಿಗೆ",
199
+ "dividend_yield": "ಲಾಭಾಂಶ ಇಳುವರಿ", "risk": "ಅಪಾಯ", "volatility": "ಏರಿಳಿತ", "drawdown": "ಗರಿಷ್ಠ ಕುಸಿತ",
200
+ "analysts": "ವಿಶ್ಲೇಷಕರು", "avg_target": "ಸರಾಸರಿ ಗುರಿ", "n_analysts": "{n} ವಿಶ್ಲೇಷಕರು",
201
+ "upcoming": "ಮುಂಬರುವವು", "earnings": "ಫಲಿತಾಂಶ", "ex_dividend": "ಎಕ್ಸ್-ಡಿವಿಡೆಂಡ್", "news": "ಸುದ್ದಿ",
202
+ "funds": "ಮ್ಯೂಚುವಲ್ ಫಂಡ್‌ಗಳು", "nav": "NAV",
203
+ "smart_top": "ಇಂದು ಗಮನಿಸಬೇಕಾದ ಟಾಪ್ {n} ಷೇರುಗಳು", "full_report": "ಎಲ್ಲಾ {n} ಷೇರುಗಳ ಪೂರ್ಣ ವರದಿ", "week": "1 ವಾರ",
204
+ "disclaimer": "ಇದು ಹೂಡಿಕೆ ಸಲಹೆಯಲ್ಲ. MarketMyna ಕಳುಹಿಸಿದೆ.",
205
+ "normal": "ಸಾಮಾನ್ಯ ವ್ಯಾಪ್ತಿ",
206
+ "reading_positive": "ಏರಿಕೆ", "reading_mixed": "ತಟಸ್ಥ", "reading_negative": "ಇಳಿಕೆ",
207
+ "reading_note": "ℹ️ ಇದು ದತ್ತಾಂಶ ತೋರಿಸುವುದನ್ನು ವಿವರಿಸುತ್ತದೆ, ಖರೀದಿ ಅಥವಾ ಮಾರಾಟದ ಸಲಹೆಯಲ್ಲ. ▲ ಏರಿಕೆ / ▼ ಇಳಿಕೆ = ಇಂದು ಹೆಚ್ಚಿನ ಸೂಚಕಗಳ ಒಲವು.",
208
+ "english_note": "ಕೆಲವು ವಿವರಗಳು ಇಂಗ್ಲಿಷ್‌ನಲ್ಲಿವೆ (ಅನುವಾದಕ್ಕೆ AI ಮಾದರಿಯನ್ನು ಹೊಂದಿಸಿ).",
209
+ },
210
+ "ml": {
211
+ "title": "MarketMyna ദൈനംദിന റിപ്പോർട്ട്", "analysis": "{mode} വിശകലനം",
212
+ "mode_quick": "വേഗത്തിലുള്ള", "mode_standard": "സാധാരണ", "mode_full": "പൂർണ്ണ", "mode_specialist": "വിദഗ്ധ",
213
+ "calls": "ഇന്നത്തെ നിർദേശങ്ങൾ", "buy": "വാങ്ങുക", "hold": "കൈവശം വയ്ക്കുക", "sell": "വിൽക്കുക",
214
+ "incomplete": "അപൂർണ്ണം", "market_overview": "വിപണി നില", "price": "വില", "target": "ലക്ഷ്യം",
215
+ "stop": "സ്റ്റോപ്പ് ലോസ്", "range_52w": "52 ആഴ്ച പരിധി", "ai_view": "AI വീക്ഷണം",
216
+ "ai_unavailable": "AI തീരുമാനം ലഭ്യമല്ല", "technical": "സാങ്കേതികം", "indicators": "സൂചകങ്ങൾ",
217
+ "fundamentals": "അടിസ്ഥാന ഘടകങ്ങൾ", "score": "സ്കോർ", "valuation": "മൂല്യനിർണ്ണയം", "pe": "P/E", "roe": "ROE",
218
+ "health": "സാമ്പത്തിക നില", "revenue_growth": "വരുമാന വളർച്ച", "dividend_yield": "ലാഭവിഹിത വരുമാനം",
219
+ "risk": "റിസ്ക്", "volatility": "ചാഞ്ചാട്ടം", "drawdown": "പരമാവധി ഇടിവ്", "analysts": "വിശകലന വിദഗ്ധർ",
220
+ "avg_target": "ശരാശരി ലക്ഷ്യം", "n_analysts": "{n} വിശകലന വിദഗ്ധർ", "upcoming": "വരാനിരിക്കുന്നവ",
221
+ "earnings": "ഫലങ്ങൾ", "ex_dividend": "എക്സ്-ഡിവിഡന്റ്", "news": "വാർത്തകൾ",
222
+ "funds": "മ്യൂച്വൽ ഫണ്ടുകൾ", "nav": "NAV",
223
+ "smart_top": "ഇന്ന് ശ്രദ്ധിക്കേണ്ട മുൻനിര {n} ഓഹരികൾ", "full_report": "എല്ലാ {n} ഓഹരികളുടെയും പൂർണ്ണ റിപ്പോർട്ട്", "week": "1 ആഴ്ച",
224
+ "disclaimer": "ഇത് നിക്ഷേപ ഉപദേശമല്ല. MarketMyna അയച്ചത്.",
225
+ "normal": "സാധാരണ പരിധി",
226
+ "reading_positive": "ഉയർച്ച", "reading_mixed": "നിഷ്പക്ഷം", "reading_negative": "താഴ്ച",
227
+ "reading_note": "ℹ️ ഇത് ഡാറ്റ കാണിക്കുന്നത് വിവരിക്കുന്നു, വാങ്ങാനോ വിൽക്കാനോ ഉള്ള ശുപാർശയല്ല. ▲ ഉയർച്ച / ▼ താഴ്ച = ഇന്ന് മിക്ക സൂചകങ്ങളുടെയും ചായ്‌വ്.",
228
+ "english_note": "ചില വിവരങ്ങൾ ഇംഗ്ലീഷിലാണ് (വിവർത്തനത്തിന് AI മോഡൽ സജ്ജമാക്കുക).",
229
+ },
230
+ "mr": {
231
+ "title": "MarketMyna दैनिक अहवाल", "analysis": "{mode} विश्लेषण",
232
+ "mode_quick": "जलद", "mode_standard": "मानक", "mode_full": "संपूर्ण", "mode_specialist": "तज्ज्ञ",
233
+ "calls": "आजच्या शिफारसी", "buy": "खरेदी करा", "hold": "होल्ड करा", "sell": "विक्री करा", "incomplete": "अपूर्ण",
234
+ "market_overview": "बाजाराची स्थिती", "price": "भाव", "target": "लक्ष्य", "stop": "स्टॉप लॉस",
235
+ "range_52w": "52 आठवड्यांची श्रेणी", "ai_view": "AI चे मत", "ai_unavailable": "AI निर्णय उपलब्ध नाही",
236
+ "technical": "तांत्रिक", "indicators": "निर्देशक", "fundamentals": "मूलभूत घटक", "score": "गुण",
237
+ "valuation": "मूल्यांकन", "pe": "P/E", "roe": "ROE", "health": "आर्थिक स्थिती", "revenue_growth": "महसूल वाढ",
238
+ "dividend_yield": "लाभांश परतावा", "risk": "जोखीम", "volatility": "अस्थिरता", "drawdown": "कमाल घसरण",
239
+ "analysts": "विश्लेषक", "avg_target": "सरासरी लक्ष्य", "n_analysts": "{n} विश्लेषक", "upcoming": "आगामी",
240
+ "earnings": "निकाल", "ex_dividend": "एक्स-डिव्हिडंड", "news": "बातम्या",
241
+ "funds": "म्युच्युअल फंड", "nav": "NAV",
242
+ "smart_top": "आज लक्ष ठेवण्याजोगे टॉप {n} शेअर्स", "full_report": "सर्व {n} शेअर्सचा पूर्ण अहवाल", "week": "1 आठवडा",
243
+ "disclaimer": "हा गुंतवणूक सल्ला नाही. MarketMyna कडून पाठवले.",
244
+ "normal": "सामान्य मर्यादा",
245
+ "reading_positive": "तेजी", "reading_mixed": "तटस्थ", "reading_negative": "मंदी",
246
+ "reading_note": "ℹ️ हे आकडेवारी काय दाखवते ते सांगते, खरेदी किंवा विक्रीचा सल्ला नाही. ▲ तेजी / ▼ मंदी = आज बहुतेक निर्देशकांचा कल.",
247
+ "english_note": "काही तपशील इंग्रजीत आहेत (भाषांतरासाठी AI मॉडेल सेट करा).",
248
+ },
249
+ "bn": {
250
+ "title": "MarketMyna দৈনিক রিপোর্ট", "analysis": "{mode} বিশ্লেষণ",
251
+ "mode_quick": "দ্রুত", "mode_standard": "মানক", "mode_full": "সম্পূর্ণ", "mode_specialist": "বিশেষজ্ঞ",
252
+ "calls": "আজকের পরামর্শ", "buy": "কিনুন", "hold": "ধরে রাখুন", "sell": "বিক্রি করুন", "incomplete": "অসম্পূর্ণ",
253
+ "market_overview": "বাজারের অবস্থা", "price": "দাম", "target": "লক্ষ্য", "stop": "স্টপ লস",
254
+ "range_52w": "৫২ সপ্তাহের পরিসর", "ai_view": "AI মতামত", "ai_unavailable": "AI সিদ্ধান্ত পাওয়া যায়নি",
255
+ "technical": "টেকনিক্যাল", "indicators": "সূচক", "fundamentals": "ফান্ডামেন্টালস", "score": "স্কোর",
256
+ "valuation": "মূল্যায়ন", "pe": "P/E", "roe": "ROE", "health": "আর্থিক অবস্থা", "revenue_growth": "রাজস্ব বৃদ্ধি",
257
+ "dividend_yield": "লভ্যাংশ ফলন", "risk": "ঝুঁকি", "volatility": "অস্থিরতা", "drawdown": "সর্বোচ্চ পতন",
258
+ "analysts": "বিশ্লেষক", "avg_target": "গড় লক্ষ্য", "n_analysts": "{n} জন বিশ্লেষক", "upcoming": "আসন্ন",
259
+ "earnings": "ফলাফল", "ex_dividend": "এক্স-ডিভিডেন্ড", "news": "খবর",
260
+ "funds": "মিউচুয়াল ফান্ড", "nav": "NAV",
261
+ "smart_top": "আজ নজরে রাখার সেরা {n}টি শেয়ার", "full_report": "সব {n}টি শেয়ারের পূর্ণ রিপোর্ট", "week": "১ সপ্তাহ",
262
+ "disclaimer": "এটি বিনিয়োগ পরামর্শ নয়। MarketMyna পাঠিয়েছে।",
263
+ "normal": "স্বাভাবিক সীমা",
264
+ "reading_positive": "ঊর্ধ্বমুখী", "reading_mixed": "নিরপেক্ষ", "reading_negative": "নিম্নমুখী",
265
+ "reading_note": "ℹ️ এটি ডেটা যা দেখায় তা বর্ণনা করে, কেনা বা বেচার পরামর্শ নয়। ▲ ঊর্ধ্বমুখী / ▼ নিম্নমুখী = আজ বেশিরভাগ সূচকের ঝোঁক।",
266
+ "english_note": "কিছু বিবরণ ইংরেজিতে আছে (অনুবাদের জন্য AI মডেল সেট করুন)।",
267
+ },
268
+ "gu": {
269
+ "title": "MarketMyna દૈનિક અહેવાલ", "analysis": "{mode} વિશ્લેષણ",
270
+ "mode_quick": "ઝડપી", "mode_standard": "માનક", "mode_full": "સંપૂર્ણ", "mode_specialist": "નિષ્ણાત",
271
+ "calls": "આજની ભલામણો", "buy": "ખરીદો", "hold": "હોલ્ડ કરો", "sell": "વેચો", "incomplete": "અધૂરું",
272
+ "market_overview": "બજારની સ્થિતિ", "price": "ભાવ", "target": "લક્ષ્ય", "stop": "સ્ટોપ લોસ",
273
+ "range_52w": "52 અઠવાડિયાની શ્રેણી", "ai_view": "AI નો અભિપ્રાય", "ai_unavailable": "AI નિર્ણય ઉપલબ્ધ નથી",
274
+ "technical": "ટેકનિકલ", "indicators": "સૂચકો", "fundamentals": "ફંડામેન્ટલ્સ", "score": "સ્કોર",
275
+ "valuation": "મૂલ્યાંકન", "pe": "P/E", "roe": "ROE", "health": "નાણાકીય સ્થિતિ", "revenue_growth": "આવક વૃદ્ધિ",
276
+ "dividend_yield": "ડિવિડન્ડ ઉપજ", "risk": "જોખમ", "volatility": "અસ્થિરતા", "drawdown": "મહત્તમ ઘટાડો",
277
+ "analysts": "વિશ્લેષકો", "avg_target": "સરેરાશ લક્ષ્ય", "n_analysts": "{n} વિશ્લેષકો", "upcoming": "આગામી",
278
+ "earnings": "પરિણામો", "ex_dividend": "એક્સ-ડિવિડન્ડ", "news": "સમાચાર",
279
+ "funds": "મ્યુચ્યુઅલ ફંડ", "nav": "NAV",
280
+ "smart_top": "આજે ધ્યાન રાખવાના ટોપ {n} શેર", "full_report": "બધા {n} શેરનો સંપૂર્ણ અહેવાલ", "week": "1 અઠવાડિયું",
281
+ "disclaimer": "આ રોકાણ સલાહ નથી. MarketMyna દ્વારા મોકલાયું.",
282
+ "normal": "સામાન્ય શ્રેણી",
283
+ "reading_positive": "તેજી", "reading_mixed": "તટસ્થ", "reading_negative": "મંદી",
284
+ "reading_note": "ℹ️ આ ડેટા શું બતાવે છે તે જણાવે છે, ખરીદવા કે વેચવાની સલાહ નથી. ▲ તેજી / ▼ મંદી = આજે મોટાભાગના સૂચકોનો ઝુકાવ.",
285
+ "english_note": "કેટલીક વિગતો અંગ્રેજીમાં છે (અનુવાદ માટે AI મોડેલ સેટ કરો).",
286
+ },
287
+ "pa": {
288
+ "title": "MarketMyna ਰੋਜ਼ਾਨਾ ਰਿਪੋਰਟ", "analysis": "{mode} ਵਿਸ਼ਲੇਸ਼ਣ",
289
+ "mode_quick": "ਤੇਜ਼", "mode_standard": "ਮਿਆਰੀ", "mode_full": "ਪੂਰਾ", "mode_specialist": "ਮਾਹਰ",
290
+ "calls": "ਅੱਜ ਦੀਆਂ ਸਿਫ਼ਾਰਸ਼ਾਂ", "buy": "ਖਰੀਦੋ", "hold": "ਰੱਖੋ", "sell": "ਵੇਚੋ", "incomplete": "ਅਧੂਰਾ",
291
+ "market_overview": "ਬਾਜ਼ਾਰ ਦੀ ਸਥਿਤੀ", "price": "ਭਾਅ", "target": "ਟੀਚਾ", "stop": "ਸਟਾਪ ਲੌਸ",
292
+ "range_52w": "52 ਹਫ਼ਤਿਆਂ ਦੀ ਰੇਂਜ", "ai_view": "AI ਦੀ ਰਾਏ", "ai_unavailable": "AI ਫ਼ੈਸਲਾ ਉਪਲਬਧ ਨਹੀਂ",
293
+ "technical": "ਤਕਨੀਕੀ", "indicators": "ਸੂਚਕ", "fundamentals": "ਬੁਨਿਆਦੀ ਅੰਕੜੇ", "score": "ਸਕੋਰ",
294
+ "valuation": "ਮੁਲਾਂਕਣ", "pe": "P/E", "roe": "ROE", "health": "ਵਿੱਤੀ ਸਥਿਤੀ", "revenue_growth": "ਆਮਦਨ ਵਾਧਾ",
295
+ "dividend_yield": "ਲਾਭਅੰਸ਼ ਉਪਜ", "risk": "ਜੋਖਮ", "volatility": "ਅਸਥਿਰਤਾ", "drawdown": "ਵੱਧ ਤੋਂ ਵੱਧ ਗਿਰਾਵਟ",
296
+ "analysts": "ਵਿਸ਼ਲੇਸ਼ਕ", "avg_target": "ਔਸਤ ਟੀਚਾ", "n_analysts": "{n} ਵਿਸ਼ਲੇਸ਼ਕ", "upcoming": "ਆਉਣ ਵਾਲੇ",
297
+ "earnings": "ਨਤੀਜੇ", "ex_dividend": "ਐਕਸ-ਡਿਵੀਡੈਂਡ", "news": "ਖ਼ਬਰਾਂ",
298
+ "funds": "ਮਿਊਚੁਅਲ ਫੰਡ", "nav": "NAV",
299
+ "smart_top": "ਅੱਜ ਧਿਆਨ ਦੇਣ ਯੋਗ ਟਾਪ {n} ਸ਼ੇਅਰ", "full_report": "ਸਾਰੇ {n} ਸ਼ੇਅਰਾਂ ਦੀ ਪੂਰੀ ਰਿਪੋਰਟ", "week": "1 ਹਫ਼ਤਾ",
300
+ "disclaimer": "ਇਹ ਨਿਵੇਸ਼ ਸਲਾਹ ਨਹੀਂ ਹੈ। MarketMyna ਵੱਲੋਂ ਭੇਜਿਆ ਗਿਆ।",
301
+ "normal": "ਆਮ ਦਾਇਰਾ",
302
+ "reading_positive": "ਤੇਜ਼ੀ", "reading_mixed": "ਨਿਰਪੱਖ", "reading_negative": "ਮੰਦੀ",
303
+ "reading_note": "ℹ️ ਇਹ ਡਾਟਾ ਕੀ ਦਿਖਾਉਂਦਾ ਹੈ ਉਹ ਦੱਸਦਾ ਹੈ, ਖਰੀਦਣ ਜਾਂ ਵੇਚਣ ਦੀ ਸਲਾਹ ਨਹੀਂ। ▲ ਤੇਜ਼ੀ / ▼ ਮੰਦੀ = ਅੱਜ ਜ਼ਿਆਦਾਤਰ ਸੂਚਕਾਂ ਦਾ ਝੁਕਾਅ।",
304
+ "english_note": "ਕੁਝ ਵੇਰਵੇ ਅੰਗਰੇਜ਼ੀ ਵਿੱਚ ਹਨ (ਅਨੁਵਾਦ ਲਈ AI ਮਾਡਲ ਸੈੱਟ ਕਰੋ)।",
305
+ },
306
+ "ur": {
307
+ "title": "MarketMyna روزانہ رپورٹ", "analysis": "{mode} تجزیہ",
308
+ "mode_quick": "فوری", "mode_standard": "معیاری", "mode_full": "مکمل", "mode_specialist": "ماہرانہ",
309
+ "calls": "آج کی سفارشات", "buy": "خریدیں", "hold": "رکھیں", "sell": "بیچیں", "incomplete": "نامکمل",
310
+ "market_overview": "مارکیٹ کا حال", "price": "قیمت", "target": "ہدف", "stop": "اسٹاپ لاس",
311
+ "range_52w": "52 ہفتوں کی حد", "ai_view": "AI کی رائے", "ai_unavailable": "AI فیصلہ دستیاب نہیں",
312
+ "technical": "تکنیکی", "indicators": "اشاریے", "fundamentals": "بنیادی عوامل", "score": "اسکور",
313
+ "valuation": "قدر پیمائی", "pe": "P/E", "roe": "ROE", "health": "مالی حالت", "revenue_growth": "آمدنی میں اضافہ",
314
+ "dividend_yield": "منافع کی شرح", "risk": "خطرہ", "volatility": "اتار چڑھاؤ", "drawdown": "زیادہ سے زیادہ کمی",
315
+ "analysts": "تجزیہ کار", "avg_target": "اوسط ہدف", "n_analysts": "{n} تجزیہ کار", "upcoming": "آنے والے",
316
+ "earnings": "نتائج", "ex_dividend": "ایکس ڈیویڈنڈ", "news": "خبریں",
317
+ "funds": "میوچل فنڈز", "nav": "NAV",
318
+ "smart_top": "آج توجہ کے قابل سرفہرست {n} شیئرز", "full_report": "تمام {n} شیئرز کی مکمل رپورٹ", "week": "1 ہفتہ",
319
+ "disclaimer": "یہ سرمایہ کاری کا مشورہ نہیں ہے۔ MarketMyna کی طرف سے بھیجا گیا۔",
320
+ "normal": "معمول کی حد",
321
+ "reading_positive": "تیزی", "reading_mixed": "غیر جانبدار", "reading_negative": "مندی",
322
+ "reading_note": "ℹ️ یہ بتاتا ہے کہ ڈیٹا کیا دکھاتا ہے، خریدنے یا بیچنے کا مشورہ نہیں۔ ▲ تیزی / ▼ مندی = آج زیادہ تر اشاریوں کا رجحان۔",
323
+ "english_note": "کچھ تفصیلات انگریزی میں ہیں (ترجمے کے لیے AI ماڈل سیٹ کریں)۔",
324
+ },
325
+ "or": {
326
+ "title": "MarketMyna ଦୈନିକ ରିପୋର୍ଟ", "analysis": "{mode} ବିଶ୍ଳେଷଣ",
327
+ "mode_quick": "ଦ୍ରୁତ", "mode_standard": "ମାନକ", "mode_full": "ସମ୍ପୂର୍ଣ୍ଣ", "mode_specialist": "ବିଶେଷଜ୍ଞ",
328
+ "calls": "ଆଜିର ପରାମର୍ଶ", "buy": "କିଣନ୍ତୁ", "hold": "ରଖନ୍ତୁ", "sell": "ବିକ୍ରି କରନ୍ତୁ", "incomplete": "ଅସମ୍ପୂର୍ଣ୍ଣ",
329
+ "market_overview": "ବଜାର ସ୍ଥିତି", "price": "ଦର", "target": "ଲକ୍ଷ୍ୟ", "stop": "ଷ୍ଟପ୍ ଲସ୍",
330
+ "range_52w": "52 ସପ୍ତାହ ପରିସର", "ai_view": "AI ମତ", "ai_unavailable": "AI ନିଷ୍ପତ୍ତି ଉପଲବ୍ଧ ନାହିଁ",
331
+ "technical": "ଟେକ୍ନିକାଲ୍", "indicators": "ସୂଚକ", "fundamentals": "ମୌଳିକ ତଥ୍ୟ", "score": "ସ୍କୋର",
332
+ "valuation": "ମୂଲ୍ୟାଙ୍କନ", "pe": "P/E", "roe": "ROE", "health": "ଆର୍ଥିକ ସ୍ଥିତି", "revenue_growth": "ରାଜସ୍ୱ ବୃଦ୍ଧି",
333
+ "dividend_yield": "ଲାଭାଂଶ ଆୟ", "risk": "ବିପଦ", "volatility": "ଅସ୍ଥିରତା", "drawdown": "ସର୍ବାଧିକ ପତନ",
334
+ "analysts": "ବିଶ୍ଳେଷକ", "avg_target": "ହାରାହାରି ଲକ୍ଷ୍ୟ", "n_analysts": "{n} ବିଶ୍ଳେଷକ", "upcoming": "ଆଗାମୀ",
335
+ "earnings": "ଫଳାଫଳ", "ex_dividend": "ଏକ୍ସ-ଡିଭିଡେଣ୍ଡ", "news": "ଖବର",
336
+ "funds": "ମ୍ୟୁଚୁଆଲ୍ ଫଣ୍ଡ", "nav": "NAV",
337
+ "smart_top": "ଆଜି ଦେଖିବାକୁ ଶୀର୍ଷ {n} ସେୟାର", "full_report": "ସମସ୍ତ {n} ସେୟାରର ପୂର୍ଣ୍ଣ ରିପୋର୍ଟ", "week": "1 ସପ୍ତାହ",
338
+ "disclaimer": "ଏହା ନିବେଶ ପରାମର୍ଶ ନୁହେଁ। MarketMyna ପଠାଇଛି।",
339
+ "normal": "ସାଧାରଣ ସୀମା",
340
+ "reading_positive": "ଉର୍ଦ୍ଧ୍ୱମୁଖୀ", "reading_mixed": "ନିରପେକ୍ଷ", "reading_negative": "ନିମ୍ନମୁଖୀ",
341
+ "reading_note": "ℹ️ ଏହା ତଥ୍ୟ କଣ ଦେଖାଉଛି ତାହା ବର୍ଣ୍ଣନା କରେ, କିଣିବା କିମ୍ବା ବିକିବାର ପରାମର୍ଶ ନୁହେଁ। ▲ ଉର୍ଦ୍ଧ୍ୱମୁଖୀ / ▼ ନିମ୍ନମୁଖୀ = ଆଜି ଅଧିକାଂଶ ସୂଚକର ଝୁକାବ।",
342
+ "english_note": "କିଛି ବିବରଣୀ ଇଂରାଜୀରେ ଅଛି (ଅନୁବାଦ ପାଇଁ AI ମଡେଲ୍ ସେଟ୍ କରନ୍ତୁ)।",
343
+ },
344
+ "zh": {
345
+ "title": "MarketMyna 每日报告", "analysis": "{mode}分析",
346
+ "mode_quick": "快速", "mode_standard": "标准", "mode_full": "完整", "mode_specialist": "专家",
347
+ "calls": "今日建议", "buy": "买入", "hold": "持有", "sell": "卖出", "incomplete": "未完成",
348
+ "market_overview": "市场概览", "price": "价格", "target": "目标价", "stop": "止损",
349
+ "range_52w": "52周区间", "ai_view": "AI观点", "ai_unavailable": "AI决策不可用",
350
+ "technical": "技术面", "indicators": "指标", "fundamentals": "基本面", "score": "评分",
351
+ "valuation": "估值", "pe": "市盈率", "roe": "ROE", "health": "财务状况", "revenue_growth": "营收增长",
352
+ "dividend_yield": "股息率", "risk": "风险", "volatility": "波动率", "drawdown": "最大回撤",
353
+ "analysts": "分析师", "avg_target": "平均目标价", "n_analysts": "{n}位分析师", "upcoming": "即将到来",
354
+ "earnings": "财报", "ex_dividend": "除息日", "news": "新闻",
355
+ "funds": "共同基金", "nav": "净值",
356
+ "smart_top": "今日重点关注 {n} 只股票", "full_report": "全部 {n} 只股票的完整报告", "week": "一周",
357
+ "disclaimer": "不构成投资建议。由 MarketMyna 发送。",
358
+ "normal": "正常区间",
359
+ "reading_positive": "看涨", "reading_mixed": "中性", "reading_negative": "看跌",
360
+ "reading_note": "ℹ️ 这里描述的是数据显示的情况,并非买入或卖出建议。▲ 看涨 / ▼ 看跌 = 今天多数指标的倾向。",
361
+ "english_note": "部分内容为英文(配置 AI 模型后可自动翻译)。",
362
+ },
363
+ "ja": {
364
+ "title": "MarketMyna 日次レポート", "analysis": "{mode}分析",
365
+ "mode_quick": "クイック", "mode_standard": "標準", "mode_full": "フル", "mode_specialist": "専門",
366
+ "calls": "本日の判断", "buy": "買い", "hold": "保有", "sell": "売り", "incomplete": "未完了",
367
+ "market_overview": "市場概況", "price": "株価", "target": "目標株価", "stop": "損切り",
368
+ "range_52w": "52週レンジ", "ai_view": "AIの見解", "ai_unavailable": "AI判断は利用できません",
369
+ "technical": "テクニカル", "indicators": "指標", "fundamentals": "ファンダメンタルズ", "score": "スコア",
370
+ "valuation": "バリュエーション", "pe": "PER", "roe": "ROE", "health": "財務健全性", "revenue_growth": "売上成長率",
371
+ "dividend_yield": "配当利回り", "risk": "リスク", "volatility": "ボラティリティ", "drawdown": "最大ドローダウン",
372
+ "analysts": "アナリスト", "avg_target": "平均目標株価", "n_analysts": "アナリスト{n}人", "upcoming": "予定",
373
+ "earnings": "決算", "ex_dividend": "権利落ち日", "news": "ニュース",
374
+ "funds": "投資信託", "nav": "基準価額",
375
+ "smart_top": "本日の注目 {n} 銘柄", "full_report": "全 {n} 銘柄の詳細レポート", "week": "1週間",
376
+ "disclaimer": "投資助言ではありません。MarketMyna より送信。",
377
+ "normal": "通常レンジ",
378
+ "reading_positive": "強気", "reading_mixed": "中立", "reading_negative": "弱気",
379
+ "reading_note": "ℹ️ データが示す状況の説明であり、売買の推奨ではありません。▲ 強気 / ▼ 弱気 = 本日の多くの指標の傾き。",
380
+ "english_note": "一部は英語のままです(AIモデルを設定すると翻訳されます)。",
381
+ },
382
+ "ko": {
383
+ "title": "MarketMyna 일일 리포트", "analysis": "{mode} 분석",
384
+ "mode_quick": "빠른", "mode_standard": "표준", "mode_full": "전체", "mode_specialist": "전문가",
385
+ "calls": "오늘의 판단", "buy": "매수", "hold": "보유", "sell": "매도", "incomplete": "미완료",
386
+ "market_overview": "시장 개요", "price": "가격", "target": "목표가", "stop": "손절가",
387
+ "range_52w": "52주 범위", "ai_view": "AI 의견", "ai_unavailable": "AI 판단을 사용할 수 없음",
388
+ "technical": "기술적 분석", "indicators": "지표", "fundamentals": "펀더멘털", "score": "점수",
389
+ "valuation": "밸류에이션", "pe": "PER", "roe": "ROE", "health": "재무 건전성", "revenue_growth": "매출 성장률",
390
+ "dividend_yield": "배당수익률", "risk": "위험", "volatility": "변동성", "drawdown": "최대 낙폭",
391
+ "analysts": "애널리스트", "avg_target": "평균 목표가", "n_analysts": "애널리스트 {n}명", "upcoming": "예정",
392
+ "earnings": "실적 발표", "ex_dividend": "배당락일", "news": "뉴스",
393
+ "funds": "뮤추얼 펀드", "nav": "기준가",
394
+ "smart_top": "오늘 주목할 상위 {n}개 종목", "full_report": "전체 {n}개 종목 상세 리포트", "week": "1주",
395
+ "disclaimer": "투자 조언이 아닙니다. MarketMyna에서 발송.",
396
+ "normal": "정상 범위",
397
+ "reading_positive": "강세", "reading_mixed": "중립", "reading_negative": "약세",
398
+ "reading_note": "ℹ️ 데이터가 보여주는 내용을 설명한 것이며 매수·매도 권유가 아닙니다. ▲ 강세 / ▼ 약세 = 오늘 대부분 지표의 방향.",
399
+ "english_note": "일부 내용은 영어입니다 (AI 모델을 설정하면 번역됩니다).",
400
+ },
401
+ "es": {
402
+ "title": "Informe diario de MarketMyna", "analysis": "Análisis {mode}",
403
+ "mode_quick": "rápido", "mode_standard": "estándar", "mode_full": "completo", "mode_specialist": "especialista",
404
+ "calls": "Recomendaciones de hoy", "buy": "Comprar", "hold": "Mantener", "sell": "Vender", "incomplete": "Incompleto",
405
+ "market_overview": "Resumen del mercado", "price": "Precio", "target": "Objetivo", "stop": "Stop loss",
406
+ "range_52w": "Rango de 52 semanas", "ai_view": "Opinión de la IA", "ai_unavailable": "Decisión de IA no disponible",
407
+ "technical": "Técnico", "indicators": "Indicadores", "fundamentals": "Fundamentales", "score": "Puntuación",
408
+ "valuation": "Valoración", "pe": "PER", "roe": "ROE", "health": "Salud financiera",
409
+ "revenue_growth": "Crecimiento de ingresos", "dividend_yield": "Rentabilidad por dividendo", "risk": "Riesgo",
410
+ "volatility": "Volatilidad", "drawdown": "Caída máxima", "analysts": "Analistas", "avg_target": "objetivo medio",
411
+ "n_analysts": "{n} analistas", "upcoming": "Próximos eventos", "earnings": "Resultados",
412
+ "ex_dividend": "Fecha ex-dividendo", "news": "Noticias",
413
+ "funds": "Fondos de inversión", "nav": "Valor liquidativo",
414
+ "smart_top": "Las {n} acciones a vigilar hoy", "full_report": "Informe completo de las {n} acciones", "week": "1 semana",
415
+ "disclaimer": "No es asesoramiento de inversión. Enviado por MarketMyna.",
416
+ "normal": "Rango normal",
417
+ "reading_positive": "alcista", "reading_mixed": "neutral", "reading_negative": "bajista",
418
+ "reading_note": "ℹ️ Describe lo que muestran los datos; no es una recomendación de compra o venta. ▲ alcista / ▼ bajista = hacia dónde se inclinan hoy la mayoría de indicadores.",
419
+ "english_note": "Algunos detalles están en inglés (configura un modelo de IA para traducirlos).",
420
+ },
421
+ "fr": {
422
+ "title": "Rapport quotidien MarketMyna", "analysis": "Analyse {mode}",
423
+ "mode_quick": "rapide", "mode_standard": "standard", "mode_full": "complète", "mode_specialist": "spécialiste",
424
+ "calls": "Recommandations du jour", "buy": "Acheter", "hold": "Conserver", "sell": "Vendre", "incomplete": "Incomplet",
425
+ "market_overview": "Aperçu du marché", "price": "Cours", "target": "Objectif", "stop": "Stop loss",
426
+ "range_52w": "Fourchette sur 52 semaines", "ai_view": "Avis de l'IA", "ai_unavailable": "Décision IA indisponible",
427
+ "technical": "Technique", "indicators": "Indicateurs", "fundamentals": "Fondamentaux", "score": "Score",
428
+ "valuation": "Valorisation", "pe": "PER", "roe": "ROE", "health": "Santé financière",
429
+ "revenue_growth": "Croissance du CA", "dividend_yield": "Rendement du dividende", "risk": "Risque",
430
+ "volatility": "Volatilité", "drawdown": "Baisse maximale", "analysts": "Analystes", "avg_target": "objectif moyen",
431
+ "n_analysts": "{n} analystes", "upcoming": "À venir", "earnings": "Résultats", "ex_dividend": "Détachement du dividende",
432
+ "news": "Actualités",
433
+ "funds": "Fonds communs", "nav": "VL",
434
+ "smart_top": "Les {n} actions à suivre aujourd'hui", "full_report": "Rapport complet des {n} actions", "week": "1 semaine",
435
+ "disclaimer": "Ceci n'est pas un conseil en investissement. Envoyé par MarketMyna.",
436
+ "normal": "Fourchette normale",
437
+ "reading_positive": "haussier", "reading_mixed": "neutre", "reading_negative": "baissier",
438
+ "reading_note": "ℹ️ Ceci décrit ce que montrent les données, ce n'est pas une recommandation d'achat ou de vente. ▲ haussier / ▼ baissier = l'orientation de la plupart des indicateurs aujourd'hui.",
439
+ "english_note": "Certains détails sont en anglais (configurez un modèle d'IA pour les traduire).",
440
+ },
441
+ "de": {
442
+ "title": "MarketMyna Tagesbericht", "analysis": "{mode}-Analyse",
443
+ "mode_quick": "Schnell", "mode_standard": "Standard", "mode_full": "Voll", "mode_specialist": "Spezialisten",
444
+ "calls": "Heutige Empfehlungen", "buy": "Kaufen", "hold": "Halten", "sell": "Verkaufen", "incomplete": "Unvollständig",
445
+ "market_overview": "Marktüberblick", "price": "Kurs", "target": "Kursziel", "stop": "Stop-Loss",
446
+ "range_52w": "52-Wochen-Spanne", "ai_view": "KI-Einschätzung", "ai_unavailable": "KI-Entscheidung nicht verfügbar",
447
+ "technical": "Technisch", "indicators": "Indikatoren", "fundamentals": "Fundamentaldaten", "score": "Bewertung",
448
+ "valuation": "Bewertung", "pe": "KGV", "roe": "Eigenkapitalrendite", "health": "Finanzielle Lage",
449
+ "revenue_growth": "Umsatzwachstum", "dividend_yield": "Dividendenrendite", "risk": "Risiko",
450
+ "volatility": "Volatilität", "drawdown": "Maximaler Rückgang", "analysts": "Analysten",
451
+ "avg_target": "durchschn. Kursziel", "n_analysts": "{n} Analysten", "upcoming": "Anstehend",
452
+ "earnings": "Quartalszahlen", "ex_dividend": "Ex-Dividende", "news": "Nachrichten",
453
+ "funds": "Investmentfonds", "nav": "NAV",
454
+ "smart_top": "Die {n} Aktien im Fokus heute", "full_report": "Vollständiger Bericht zu allen {n} Aktien", "week": "1 Woche",
455
+ "disclaimer": "Keine Anlageberatung. Gesendet von MarketMyna.",
456
+ "normal": "Normale Spanne",
457
+ "reading_positive": "bullisch", "reading_mixed": "neutral", "reading_negative": "bärisch",
458
+ "reading_note": "ℹ️ Beschreibt, was die Daten zeigen – keine Kauf- oder Verkaufsempfehlung. ▲ bullisch / ▼ bärisch = wohin die meisten Indikatoren heute neigen.",
459
+ "english_note": "Einige Details sind auf Englisch (richte ein KI-Modell zur Übersetzung ein).",
460
+ },
461
+ "pt": {
462
+ "title": "Relatório diário MarketMyna", "analysis": "Análise {mode}",
463
+ "mode_quick": "rápida", "mode_standard": "padrão", "mode_full": "completa", "mode_specialist": "especialista",
464
+ "calls": "Recomendações de hoje", "buy": "Comprar", "hold": "Manter", "sell": "Vender", "incomplete": "Incompleto",
465
+ "market_overview": "Visão geral do mercado", "price": "Preço", "target": "Alvo", "stop": "Stop loss",
466
+ "range_52w": "Faixa de 52 semanas", "ai_view": "Visão da IA", "ai_unavailable": "Decisão da IA indisponível",
467
+ "technical": "Técnico", "indicators": "Indicadores", "fundamentals": "Fundamentos", "score": "Pontuação",
468
+ "valuation": "Valuation", "pe": "P/L", "roe": "ROE", "health": "Saúde financeira",
469
+ "revenue_growth": "Crescimento da receita", "dividend_yield": "Dividend yield", "risk": "Risco",
470
+ "volatility": "Volatilidade", "drawdown": "Queda máxima", "analysts": "Analistas", "avg_target": "alvo médio",
471
+ "n_analysts": "{n} analistas", "upcoming": "Próximos eventos", "earnings": "Resultados",
472
+ "ex_dividend": "Data ex-dividendo", "news": "Notícias",
473
+ "funds": "Fundos de investimento", "nav": "Cota",
474
+ "smart_top": "As {n} ações para acompanhar hoje", "full_report": "Relatório completo das {n} ações", "week": "1 semana",
475
+ "disclaimer": "Não é recomendação de investimento. Enviado pelo MarketMyna.",
476
+ "normal": "Faixa normal",
477
+ "reading_positive": "de alta", "reading_mixed": "neutro", "reading_negative": "de baixa",
478
+ "reading_note": "ℹ️ Descreve o que os dados mostram; não é recomendação de compra ou venda. ▲ de alta / ▼ de baixa = para onde a maioria dos indicadores aponta hoje.",
479
+ "english_note": "Alguns detalhes estão em inglês (configure um modelo de IA para traduzi-los).",
480
+ },
481
+ "ru": {
482
+ "title": "Ежедневный отчёт MarketMyna", "analysis": "{mode} анализ",
483
+ "mode_quick": "Быстрый", "mode_standard": "Стандартный", "mode_full": "Полный", "mode_specialist": "Экспертный",
484
+ "calls": "Рекомендации на сегодня", "buy": "Покупать", "hold": "Держать", "sell": "Продавать",
485
+ "incomplete": "Не завершено", "market_overview": "Обзор рынка", "price": "Цена", "target": "Цель",
486
+ "stop": "Стоп-лосс", "range_52w": "Диапазон за 52 недели", "ai_view": "Мнение ИИ",
487
+ "ai_unavailable": "Решение ИИ недоступно", "technical": "Технический анализ", "indicators": "Индикаторы",
488
+ "fundamentals": "Фундаментальные данные", "score": "Оценка", "valuation": "Оценка стоимости", "pe": "P/E",
489
+ "roe": "ROE", "health": "Финансовое состояние", "revenue_growth": "Рост выручки",
490
+ "dividend_yield": "Дивидендная доходность", "risk": "Риск", "volatility": "Волатильность",
491
+ "drawdown": "Макс. просадка", "analysts": "Аналитики", "avg_target": "средняя цель",
492
+ "n_analysts": "аналитиков: {n}", "upcoming": "Предстоящие события", "earnings": "Отчётность",
493
+ "ex_dividend": "Экс-дивидендная дата", "news": "Новости",
494
+ "funds": "Паевые фонды", "nav": "СЧА",
495
+ "smart_top": "Топ-{n} акций для наблюдения сегодня", "full_report": "Полный отчёт по всем акциям: {n}", "week": "1 неделя",
496
+ "disclaimer": "Не является инвестиционной рекомендацией. Отправлено MarketMyna.",
497
+ "normal": "Обычный диапазон",
498
+ "reading_positive": "бычий", "reading_mixed": "нейтральный", "reading_negative": "медвежий",
499
+ "reading_note": "ℹ️ Это описание того, что показывают данные, а не рекомендация покупать или продавать. ▲ бычий / ▼ медвежий = куда сегодня склоняется большинство индикаторов.",
500
+ "english_note": "Часть информации на английском (настройте модель ИИ для перевода).",
501
+ },
502
+ "ar": {
503
+ "title": "تقرير MarketMyna اليومي", "analysis": "تحليل {mode}",
504
+ "mode_quick": "سريع", "mode_standard": "قياسي", "mode_full": "كامل", "mode_specialist": "متخصص",
505
+ "calls": "توصيات اليوم", "buy": "شراء", "hold": "احتفاظ", "sell": "بيع", "incomplete": "غير مكتمل",
506
+ "market_overview": "نظرة على السوق", "price": "السعر", "target": "الهدف", "stop": "وقف الخسارة",
507
+ "range_52w": "نطاق 52 أسبوعًا", "ai_view": "رأي الذكاء الاصطناعي", "ai_unavailable": "قرار الذكاء الاصطناعي غير متاح",
508
+ "technical": "فني", "indicators": "المؤشرات", "fundamentals": "الأساسيات", "score": "التقييم",
509
+ "valuation": "التقييم السعري", "pe": "مكرر الربحية", "roe": "العائد على حقوق الملكية", "health": "الوضع المالي",
510
+ "revenue_growth": "نمو الإيرادات", "dividend_yield": "عائد التوزيعات", "risk": "المخاطر",
511
+ "volatility": "التقلب", "drawdown": "أقصى تراجع", "analysts": "المحللون", "avg_target": "متوسط الهدف",
512
+ "n_analysts": "{n} محللين", "upcoming": "القادم", "earnings": "النتائج المالية", "ex_dividend": "تاريخ استحقاق التوزيع",
513
+ "news": "الأخبار",
514
+ "funds": "صناديق الاستثمار", "nav": "صافي قيمة الأصول",
515
+ "smart_top": "أهم {n} أسهم للمتابعة اليوم", "full_report": "التقرير الكامل لجميع الأسهم ({n})", "week": "أسبوع",
516
+ "disclaimer": "ليست نصيحة استثمارية. أرسلها MarketMyna.",
517
+ "normal": "النطاق المعتاد",
518
+ "reading_positive": "صاعد", "reading_mixed": "محايد", "reading_negative": "هابط",
519
+ "reading_note": "ℹ️ يصف هذا ما تُظهره البيانات، وليس توصية بالشراء أو البيع. ▲ صاعد / ▼ هابط = اتجاه معظم المؤشرات اليوم.",
520
+ "english_note": "بعض التفاصيل بالإنجليزية (اضبط نموذج ذكاء اصطناعي لترجمتها).",
521
+ },
522
+ "id": {
523
+ "title": "Laporan harian MarketMyna", "analysis": "Analisis {mode}",
524
+ "mode_quick": "cepat", "mode_standard": "standar", "mode_full": "lengkap", "mode_specialist": "spesialis",
525
+ "calls": "Rekomendasi hari ini", "buy": "Beli", "hold": "Tahan", "sell": "Jual", "incomplete": "Belum lengkap",
526
+ "market_overview": "Ringkasan pasar", "price": "Harga", "target": "Target", "stop": "Stop loss",
527
+ "range_52w": "Rentang 52 minggu", "ai_view": "Pandangan AI", "ai_unavailable": "Keputusan AI tidak tersedia",
528
+ "technical": "Teknikal", "indicators": "Indikator", "fundamentals": "Fundamental", "score": "Skor",
529
+ "valuation": "Valuasi", "pe": "PER", "roe": "ROE", "health": "Kesehatan keuangan",
530
+ "revenue_growth": "Pertumbuhan pendapatan", "dividend_yield": "Imbal hasil dividen", "risk": "Risiko",
531
+ "volatility": "Volatilitas", "drawdown": "Penurunan maksimum", "analysts": "Analis", "avg_target": "target rata-rata",
532
+ "n_analysts": "{n} analis", "upcoming": "Mendatang", "earnings": "Laporan keuangan", "ex_dividend": "Tanggal ex-dividen",
533
+ "news": "Berita",
534
+ "funds": "Reksa dana", "nav": "NAB",
535
+ "smart_top": "{n} saham teratas untuk dipantau hari ini", "full_report": "Laporan lengkap semua {n} saham", "week": "1 minggu",
536
+ "disclaimer": "Bukan saran investasi. Dikirim oleh MarketMyna.",
537
+ "normal": "Rentang normal",
538
+ "reading_positive": "bullish", "reading_mixed": "netral", "reading_negative": "bearish",
539
+ "reading_note": "ℹ️ Ini menjelaskan apa yang ditunjukkan data, bukan rekomendasi beli atau jual. ▲ bullish / ▼ bearish = arah kebanyakan indikator hari ini.",
540
+ "english_note": "Beberapa detail dalam bahasa Inggris (atur model AI untuk menerjemahkannya).",
541
+ },
542
+ }
543
+
544
+ _VALUES: dict[str, dict[str, str]] = {
545
+ "hi": {"bullish": "तेज़ी", "bearish": "मंदी", "neutral": "तटस्थ", "low": "कम", "medium": "मध्यम", "high": "उच्च",
546
+ "strong_buy": "मज़बूत खरीद", "buy": "खरीदें", "hold": "होल्ड", "sell": "बेचें", "strong_sell": "मज़बूत बिक्री",
547
+ "underperform": "कमज़ोर प्रदर्शन", "outperform": "बेहतर प्रदर्शन", "undervalued": "सस्ता",
548
+ "fair": "उचित", "overvalued": "महँगा", "good": "अच्छा", "average": "औसत", "poor": "कमज़ोर", "moderate": "मध्यम"},
549
+ "ta": {"bullish": "ஏற்றம்", "bearish": "இறக்கம்", "neutral": "நடுநிலை", "low": "குறைவு", "medium": "நடுத்தரம்",
550
+ "high": "அதிகம்", "strong_buy": "உறுதியாக வாங்கவும்", "buy": "வாங்கவும்", "hold": "வைத்திருக்கவும்",
551
+ "sell": "விற்கவும்", "strong_sell": "உறுதியாக விற்கவும்", "underperform": "பின்தங்கும்",
552
+ "outperform": "முன்னிலை", "undervalued": "குறைமதிப்பு", "fair": "நியாயம்", "overvalued": "அதிகமதிப்பு",
553
+ "good": "நல்லது", "average": "சராசரி", "poor": "மோசம்", "moderate": "மிதமானது"},
554
+ "te": {"bullish": "బుల్లిష్", "bearish": "బేరిష్", "neutral": "తటస్థం", "low": "తక్కువ", "medium": "మధ్యస్థం",
555
+ "high": "ఎక్కువ", "strong_buy": "బలంగా కొనండి", "buy": "కొనండి", "hold": "ఉంచుకోండి", "sell": "అమ్మండి",
556
+ "strong_sell": "బలంగా అమ్మండి", "underperform": "వెనుకబడుతుంది", "outperform": "మెరుగ్గా",
557
+ "undervalued": "తక్కువ విలువ", "fair": "సరైన విలువ", "overvalued": "అధిక విలువ", "good": "మంచిది",
558
+ "average": "సగటు", "poor": "బలహీనం", "moderate": "మితమైన"},
559
+ "kn": {"bullish": "ಏರಿಕೆ", "bearish": "ಇಳಿಕೆ", "neutral": "ತಟಸ್ಥ", "low": "ಕಡಿಮೆ", "medium": "ಮಧ್ಯಮ", "high": "ಹೆಚ್ಚು",
560
+ "strong_buy": "ಬಲವಾಗಿ ಖರೀದಿಸಿ", "buy": "ಖರೀದಿಸಿ", "hold": "ಇಟ್ಟುಕೊಳ್ಳಿ", "sell": "ಮಾರಾಟ ಮಾಡಿ",
561
+ "strong_sell": "ಬಲವಾಗಿ ಮಾರಿ", "underperform": "ಹಿಂದುಳಿಯುವ", "outperform": "ಮುನ್ನಡೆ",
562
+ "undervalued": "ಕಡಿಮೆ ಮೌಲ್ಯ", "fair": "ನ್ಯಾಯಯುತ", "overvalued": "ಅಧಿಕ ಮೌಲ್ಯ", "good": "ಉತ್ತಮ",
563
+ "average": "ಸರಾಸರಿ", "poor": "ದುರ್ಬಲ", "moderate": "ಮಧ್ಯಮ"},
564
+ "ml": {"bullish": "ഉയർച്ച", "bearish": "താഴ്ച", "neutral": "നിഷ്പക്ഷം", "low": "കുറവ്", "medium": "ഇടത്തരം",
565
+ "high": "ഉയർന്നത്", "strong_buy": "ശക്തമായി വാങ്ങുക", "buy": "വാങ്ങുക", "hold": "കൈവശം വയ്ക്കുക",
566
+ "sell": "വിൽക്കുക", "strong_sell": "ശക്തമായി വിൽക്കുക", "underperform": "പിന്നിലാകും",
567
+ "outperform": "മുന്നിലെത്തും", "undervalued": "മൂല്യം കുറവ്", "fair": "ന്യായം", "overvalued": "മൂല്യം കൂടുതൽ",
568
+ "good": "നല്ലത്", "average": "ശരാശരി", "poor": "ദുർബലം", "moderate": "മിതമായ"},
569
+ "mr": {"bullish": "तेजी", "bearish": "मंदी", "neutral": "तटस्थ", "low": "कमी", "medium": "मध्यम", "high": "जास्त",
570
+ "strong_buy": "जोरदार खरेदी", "buy": "खरेदी", "hold": "होल्ड", "sell": "विक्री", "strong_sell": "जोरदार विक्री",
571
+ "underperform": "कमी कामगिरी", "outperform": "सरस कामगिरी", "undervalued": "स्वस्त", "fair": "योग्य",
572
+ "overvalued": "महाग", "good": "चांगले", "average": "सरासरी", "poor": "कमकुवत", "moderate": "मध्यम"},
573
+ "bn": {"bullish": "ঊর্ধ্বমুখী", "bearish": "নিম্নমুখী", "neutral": "নিরপেক্ষ", "low": "কম", "medium": "মাঝারি",
574
+ "high": "বেশি", "strong_buy": "জোরালো কিনুন", "buy": "কিনুন", "hold": "ধরে রাখুন", "sell": "বিক্রি করুন",
575
+ "strong_sell": "জোরালো বিক্রি", "underperform": "পিছিয়ে থাকবে", "outperform": "এগিয়ে থাকবে",
576
+ "undervalued": "অবমূল্যায়িত", "fair": "ন্যায্য", "overvalued": "অতিমূল্যায়িত", "good": "ভালো",
577
+ "average": "গড়", "poor": "দুর্বল", "moderate": "মাঝারি"},
578
+ "gu": {"bullish": "તેજી", "bearish": "મંદી", "neutral": "તટસ્થ", "low": "ઓછું", "medium": "મધ્યમ", "high": "ઊંચું",
579
+ "strong_buy": "મજબૂત ખરીદી", "buy": "ખરીદો", "hold": "હોલ્ડ", "sell": "વેચો", "strong_sell": "મજબૂત વેચાણ",
580
+ "underperform": "નબળો દેખાવ", "outperform": "સારો દેખાવ", "undervalued": "સસ્તું", "fair": "યોગ્ય",
581
+ "overvalued": "મોંઘું", "good": "સારું", "average": "સરેરાશ", "poor": "નબળું", "moderate": "મધ્યમ"},
582
+ "pa": {"bullish": "ਤੇਜ਼ੀ", "bearish": "ਮੰਦੀ", "neutral": "ਨਿਰਪੱਖ", "low": "ਘੱਟ", "medium": "ਦਰਮਿਆਨਾ", "high": "ਵੱਧ",
583
+ "strong_buy": "ਪੱਕੀ ਖਰੀਦ", "buy": "ਖਰੀਦੋ", "hold": "ਰੱਖੋ", "sell": "ਵੇਚੋ", "strong_sell": "ਪੱਕੀ ਵਿਕਰੀ",
584
+ "underperform": "ਕਮਜ਼ੋਰ ਪ੍ਰਦਰਸ਼ਨ", "outperform": "ਵਧੀਆ ਪ੍ਰਦਰਸ਼ਨ", "undervalued": "ਸਸਤਾ", "fair": "ਠੀਕ",
585
+ "overvalued": "ਮਹਿੰਗਾ", "good": "ਚੰਗਾ", "average": "ਔਸਤ", "poor": "ਕਮਜ਼ੋਰ", "moderate": "ਦਰਮਿਆਨਾ"},
586
+ "ur": {"bullish": "تیزی", "bearish": "مندی", "neutral": "غیر جانبدار", "low": "کم", "medium": "درمیانہ", "high": "زیادہ",
587
+ "strong_buy": "مضبوط خرید", "buy": "خریدیں", "hold": "رکھیں", "sell": "بیچیں", "strong_sell": "مضبوط فروخت",
588
+ "underperform": "کمزور کارکردگی", "outperform": "بہتر کارکردگی", "undervalued": "سستا", "fair": "مناسب",
589
+ "overvalued": "مہنگا", "good": "اچھا", "average": "اوسط", "poor": "کمزور", "moderate": "درمیانہ"},
590
+ "or": {"bullish": "ଉର୍ଦ୍ଧ୍ୱମୁଖୀ", "bearish": "ନିମ୍ନମୁଖୀ", "neutral": "ନିରପେକ୍ଷ", "low": "କମ୍", "medium": "ମଧ୍ୟମ",
591
+ "high": "ଅଧିକ", "strong_buy": "ଦୃଢ଼ କିଣନ୍ତୁ", "buy": "କିଣନ୍ତୁ", "hold": "ରଖନ୍ତୁ", "sell": "ବିକ୍ରି କରନ୍ତୁ",
592
+ "strong_sell": "ଦୃଢ଼ ବିକ୍ରି", "underperform": "ପଛରେ ରହିବ", "outperform": "ଆଗରେ ରହିବ",
593
+ "undervalued": "କମ୍ ମୂଲ୍ୟ", "fair": "ଉଚିତ", "overvalued": "ଅଧିକ ମୂଲ୍ୟ", "good": "ଭଲ", "average": "ହାରାହାରି",
594
+ "poor": "ଦୁର୍ବଳ", "moderate": "ମଧ୍ୟମ"},
595
+ "zh": {"bullish": "看涨", "bearish": "看跌", "neutral": "中性", "low": "低", "medium": "中", "high": "高",
596
+ "strong_buy": "强烈买入", "buy": "买入", "hold": "持有", "sell": "卖出", "strong_sell": "强烈卖出",
597
+ "underperform": "跑输大盘", "outperform": "跑赢大盘", "undervalued": "低估", "fair": "合理", "overvalued": "高估",
598
+ "good": "良好", "average": "一般", "poor": "较差", "moderate": "适中"},
599
+ "ja": {"bullish": "強気", "bearish": "弱気", "neutral": "中立", "low": "低", "medium": "中", "high": "高",
600
+ "strong_buy": "強い買い", "buy": "買い", "hold": "保有", "sell": "売り", "strong_sell": "強い売り",
601
+ "underperform": "アンダーパフォーム", "outperform": "アウトパフォーム", "undervalued": "割安", "fair": "適正",
602
+ "overvalued": "割高", "good": "良好", "average": "普通", "poor": "不良", "moderate": "中程度"},
603
+ "ko": {"bullish": "강세", "bearish": "약세", "neutral": "중립", "low": "낮음", "medium": "보통", "high": "높음",
604
+ "strong_buy": "강력 매수", "buy": "매수", "hold": "보유", "sell": "매도", "strong_sell": "강력 매도",
605
+ "underperform": "시장 하회", "outperform": "시장 상회", "undervalued": "저평가", "fair": "적정", "overvalued": "고평가",
606
+ "good": "양호", "average": "보통", "poor": "미흡", "moderate": "중간"},
607
+ "es": {"bullish": "alcista", "bearish": "bajista", "neutral": "neutral", "low": "bajo", "medium": "medio", "high": "alto",
608
+ "strong_buy": "compra fuerte", "buy": "comprar", "hold": "mantener", "sell": "vender", "strong_sell": "venta fuerte",
609
+ "underperform": "infraponderar", "outperform": "sobreponderar", "undervalued": "infravalorada", "fair": "justa",
610
+ "overvalued": "sobrevalorada", "good": "buena", "average": "media", "poor": "débil", "moderate": "moderado"},
611
+ "fr": {"bullish": "haussier", "bearish": "baissier", "neutral": "neutre", "low": "faible", "medium": "moyen", "high": "élevé",
612
+ "strong_buy": "achat fort", "buy": "acheter", "hold": "conserver", "sell": "vendre", "strong_sell": "vente forte",
613
+ "underperform": "sous-performance", "outperform": "surperformance", "undervalued": "sous-évaluée",
614
+ "fair": "correcte", "overvalued": "surévaluée", "good": "bonne", "average": "moyenne", "poor": "faible",
615
+ "moderate": "modérée"},
616
+ "de": {"bullish": "bullisch", "bearish": "bärisch", "neutral": "neutral", "low": "niedrig", "medium": "mittel",
617
+ "high": "hoch", "strong_buy": "starker Kauf", "buy": "kaufen", "hold": "halten", "sell": "verkaufen",
618
+ "strong_sell": "starker Verkauf", "underperform": "untergewichten", "outperform": "übergewichten",
619
+ "undervalued": "unterbewertet", "fair": "fair", "overvalued": "überbewertet", "good": "gut",
620
+ "average": "durchschnittlich", "poor": "schwach", "moderate": "moderat"},
621
+ "pt": {"bullish": "de alta", "bearish": "de baixa", "neutral": "neutro", "low": "baixo", "medium": "médio", "high": "alto",
622
+ "strong_buy": "compra forte", "buy": "comprar", "hold": "manter", "sell": "vender", "strong_sell": "venda forte",
623
+ "underperform": "desempenho inferior", "outperform": "desempenho superior", "undervalued": "subvalorizada",
624
+ "fair": "justa", "overvalued": "sobrevalorizada", "good": "boa", "average": "média", "poor": "fraca",
625
+ "moderate": "moderado"},
626
+ "ru": {"bullish": "бычий", "bearish": "медвежий", "neutral": "нейтральный", "low": "низкий", "medium": "средний",
627
+ "high": "высокий", "strong_buy": "активно покупать", "buy": "покупать", "hold": "держать", "sell": "продавать",
628
+ "strong_sell": "активно продавать", "underperform": "хуже рынка", "outperform": "лучше рынка",
629
+ "undervalued": "недооценена", "fair": "справедливая", "overvalued": "переоценена", "good": "хорошее",
630
+ "average": "среднее", "poor": "слабое", "moderate": "умеренный"},
631
+ "ar": {"bullish": "صاعد", "bearish": "هابط", "neutral": "محايد", "low": "منخفض", "medium": "متوسط", "high": "مرتفع",
632
+ "strong_buy": "شراء قوي", "buy": "شراء", "hold": "احتفاظ", "sell": "بيع", "strong_sell": "بيع قوي",
633
+ "underperform": "أداء أضعف", "outperform": "أداء أفضل", "undervalued": "مقوّم بأقل من قيمته",
634
+ "fair": "عادل", "overvalued": "مقوّم بأعلى من قيمته", "good": "جيد", "average": "متوسط", "poor": "ضعيف",
635
+ "moderate": "معتدل"},
636
+ "id": {"bullish": "bullish", "bearish": "bearish", "neutral": "netral", "low": "rendah", "medium": "sedang", "high": "tinggi",
637
+ "strong_buy": "beli kuat", "buy": "beli", "hold": "tahan", "sell": "jual", "strong_sell": "jual kuat",
638
+ "underperform": "underperform", "outperform": "outperform", "undervalued": "undervalued", "fair": "wajar",
639
+ "overvalued": "overvalued", "good": "baik", "average": "rata-rata", "poor": "lemah", "moderate": "moderat"},
640
+ }
641
+
642
+
643
+ def normalize_language(code: str | None) -> str:
644
+ """Accept 'ta', 'TA', 'ta-IN', 'Tamil', 'தமிழ்' -> 'ta' (unknown -> 'en')."""
645
+ if not code:
646
+ return "en"
647
+ code = code.strip()
648
+ if code in LANGUAGES:
649
+ return code
650
+ lowered = code.lower()
651
+ for key, (native, english) in LANGUAGES.items():
652
+ if lowered in (key.lower(), native.lower(), english.lower()):
653
+ return key
654
+ base = lowered.split("-")[0].split("_")[0]
655
+ return base if base in LANGUAGES else "en"
656
+
657
+
658
+ def has_builtin(lang: str) -> bool:
659
+ return lang in BUILTIN_LANGUAGES
660
+
661
+
662
+ def t(lang: str, key: str, **kwargs) -> str:
663
+ """Label in `lang`, falling back to English for AI-only languages."""
664
+ text = _STRINGS.get(lang, {}).get(key) or _EN[key]
665
+ return text.format(**kwargs) if kwargs else text
666
+
667
+
668
+ def tv(lang: str, value: str | None) -> str:
669
+ """Translate a value word (signal, rating, level); unknown words pass through."""
670
+ if not value:
671
+ return ""
672
+ key = str(value).strip().lower().replace(" ", "_")
673
+ return _VALUES.get(lang, {}).get(key) or _EN_VALUES.get(key) or str(value).replace("_", " ")
674
+
675
+
676
+ def language_name(lang: str) -> str:
677
+ native, english = LANGUAGES.get(lang, (lang, lang))
678
+ return english