From 50ab2cf69c64db66a27c3c01e3abaa36e5b10e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E4=B8=9C=E4=BA=91?= Date: Mon, 10 Feb 2025 18:30:16 +0800 Subject: [PATCH] Initialize project structure with Bun, Elysia, and AI-powered article summarization --- .gitignore | 175 +++++++++++++++++++++++++++++++++++++++++++ 2025-2-10.md | 13 ++++ README.md | 15 ++++ bak/ai.js | 15 ++++ bak/rss.js | 21 ++++++ bak/server.js | 29 +++++++ bak/wechat.js | 24 ++++++ bun.lockb | Bin 0 -> 43722 bytes config.json | 0 global.d.ts | 1 + history/2025/2/10.md | 78 +++++++++++++++++++ index.ts | 143 +++++++++++++++++++++++++++++++++++ jsconfig.json | 27 +++++++ package.json | 20 +++++ style.css | 11 +++ wechat.js | 16 ++++ 16 files changed, 588 insertions(+) create mode 100644 .gitignore create mode 100644 2025-2-10.md create mode 100644 README.md create mode 100644 bak/ai.js create mode 100644 bak/rss.js create mode 100644 bak/server.js create mode 100644 bak/wechat.js create mode 100755 bun.lockb create mode 100644 config.json create mode 100644 global.d.ts create mode 100644 history/2025/2/10.md create mode 100644 index.ts create mode 100644 jsconfig.json create mode 100644 package.json create mode 100644 style.css create mode 100644 wechat.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b1ee42 --- /dev/null +++ b/.gitignore @@ -0,0 +1,175 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/2025-2-10.md b/2025-2-10.md new file mode 100644 index 0000000..d3face5 --- /dev/null +++ b/2025-2-10.md @@ -0,0 +1,13 @@ +# 总结 + +**核心观点:** + +* **指数层面:** 虽然今天收小阳线,但存在隐患,主要问题是成交量大幅萎缩,即便突破3322点(60日线)问题可能更大。下午的上攻伴随量能萎缩,呈现量价背离,需要警惕。 +* **操作建议:** 如果明天高开个股出现进攻衰竭信号,可适当减仓,以防量能持续萎缩导致市场降温。但由于今天只是第一天量价不匹配,若未来量能能再次放大,则个股仍有操作空间。 +* **仓位:** 个人维持5-5.5成仓位,消费和医药持仓为主,不考虑加仓。目前位置不适合中线布局,除非是长线布局。 +* **DS题材(可能指数字经济或算力概念):** 目前已进入深度博傻阶段,等待接盘侠。三大运营商(电信、联通)必须持续冲新高,否则可能面临负反馈。资金不会立刻撤出DS,仍会在科技股中流动,直到更大的利好出现。 +* **风险提示:** 不建议追高DS题材,现在入场已经太晚,如果要参与只能小仓位短线投机,并设置止损。不要盲目相信科技信仰,避免高位接盘。 + +**总结:** + +作者认为当前市场存在量价背离的隐患,建议谨慎操作,注意控制仓位。对于近期火热的DS题材,作者持谨慎态度,认为已进入博傻阶段,不建议追高。 diff --git a/README.md b/README.md new file mode 100644 index 0000000..b4a02e7 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# info_flow + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.js +``` + +This project was created using `bun init` in bun v1.1.37. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/bak/ai.js b/bak/ai.js new file mode 100644 index 0000000..edccd1a --- /dev/null +++ b/bak/ai.js @@ -0,0 +1,15 @@ +// ai.js +export async function analyzeContent(content) { + // 假设DeepSeek API的调用方式 + const response = await fetch("https://api.deepseek.com/v1/analyze", { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": "Bearer sk-75972dd6431e4440a0428fa8922ed6b1", + }, + body: JSON.stringify({ content }), + }); + const result = await response.json(); + console.log('Result:', result); + return result.summary; // 假设返回的是Markdown格式的总结 +} diff --git a/bak/rss.js b/bak/rss.js new file mode 100644 index 0000000..003d34f --- /dev/null +++ b/bak/rss.js @@ -0,0 +1,21 @@ +// ... existing code ... +export async function fetchRSS(url, maxRetries = 3) { + let retries = 0; + while (retries < maxRetries) { + try { + const response = await fetch(url, { verbose: true, keepalive: true, timeout: 10000, compress: false }); + // console.log('Response:', response); + const text = await response.text(); + // console.log('Response Text:', text); + return text; + } catch (error) { + console.error(`Fetch Error (Attempt ${retries + 1}):`, error); + retries++; + // 等待一段时间再重试,避免过于频繁的请求 + await new Promise(resolve => setTimeout(resolve, 1000)); + } + } + console.error('Fetch failed after multiple retries.'); + return null; +} +// ... existing code ... \ No newline at end of file diff --git a/bak/server.js b/bak/server.js new file mode 100644 index 0000000..bfbd872 --- /dev/null +++ b/bak/server.js @@ -0,0 +1,29 @@ +// server.js +import { serve } from "bun"; +import { fetchRSS } from "./rss.js"; +import { analyzeContent } from "./ai.js"; +import { getWeChatArticleLinks } from "./wechat.js"; +const PORT = 3000; + +async function handleRequest(request) { + // 从环境变量中获取 RSS URL,如果没有则使用默认值 + const rssUrl = "https://mp.weixin.qq.com/s/vQgsMuxXffpFZkNFj89wUQ"; + try { + const rssContent = await fetchRSS(rssUrl); + const analyzedContent = await analyzeContent(rssContent); + + return new Response(analyzedContent, { + headers: { "Content-Type": "text/markdown" }, + }); + } catch (error) { + console.error("Error processing request:", error); + return new Response("Error processing request", { status: 500 }); + } +} + +serve({ + port: PORT, + fetch: handleRequest, +}); + +console.log(`Server running at http://localhost:${PORT}`); diff --git a/bak/wechat.js b/bak/wechat.js new file mode 100644 index 0000000..c7f4851 --- /dev/null +++ b/bak/wechat.js @@ -0,0 +1,24 @@ +import { JSDOM } from 'jsdom'; + +async function getWeChatArticleLinks(publicAccountName) { + // const searchUrl = `https://weixin.sogou.com/weixin?p=01030402&query=${encodeURIComponent(publicAccountName)}&type=2&ie=utf8`; + // const response = await fetch(searchUrl); + console.log(`https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=${publicAccountName}`); + const response = await fetch(`https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&__biz=${publicAccountName}`, { + headers: { + 'Referer': `https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=${publicAccountName}` + } +}); + const html = await response.text(); + + const { document } = new JSDOM(html).window; + const articleLinks = []; + const articleElements = document.querySelectorAll('.news-box .news-list li a'); + articleElements.forEach((element) => { + const link = element.href; + articleLinks.push(link); + }); + return articleLinks; +} + +export { getWeChatArticleLinks }; \ No newline at end of file diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..b546e67465dfc73b43f142cc2f8158e60c33f0cf GIT binary patch literal 43722 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 literal 0 HcmV?d00001 diff --git a/config.json b/config.json new file mode 100644 index 0000000..e69de29 diff --git a/global.d.ts b/global.d.ts new file mode 100644 index 0000000..9e77821 --- /dev/null +++ b/global.d.ts @@ -0,0 +1 @@ +declare module '@elysiajs/html'; \ No newline at end of file diff --git a/history/2025/2/10.md b/history/2025/2/10.md new file mode 100644 index 0000000..1efbbfb --- /dev/null +++ b/history/2025/2/10.md @@ -0,0 +1,78 @@ +好的,我已经收到了你提供的三篇文章。现在我将对它们进行分析,并为你设计短、中、长线的投资策略。 + +**一、文章核心内容总结:** + +* **文章1(2.10日收盘总结):** + * **市场隐患:** 量能大幅缩量,下午出现量价背离,进攻衰竭信号。 + * **操作建议:** 尾盘/明早高开出现进攻衰竭信号的个股减仓。如果后续量能放大或维持常态,则个股仍可操作,不轻易大减仓。 + * **仓位建议:** 维持5-5.5成仓位。消费和医药持仓为主,不加仓。 + * **投资策略:** 中线布局意义不大,除非是半年以上不动的大长线布局。 + * **Deepseek (DS) 风险:** 深度博傻阶段,等接盘侠。三大运营商必须继续冲新高,否则负反馈可能开始。不建议追高,手痒玩玩投机仓短线带好止损。资金仍在科技股里流动,等待更大层面的重磅利好。 +* **文章2 (阳气乍露,日之初升):** + * **市场定性:** 情绪周期为上升。 + * **操作建议:** 关注拓维信息、华胜天成,给机会可考虑上车。 + * **Deepseek (DS) 策略:** DS是市场最强主线,等待DS大分歧时上车补票。前排给机会大胆上车。 +* **文章3 (重要提示):** + * **应对策略:** 在节奏感不好的时候,耐心等待一个看得懂的极致最票的模式内机会。 + * **龙头战法:** 行情超预期走强后,重新改变行情定性,出现龙头强分机会。 + * **案例:** 每日互动 (DS概念),行情级别在确定性扩大加强,作为市场最强票,绕不过去。 + * **强趋势股梳理:** 列举了云服务、DS、哪吒、AI医疗、端侧、智驾、机器人等方向的个股,作为一段时间内的观察标的。 + * **主要题材梳理:** DS概念、中兵系重组。 + +**二、投资策略设计:** + +综合以上三篇文章的信息,我可以为你设计一个短中长线的投资策略,请注意,这只是根据提供的资料做出的建议,实际投资需要结合你的风险承受能力、资金情况和市场变化灵活调整。 + +**1. 短线策略(1-3周):** + +* **核心:** 把握Deepseek (DS) 的短线机会,但控制风险。 +* **选股:** + * **激进型:** 关注DS概念中的龙头个股,如文章3提到的每日互动,或者其他文中提及的DS概念股。 + * **稳健型:** 等待DS概念出现大分歧时,选择调整充分、基本面较好的个股逢低介入。关注文章2提到的拓维信息、华胜天成,若调整到位可考虑。 +* **操作:** + * 严格止损:因为DS概念处于博傻阶段,一旦出现亏损,立即止损。文章1建议手痒玩玩投机仓短线带好止损。 + * 快进快出:不恋战,赚取快钱,避免成为接盘侠。 + * 关注量价关系:文章1提到量价背离是风险信号,要警惕。 +* **仓位:** 短线仓位控制在总仓位的10-20%。 + +**2. 中线策略(3个月-1年):** + +* **核心:** 围绕科技主线,选择有业绩支撑、成长性较好的个股,适当关注消费和医药。 +* **选股:** + * **科技:** 从云服务、AI医疗、端侧、智驾、机器人等方向中,选择细分行业的龙头企业。 + * **消费/医药:** 持有原有仓位,不加仓。 +* **操作:** + * 逢低布局:选择在回调时逐步建仓。 + * 价值投资:关注公司的基本面,长期持有。 +* **仓位:** 中线仓位控制在总仓位的30-40%。 + +**3. 长线策略(1年以上):** + +* **核心:** 低位布局,长期持有,耐心等待。 +* **选股:** + * **低估值潜力股:** 寻找被市场低估的、有长期发展潜力的个股。 + * **行业龙头:** 选择具有长期竞争优势的行业龙头企业。 +* **操作:** + * 分批建仓:在低位分批买入,降低成本。 + * 长期持有:不轻易交易,享受企业成长带来的收益。 +* **仓位:** 长线仓位控制在总仓位的30-40%。 + +**4. 整体仓位控制:** + +* 根据你的风险承受能力,将总仓位控制在50-70%。 +* 短、中、长线仓位的比例可以根据市场情况进行调整。 +* 保留一定的现金,以备不时之需。 + +**5. 风险提示:** + +* 股市有风险,投资需谨慎。 +* 密切关注市场动态,及时调整投资策略。 +* 不要盲目跟风,要有自己的判断。 +* 控制好仓位,避免过度投资。 + +**6. 需要进一步考虑的问题:** + +* **文章1中提到“其他更大更高层面的重磅利好”是什么?** 这个利好出现时,可能会打破DS的局面,需要密切关注。 +* **中兵系重组的机会如何?** 文章3提到了中兵系重组,可以进一步研究相关标的。 + +希望这个策略能给你一些参考。记住,投资需要不断学习和实践,才能找到最适合自己的方法。祝你投资顺利! diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..2a5582d --- /dev/null +++ b/index.ts @@ -0,0 +1,143 @@ +import { Elysia } from "elysia"; +import { html } from '@elysiajs/html' +import { JSDOM } from 'jsdom'; +import { GoogleGenerativeAI } from "@google/generative-ai"; + +const genAI = new GoogleGenerativeAI(process.env.API_KEY || ""); + +const model = genAI.getGenerativeModel({ model: "gemini-2.0-flash-lite-preview-02-05" }); + +async function callGeminiAPI(articleContent: string): Promise { + // articleContent = `You are a helpful assistant that summarizes WeChat articles.use Chinese: ${articleContent}`; + // const response = (await model.generateContent(articleContent)).response; + // return response.text(); + + + const { + GoogleGenerativeAI, + HarmCategory, + HarmBlockThreshold, + } = require("@google/generative-ai"); + + const apiKey = process.env.API_KEY; + const genAI = new GoogleGenerativeAI(apiKey); + + const model = genAI.getGenerativeModel({ + model: "gemini-2.0-flash", + }); + + const generationConfig = { + temperature: 1, + topP: 0.95, + topK: 40, + maxOutputTokens: 8192, + responseMimeType: "text/plain", + }; + + async function run(articleContent: string) { + const chatSession = model.startChat({ + generationConfig, + history: [ + { + role: "user", + parts: [ + { text: "接下来我会给你提供几篇文章,用---和换行分割。如果是投资主题,我希望你能帮我总结和设计出一个短中长线的投资策略:" }, + ], + }, + { + role: "model", + parts: [ + { text: "请提供你说的文章,我会根据内容总结并设计投资策略。你需要将几篇文章用`---`和换行分割,像你例子里那样。" }, + ], + }, + { + role: "user", + parts: [ + { text: articleContent }, + ], + } + ], + }); + + const result = await chatSession.sendMessage("INSERT_INPUT_HERE"); + console.log(result.response.text()); + return result.response.text(); + } + + return run(articleContent); +} + +const app = new Elysia() + .use(html()) + .get("/", () => ` + + + + 文章总结 + + +

输入微信文章链接

+
+
+

+ +
+ + + `) + .post("/summarize", async ({ body }) => { + try { + const { articleUrl } = body as { articleUrl: string }; + const urls = articleUrl.split('\n').filter(url => url.trim() !== ''); + + async function fetchArticle(url: string): Promise { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to fetch article: Status Code ${response.status}`); + } + return await response.text(); + } + + let articleText = ''; + for (const url of urls) { + try { + const articleHTML = await fetchArticle(url); + const dom = new JSDOM(articleHTML); + const jsContent = dom.window.document.querySelector("#js_content"); + const content = jsContent ? jsContent.textContent : ""; + articleText += content + '\n---\n'; + } catch (error) { + console.error(`Failed to process article from ${url}:`, error); + // Optionally, you might want to handle the error more gracefully, + // such as skipping the article or returning a default value. + } + } + + // return articleText; + const geminiResponse = await callGeminiAPI(articleText); + const today = new Date(); + const fs = require('fs'); + const path = require('path'); + const fileName = `history/${today.getFullYear()}/${today.getMonth() + 1}/${today.getDate()}.md`; + const dir = path.dirname(fileName); + + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + + fs.writeFileSync(fileName, geminiResponse); + return new Response(geminiResponse, { + headers: { + "Content-Type": "text/markdown; charset=utf-8", + }, + }); + } catch (error: any) { + console.error("Error:", error); + return { error: error.message }; + } + }) + .listen({ port: 3000 }); + +console.log( + `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}` +); diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..238655f --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..871be67 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "info_flow", + "module": "index.js", + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "type": "module", + "dependencies": { + "@elysiajs/html": "^1.2.0", + "@google/generative-ai": "^0.21.0", + "cheerio": "^1.0.0", + "dotenv": "^16.4.7", + "elysia": "^1.2.12", + "jsdom": "^26.0.0", + "openai": "^4.83.0" + } +} \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..749ab24 --- /dev/null +++ b/style.css @@ -0,0 +1,11 @@ +/* style.css */ +body { + max-width: 768px; + margin: 0 auto; + font-family: system-ui; + line-height: 1.6; +} +.timestamp { + color: #666; + font-size: 0.8em +} diff --git a/wechat.js b/wechat.js new file mode 100644 index 0000000..e1bd9ca --- /dev/null +++ b/wechat.js @@ -0,0 +1,16 @@ +import { JSDOM } from 'jsdom'; + +async function getWeChatArticleLinks(publicAccountName) { + const html = await response.text(); + + const { document } = new JSDOM(html).window; + const articleLinks = []; + const articleElements = document.querySelectorAll('.news-box .news-list li a'); + articleElements.forEach((element) => { + const link = element.href; + articleLinks.push(link); + }); + return articleLinks; +} + +export { getWeChatArticleLinks }; \ No newline at end of file