{"_id":"@andy-toolforge/vn-stock","_rev":"5-35679d604de4fba288c761f17565ceb7","name":"@andy-toolforge/vn-stock","dist-tags":{"latest":"0.2.3"},"versions":{"0.1.0":{"name":"@andy-toolforge/vn-stock","version":"0.1.0","_id":"@andy-toolforge/vn-stock@0.1.0","maintainers":[{"name":"andy_pham","email":"phamlehoaian@gmail.com"}],"homepage":"https://github.com/andy-pham-it/toolforge#readme","bugs":{"url":"https://github.com/andy-pham-it/toolforge/issues"},"dist":{"shasum":"91a61935cfd19b0b82210733022c33ad181f6d3b","tarball":"https://registry.npmjs.org/@andy-toolforge/vn-stock/-/vn-stock-0.1.0.tgz","fileCount":14,"integrity":"sha512-neDfLfk94fxyxIc5+7sa8c4rjwjGdHyOpMOdrLOq6CDkex7OMt5qds0aK6XTMNazIBBjpf4K95ZJ3SzDQc3mLA==","signatures":[{"sig":"MEQCID03EWZ6yOt/a2eA4AHv4vdG3jVy/FtizBudlbIcibtnAiBijjdpjWLB9jP5To48r3lpHnAP+qjJJLiq9Po1R5HSVw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":100721},"main":"lib/index.js","gitHead":"450539c9b90b4f5345760a11e07186cdae2b7163","scripts":{"test":"node --test lib/*.test.js","postinstall":"node skills/postinstall.js"},"_npmUser":{"name":"andy_pham","email":"phamlehoaian@gmail.com"},"repository":{"url":"git+https://github.com/andy-pham-it/toolforge.git","type":"git"},"_npmVersion":"10.8.2","description":"Toolforge domain: VN stock screener and scanner — technical analysis, screening, scoring from MongoDB data","directories":{},"_nodeVersion":"20.20.2","dependencies":{"mongodb":"^6.0.0","@andy-toolforge/core":"^1.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/vn-stock_0.1.0_1783958445701_0.06692670169876025","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@andy-toolforge/vn-stock","version":"0.2.0","_id":"@andy-toolforge/vn-stock@0.2.0","maintainers":[{"name":"andy_pham","email":"phamlehoaian@gmail.com"}],"homepage":"https://github.com/andy-pham-it/toolforge#readme","bugs":{"url":"https://github.com/andy-pham-it/toolforge/issues"},"dist":{"shasum":"b46476a02dc083158590a7d0932a772c36b86864","tarball":"https://registry.npmjs.org/@andy-toolforge/vn-stock/-/vn-stock-0.2.0.tgz","fileCount":14,"integrity":"sha512-Oty5X7+9zvzdaw2NmoxLVT/HB8WyORLd3WsMzwalgBZh/wsMCvneIKvKZly0MH3BBAwAZoRTnpyxzsUZ+FI23g==","signatures":[{"sig":"MEYCIQC5oRpeG6g5bjjS2oUgPqHygVjP7J1Ba6/7aTc13XEUrAIhAMNZo4xhcayuwygNM1J7BRnVUEjawv5Q/+lrXZiGHji0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":100967},"main":"lib/index.js","gitHead":"a42b14ba680c2b815e38ad09bc76ba31ca2fefe1","scripts":{"test":"node --test lib/*.test.js","postinstall":"node skills/postinstall.js"},"_npmUser":{"name":"andy_pham","email":"phamlehoaian@gmail.com"},"repository":{"url":"git+https://github.com/andy-pham-it/toolforge.git","type":"git"},"_npmVersion":"10.8.2","description":"Toolforge domain: VN stock screener and scanner — technical analysis, screening, scoring from MongoDB data","directories":{},"_nodeVersion":"20.20.2","dependencies":{"mongodb":"^6.0.0","@andy-toolforge/core":"^1.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/vn-stock_0.2.0_1784005925920_0.8176653164795964","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@andy-toolforge/vn-stock","version":"0.2.1","_id":"@andy-toolforge/vn-stock@0.2.1","maintainers":[{"name":"andy_pham","email":"phamlehoaian@gmail.com"}],"homepage":"https://github.com/andy-pham-it/toolforge#readme","bugs":{"url":"https://github.com/andy-pham-it/toolforge/issues"},"dist":{"shasum":"8e88ce36df1300a96327ab5fa7ae0f7cadeabef1","tarball":"https://registry.npmjs.org/@andy-toolforge/vn-stock/-/vn-stock-0.2.1.tgz","fileCount":23,"integrity":"sha512-T/OjBz6VmmIxo0Db6ojPf9aZs1shss+yMpvMViOPWDwPYDAP64Mm6k3qcCUVTfoJ/yg/juzfb26ePZStoAfEEQ==","signatures":[{"sig":"MEUCIDR2hQiOHCMG3Mq6sbL6F/Ca5Tnx+NurZ+vmQa1j/uaZAiEA6ZGbg+OFehb2g2eUH3AthvG7FKDs+SJ64eH3V8liyVw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":168299},"main":"lib/index.js","gitHead":"f40b9940c6eec4e49f48b2e0671fbfaa9ff7e711","scripts":{"test":"node --test lib/*.test.js","postinstall":"node skills/postinstall.js"},"_npmUser":{"name":"andy_pham","email":"phamlehoaian@gmail.com"},"repository":{"url":"git+https://github.com/andy-pham-it/toolforge.git","type":"git"},"_npmVersion":"10.8.2","description":"Toolforge domain: VN stock screener and scanner — technical analysis, screening, scoring from MongoDB data","directories":{},"_nodeVersion":"20.20.2","dependencies":{"mongodb":"^6.0.0","@andy-toolforge/core":"^1.0.0","@andy-toolforge/genai-tools":"^0.1.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/vn-stock_0.2.1_1784202678021_0.9192200158633921","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@andy-toolforge/vn-stock","version":"0.2.2","_id":"@andy-toolforge/vn-stock@0.2.2","maintainers":[{"name":"andy_pham","email":"phamlehoaian@gmail.com"}],"homepage":"https://github.com/andy-pham-it/toolforge#readme","bugs":{"url":"https://github.com/andy-pham-it/toolforge/issues"},"dist":{"shasum":"660bde5578385270b8be026b6d7d3b340c4ae487","tarball":"https://registry.npmjs.org/@andy-toolforge/vn-stock/-/vn-stock-0.2.2.tgz","fileCount":23,"integrity":"sha512-cWRqDEr2uwfo6yAQFDU+1pv5+9co0G0Hz6sRyLUHl9ODzyWGvtMZ2ZO/bclWNix05hkVw14q47F4P617+RcpfA==","signatures":[{"sig":"MEQCIHoYI7Iyvw6/wyJz/B0zkA6g50++O6yNyCsjKaedhC6CAiB0jFu546fB6Om4jRdayHc6xvl0LnMMDpsHD58asMMAuw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":169386},"main":"lib/index.js","gitHead":"b7d978bea4f8b1338a5af8584318383429bb558b","scripts":{"test":"node --test lib/*.test.js","postinstall":"node skills/postinstall.js"},"_npmUser":{"name":"andy_pham","email":"phamlehoaian@gmail.com"},"repository":{"url":"git+https://github.com/andy-pham-it/toolforge.git","type":"git"},"_npmVersion":"10.8.2","description":"Toolforge domain: VN stock screener and scanner — technical analysis, screening, scoring from MongoDB data","directories":{},"_nodeVersion":"20.20.2","dependencies":{"mongodb":"^6.0.0","@andy-toolforge/core":"^1.0.0","@andy-toolforge/genai-tools":"^0.1.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/vn-stock_0.2.2_1784221627603_0.11387326039954115","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@andy-toolforge/vn-stock","version":"0.2.3","description":"Toolforge domain: VN stock screener and scanner — technical analysis, screening, scoring from MongoDB data","main":"lib/index.js","repository":{"type":"git","url":"git+https://github.com/andy-pham-it/toolforge.git"},"scripts":{"postinstall":"node skills/postinstall.js","test":"node --test lib/*.test.js"},"dependencies":{"@andy-toolforge/core":"^1.0.0","@andy-toolforge/genai-tools":"^0.1.0","mongodb":"^6.0.0"},"_id":"@andy-toolforge/vn-stock@0.2.3","gitHead":"13f8dac5f981440ff64e699c165978285c470e1a","bugs":{"url":"https://github.com/andy-pham-it/toolforge/issues"},"homepage":"https://github.com/andy-pham-it/toolforge#readme","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-+6RugPU1M9v6LvugsAl6+w1AMNcqg+vuIoGrCxGvgKvOlimhm4ZMBJEJLgHp6XejjjTgcf9IdxiPHRO474Htvg==","shasum":"bb830838017ca8dab1115ae59ddabd355e535677","tarball":"https://registry.npmjs.org/@andy-toolforge/vn-stock/-/vn-stock-0.2.3.tgz","fileCount":23,"unpackedSize":172598,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCcL2DwdAdBrfZfVJY/9sIAwusxqyhP/ZhCZEklgUg3nAIhANjz2Rctq9Y2Rck2hovdBOAdlMUjOebr7lW/LJ1RUNp8"}]},"_npmUser":{"name":"andy_pham","email":"phamlehoaian@gmail.com"},"directories":{},"maintainers":[{"name":"andy_pham","email":"phamlehoaian@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vn-stock_0.2.3_1784305217692_0.4075349038484539"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-13T16:00:45.484Z","modified":"2026-07-17T16:20:18.000Z","0.1.0":"2026-07-13T16:00:45.881Z","0.2.0":"2026-07-14T05:12:06.121Z","0.2.1":"2026-07-16T11:51:18.171Z","0.2.2":"2026-07-16T17:07:07.779Z","0.2.3":"2026-07-17T16:20:17.849Z"},"bugs":{"url":"https://github.com/andy-pham-it/toolforge/issues"},"homepage":"https://github.com/andy-pham-it/toolforge#readme","repository":{"type":"git","url":"git+https://github.com/andy-pham-it/toolforge.git"},"description":"Toolforge domain: VN stock screener and scanner — technical analysis, screening, scoring from MongoDB data","maintainers":[{"name":"andy_pham","email":"phamlehoaian@gmail.com"}],"readme":"# @andy-toolforge/vn-stock\n\n[![npm](https://img.shields.io/npm/v/@andy-toolforge/vn-stock)](https://npmjs.com/package/@andy-toolforge/vn-stock)\n[![License](https://img.shields.io/npm/l/@andy-toolforge/vn-stock)](https://github.com/andy-pham-it/toolforge)\n\n**VN stock market screening, scoring, signal detection, and technical indicator calculation.** Thuộc hệ sinh thái [toolforge](https://github.com/andy-pham-it/toolforge).\n\nPackage này giúp bạn:\n- Sàng lọc cổ phiếu VN theo điều kiện kỹ thuật (RSI, EMA, MACD, volume...)\n- Chấm điểm đa yếu tố (technical, volume, momentum, fundamental)\n- Phát hiện tín hiệu giao dịch (17+ patterns: trend, momentum, volatility, price action)\n- Tính toán chỉ báo kỹ thuật qua Python engine (29 indicators)\n- Tích hợp MCP server cho AI agent\n\n## Installation\n\n```bash\nnpm install @andy-toolforge/vn-stock\n```\n\nYêu cầu `@andy-toolforge/core` và `mongodb` (tự động cài kèm).\n\nĐể sử dụng Indicator Calculation (Python bridge), cần cài thêm:\n\n```bash\nuv sync  # trong thư mục py-packages/vn-stock-indicators/\n```\n\n## API Reference\n\n```javascript\nconst {\n    StockDB,              // MongoDB connection & collection helpers\n    StockScreener,        // Filter/screen stocks by technical conditions\n    StockScorer,          // Multi-factor scoring engine (0-100)\n    SignalDetector,       // Detect 17 technical signals\n    IndicatorEngine,      // Python subprocess bridge — 29 indicators\n    IndicatorEngineError, // Error class with code property\n} = require('@andy-toolforge/vn-stock');\n```\n\n---\n\n### StockDB\n\nKết nối MongoDB và truy vấn dữ liệu cổ phiếu. Dữ liệu được pre-fetched bởi fetch team — không gọi API trực tiếp.\n\n**Constructor:** `new StockDB()`\n\n**Methods:**\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `connect()` | `Promise<void>` | Kết nối MongoDB (stock_db) |\n| `close()` | `Promise<void>` | Đóng kết nối |\n| `getLatestCandles(symbols, limit)` | `Array` | Lấy N candle gần nhất cho từng symbol |\n| `getIntradayIndicators(symbols?)` | `Array` | Lấy intraday indicators (15m/1h) |\n| `getFundamentals(symbols)` | `Array` | Lấy dữ liệu cơ bản (PE, PB, ROE...) |\n\n---\n\n### StockScreener\n\nSàng lọc cổ phiếu theo điều kiện kỹ thuật — daily và intraday.\n\n**Constructor:** `new StockScreener()`\n\n**Methods:**\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `screenDaily({ filters, sortBy, limit })` | `Array` | Screen daily với filter operators |\n| `screenIntraday({ filters, interval, sortBy, limit })` | `Array` | Screen intraday (15m/1h) |\n| `getSymbolInfo(symbol)` | `Object` | Full info: daily + intraday + fundamentals |\n\n```javascript\nconst { StockScreener } = require('@andy-toolforge/vn-stock');\nconst screener = new StockScreener();\n\n// RSI oversold + EMA uptrend\nconst results = await screener.screenDaily({\n    filters: [\n        { field: 'rsi', operator: 'lt', value: 30 },\n        { field: 'ema20', operator: 'gt', compareToField: 'ema50' },\n    ],\n    sortBy: 'rsi',\n    limit: 20,\n});\n\n// Intraday: 15m RSI oversold\nconst intraday = await screener.screenIntraday({\n    filters: [{ field: 'rsi', operator: 'lt', value: 25 }],\n    interval: '15m',\n});\n\n// Single symbol\nconst info = await screener.getSymbolInfo('FPT');\nconsole.log(info.daily?.rsi, info.fundamentals?.pe);\n```\n\n**Filter Operators:**\n\n| Operator | Mô tả |\n|----------|-------|\n| `gt` / `gte` | Lớn hơn / lớn hơn hoặc bằng |\n| `lt` / `lte` | Nhỏ hơn / nhỏ hơn hoặc bằng |\n| `eq` / `neq` | Bằng / không bằng |\n| `crossAbove` | Cắt lên (field > compareToField, trước đó <=) |\n| `crossBelow` | Cắt xuống (field < compareToField, trước đó >=) |\n\n---\n\n### StockScorer\n\nChấm điểm cổ phiếu 0-100 theo 4 yếu tố.\n\n**Constructor:** `new StockScorer({ weights? })`\n\n**Methods:**\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `scoreCandle(candle, fundamentals?, prevCandle?)` | `{ total, breakdown }` | Chấm điểm một candle |\n| `scoreAll({ limit })` | `Array` | Xếp hạng tất cả symbols (daily) |\n| `scoreIntraday(symbol, interval?)` | `Object\\|null` | Chấm điểm intraday 1 symbol |\n| `scoreAllIntraday({ interval, limit })` | `Array` | Xếp hạng tất cả symbols (intraday) |\n\n**Scoring Factors:**\n\n| Factor | Weight | Indicators |\n|--------|:------:|------------|\n| **Technical** | 40% | RSI (30%), EMA20/50/100 alignment (40%), MACD cross + histogram (30%), Bollinger position + squeeze (bonus), ATR (bonus) |\n| **Volume** | 20% | Volume vs vol_ma20 ratio (4 thresholds), OBV divergence |\n| **Momentum** | 20% | Price change % (5 thresholds), MFI (4 zones), Stochastic crossover, VWAP distance |\n| **Fundamental** | 20% | PE, PB, ROE, EPS growth (5 zones mỗi chỉ số); defaults to 50 nếu không có data |\n\n```javascript\nconst { StockScorer } = require('@andy-toolforge/vn-stock');\nconst scorer = new StockScorer();\n\n// Score all symbols (auto-ranked)\nconst ranked = await scorer.scoreAll({ limit: 20 });\n\n// Intraday scoring\nconst intradayRanked = await scorer.scoreAllIntraday({ interval: '15m', limit: 20 });\nconst fpt15m = await scorer.scoreIntraday('FPT', '15m');\n\n// Single candle with custom weights\nconst scorer2 = new StockScorer({ weights: { technical: 0.5, volume: 0.3, momentum: 0.2, fundamental: 0 } });\nconst result = scorer2.scoreCandle(\n    { rsi: 72, ema20: 110, ema50: 100, volume: 2e6, vol_ma20: 500000, price_change_pct: 3.5, obv: 1500 },\n    { pe: 12, pb: 1.5, roe: 18 },\n    { obv: 1300 }\n);\nconsole.log(result.total, result.breakdown);\n```\n\n---\n\n### SignalDetector\n\nPhát hiện tín hiệu giao dịch từ dữ liệu nến + chỉ báo — 17 methods, 6 categories.\n\n**Constructor:** `new SignalDetector(config?)`\n\n**Methods:**\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `getSignals(candle, prevCandle?)` | `Array` | Tất cả tín hiệu phát hiện được |\n| `getSignalsGrouped(candle, prevCandle?)` | `Object` | Tín hiệu grouped theo category |\n\n**Detection Categories:**\n\n| Category | Signals |\n|----------|---------|\n| **Trend** | MACD crossover, EMA crossover, EMA alignment |\n| **Momentum** | RSI oversold/overbought, RSI divergence, Stochastic crossover |\n| **Volatility** | Bollinger squeeze/breakout, ATR breakout |\n| **Volume** | Volume spike, Volume SMA breakout, Volume divergence |\n| **Flow / MCDX** | MFI (Money Flow Index) zones |\n| **Price Action** | Engulfing, Doji, Hammer, Price reversal |\n\n```javascript\nconst { SignalDetector } = require('@andy-toolforge/vn-stock');\nconst detector = new SignalDetector();\n\n// Detect all signals\nconst signals = detector.getSignals(candle, prevCandle);\n// → [{ type: 'EMA_CROSSOVER', direction: 'bullish', strength: 0.85, message: '...' }, ...]\n\n// Grouped by category\nconst grouped = detector.getSignalsGrouped(candle, prevCandle);\n// → { trend: [...], momentum: [...], volatility: [...], volume: [...], flow: [...], priceAction: [...] }\n\n// Custom thresholds\nconst custom = new SignalDetector({\n    rsi: { oversold: 25, overbought: 75 },\n    volume: { spikeRatio: 3.0 },\n});\n```\n\n---\n\n### IndicatorEngine\n\nTính toán chỉ báo kỹ thuật bằng Python engine (`vn-stock-indicators`). Hỗ trợ 29 indicators qua 2 chế độ.\n\n**Constructor:** `new IndicatorEngine({ mode?, pythonPath?, mongoUri? })`\n\n**Methods:**\n\n| Method | Returns | Description |\n|--------|---------|-------------|\n| `compute({ indicators, ohlcv, params })` | `Object` | Tính indicators từ OHLCV data |\n| `fetchAndCompute({ symbol, source, indicators, params, limit })` | `Object` | Fetch từ MongoDB + tính |\n| `connect()` | `void` | Kết nối pool mode |\n| `disconnect()` | `void` | Ngắt kết nối pool mode |\n\n**Chế độ hoạt động:**\n\n| Mode | Mô tả |\n|------|-------|\n| `spawn` (default) | Mỗi lần gọi spawn một Python process mới. Phù hợp gọi ít, không cần maintain state. |\n| `pool` | Giữ Python process persistent, giao tiếp qua JSON-line protocol. Nhanh hơn khi gọi nhiều lần. |\n\n**29 Indicators hỗ trợ:**\n\n| Category | Functions |\n|----------|-----------|\n| **Trend** | sma, ema, wema, wma, dema, tema, macd, adx, psar, ichimoku |\n| **Momentum** | rsi, stochastic, williams_r, cci, mfi, roc |\n| **Volatility** | bollinger_bands, atr, keltner, volatility |\n| **Volume** | obv, volume_sma, vwap, ad, adosc |\n| **Price Action** | support_resistance, pivot_points, detect_engulfing, detect_doji, detect_hammer |\n\n```javascript\nconst { IndicatorEngine } = require('@andy-toolforge/vn-stock');\n\n// Spawn mode (one-off)\nconst engine = new IndicatorEngine();\nconst result = await engine.compute({\n    indicators: ['sma', 'ema', 'rsi', 'macd', 'bbands'],\n    ohlcv: { open: [...], high: [...], low: [...], close: [...], volume: [...] },\n    params: { sma: [20, 50], ema: [20], rsi: [14] },\n});\n\n// Pool mode (reuse process)\nconst pool = new IndicatorEngine({ mode: 'pool', pythonPath: 'uv' });\nawait pool.connect();\nconst r1 = await pool.compute({ indicators: ['sma'], ohlcv: {...}, params: { sma: [20] } });\nconst r2 = await pool.compute({ indicators: ['rsi'], ohlcv: {...}, params: { rsi: [14] } });\nawait pool.disconnect();\n\n// Fetch from MongoDB + compute\nconst mongo = new IndicatorEngine({ mongoUri: 'mongodb://localhost:27017' });\nconst fromDb = await mongo.fetchAndCompute({\n    symbol: 'FPT', source: 'daily',\n    indicators: ['sma', 'ema', 'rsi'],\n    params: { sma: [20, 50], ema: [20], rsi: [14] },\n});\n```\n\n---\n\n## MCP Tools\n\nPackage này tự động đăng ký 4 tools với `@andy-toolforge/mcp` qua cơ chế discovery:\n\n| Tool | Description |\n|------|-------------|\n| `toolforge_vn_stock_screen` | Screen cổ phiếu theo filter conditions (daily) |\n| `toolforge_vn_stock_info` | Lấy full info symbol (daily + intraday + fundamentals) |\n| `toolforge_vn_stock_score` | Xếp hạng tất cả stocks theo daily multi-factor score |\n| `toolforge_vn_stock_score_intraday` | Xếp hạng intraday (15m/1h), không có fundamental |\n| `toolforge_vn_stock_analyze` | AI analysis — recommendation, score, reasoning for a symbol |\n| `toolforge_vn_stock_deep_dive` | Deep dive — entry/exit, SL, support/resistance, risk/reward |\n| `toolforge_vn_stock_compare` | Compare multiple symbols — ranking, top pick, AI summary |\n\n## Testing\n\n```bash\nnpm test -w @andy-toolforge/vn-stock\n```\n","readmeFilename":"README.md"}