commit c38a898a3a1ca3d74a80d395a95610c95aa3766f Author: zlei9 Date: Sun Mar 29 13:19:31 2026 +0800 Initial commit with translated description diff --git a/README.md b/README.md new file mode 100644 index 0000000..bdf5919 --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +# Stock Watcher Skill + +A standardized stock watchlist management skill for Clawdbot that provides clean, consistent functionality for tracking Chinese A-share stocks. + +## Features + +- ✅ **Add stocks** to watchlist using 6-digit stock codes +- ✅ **View watchlist** with clear formatting +- ✅ **Remove individual stocks** from watchlist +- ✅ **Clear entire watchlist** with one command +- ✅ **Get performance summary** for all watched stocks +- ✅ **Standardized storage path** - no more path confusion! +- ✅ **Easy installation/uninstallation** + +## Installation + +For new users, the skill will be automatically installed when first used. The installation script creates: + +- Standardized watchlist directory: `~/.clawdbot/stock_watcher/` +- Watchlist file: `~/.clawdbot/stock_watcher/watchlist.txt` +- All necessary scripts in the skill directory + +## Usage Commands + +### Add a stock +```bash +cd ~/.clawdbot/skills/stock-watcher/scripts && python3 add_stock.py 600053 +``` + +### View watchlist +```bash +cd ~/.clawdbot/skills/stock-watcher/scripts && python3 list_stocks.py +``` + +### Remove a stock +```bash +cd ~/.clawdbot/skills/stock-watcher/scripts && python3 remove_stock.py 600053 +``` + +### Clear watchlist +```bash +cd ~/.clawdbot/skills/stock-watcher/scripts && python3 clear_watchlist.py +``` + +### Get performance summary +```bash +cd ~/.clawdbot/skills/stock-watcher/scripts && python3 summarize_performance.py +``` + +## Data Source + +- **Primary source**: 同花顺 (10jqka.com.cn) +- **Stock pages**: `https://stockpage.10jqka.com.cn/{stock_code}/` +- **Supported markets**: Shanghai A-shares, Shenzhen A-shares, STAR Market + +## File Structure + +``` +stock-watcher/ +├── SKILL.md # Skill metadata and instructions +├── scripts/ +│ ├── config.py # Centralized configuration +│ ├── add_stock.py # Add stock to watchlist +│ ├── list_stocks.py # List all stocks in watchlist +│ ├── remove_stock.py # Remove specific stock +│ ├── clear_watchlist.py # Clear entire watchlist +│ ├── summarize_performance.py # Get stock performance data +│ ├── install.sh # Installation script +│ └── uninstall.sh # Uninstallation script +└── references/ # (Reserved for future reference docs) +``` + +## Storage Location + +All user data is stored in a single, standardized location: +- **Directory**: `~/.clawdbot/stock_watcher/` +- **Watchlist file**: `~/.clawdbot/stock_watcher/watchlist.txt` + +Format: `stock_code|stock_name` (e.g., `600053|九鼎投资`) + +## Troubleshooting + +### "Command not found" errors +Ensure you have Python 3 and required packages installed: +```bash +pip3 install requests beautifulsoup4 +``` + +### Network issues +The skill fetches data from 10jqka.com.cn. Ensure you have internet access and the site is accessible. + +### Permission errors +Make sure the `~/.clawdbot/` directory is writable by your user. + +## Uninstallation + +To completely remove the skill and all data: +```bash +cd ~/.clawdbot/skills/stock-watcher/scripts && ./uninstall.sh +``` + +This will remove both the skill scripts and your watchlist data. \ No newline at end of file diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..8cba12a --- /dev/null +++ b/SKILL.md @@ -0,0 +1,88 @@ +--- +name: stock-watcher +description: "管理和监控个人股票观察列表。" +--- + +# Stock Watcher Skill + +This skill provides comprehensive stock watchlist management capabilities, allowing users to track their favorite stocks and get performance summaries using real-time data from 同花顺 (10jqka.com.cn). + +## 自选股行情查看 + +当你要求查看自选股行情时,系统会直接显示以下信息: +- 每只股票的代码和名称 +- 近期表现指标(涨跌幅等关键数据) +- 详细信息链接(可点击查看) + +无需额外命令,直接为你呈现简洁明了的行情概览。 + +## 管理自选股 + +### 添加股票 +使用股票代码(6位数字)添加到自选股: +- 例如:添加 600053 九鼎投资 + +### 删除股票 +通过股票代码删除自选股: +- 例如:删除 600053 + +### 查看自选股列表 +显示当前所有自选股的完整列表 + +### 清空自选股列表 +完全清空所有自选股 + +## 数据来源 + +主要使用**同花顺 (10jqka.com.cn)** 作为数据源: +- **股票页面**: `https://stockpage.10jqka.com.cn/{stock_code}/` +- 支持沪深A股及科创板市场 +- 提供实时行情、技术分析和资金流向数据 + +## 自选股管理 + +### 文件格式 +自选股存储在 `~/.clawdbot/stock_watcher/watchlist.txt`: +``` +600053|九鼎投资 +600018|上港集团 +688785|恒运昌 +``` + +### 支持操作 +1. **添加股票**: 验证股票代码格式并添加到自选股 +2. **删除股票**: 按股票代码精确匹配删除 +3. **查看列表**: 显示当前自选股 +4. **清空列表**: 完全清空自选股 +5. **行情总结**: 获取所有股票的最新数据并提供简洁摘要 + +## 行情摘要特点 + +- 直接显示关键行情指标,无冗余信息 +- 提供股票详情链接便于深入查看 +- 自动处理网络错误和数据异常 +- 合理控制请求频率(每秒1次) + +## 注意事项 + +- **股票代码格式**: 使用6位数字代码(如 `600053`) +- **数据延迟**: 行情可能有1-3分钟延迟 +- **网络依赖**: 需要网络连接获取实时数据 +- **市场范围**: 主要支持A股市场(沪市/深市/科创板) + +## 安装与卸载 + +### 安装 +运行 `scripts/install.sh` 脚本自动创建必要的目录结构。 + +### 卸载 +运行 `scripts/uninstall.sh` 脚本完全移除所有相关文件。 + +## 脚本说明 + +所有脚本都使用统一的配置文件 `config.py` 来管理存储路径,确保路径一致性: +- `add_stock.py` - 添加股票到自选股 +- `remove_stock.py` - 从自选股删除股票 +- `list_stocks.py` - 列出所有自选股 +- `clear_watchlist.py` - 清空自选股列表 +- `summarize_performance.py` - 获取股票行情摘要 \ No newline at end of file diff --git a/_meta.json b/_meta.json new file mode 100644 index 0000000..232d968 --- /dev/null +++ b/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn7dkx3sey4sf5s5336q2axad580mwhy", + "slug": "stock-watcher", + "version": "1.0.0", + "publishedAt": 1770348343954 +} \ No newline at end of file diff --git a/scripts/add_stock.py b/scripts/add_stock.py new file mode 100644 index 0000000..4f73043 --- /dev/null +++ b/scripts/add_stock.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +""" +Add stock to watchlist +Usage: python3 add_stock.py [stock_name] +""" +import sys +import os +import requests +from bs4 import BeautifulSoup +from config import WATCHLIST_FILE + +def get_stock_name_from_code(stock_code): + """Get stock name from 10jqka.com.cn using stock code""" + try: + url = f"https://stockpage.10jqka.com.cn/{stock_code}/" + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' + } + response = requests.get(url, headers=headers, timeout=10) + response.encoding = 'utf-8' + + if response.status_code == 200: + soup = BeautifulSoup(response.text, 'html.parser') + title = soup.find('title') + if title: + title_text = title.get_text() + if '(' in title_text and ')' in title_text: + stock_name = title_text.split('(')[0].strip() + return stock_name + except Exception as e: + pass + return None + +def add_stock(stock_code, stock_name=None): + """Add stock to watchlist.txt in the correct location""" + # Ensure the directory exists + os.makedirs(os.path.dirname(WATCHLIST_FILE), exist_ok=True) + + # Get stock name if not provided + if not stock_name: + stock_name = get_stock_name_from_code(stock_code) + if not stock_name: + stock_name = stock_code # fallback to code if name cannot be fetched + + # Read existing watchlist + existing_stocks = [] + if os.path.exists(WATCHLIST_FILE): + with open(WATCHLIST_FILE, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line: + existing_stocks.append(line) + + # Check if stock already exists + stock_entry = f"{stock_code}|{stock_name}" + stock_exists = False + for existing in existing_stocks: + if existing.startswith(f"{stock_code}|"): + stock_exists = True + break + + if stock_exists: + print(f"Stock {stock_code} already in watchlist") + return False + + # Add new stock + existing_stocks.append(stock_entry) + + # Write back to file with proper newlines + with open(WATCHLIST_FILE, 'w', encoding='utf-8') as f: + for stock in existing_stocks: + f.write(stock + '\n') + + print(f"Added stock {stock_code} ({stock_name}) to watchlist") + return True + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: python3 add_stock.py [stock_name]") + sys.exit(1) + + stock_code = sys.argv[1] + stock_name = sys.argv[2] if len(sys.argv) > 2 else None + add_stock(stock_code, stock_name) \ No newline at end of file diff --git a/scripts/clear_watchlist.py b/scripts/clear_watchlist.py new file mode 100644 index 0000000..48783fc --- /dev/null +++ b/scripts/clear_watchlist.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +""" +Clear the entire watchlist. +This script removes all stocks from the watchlist file. +""" +import os +import sys + +# Define the watchlist file path directly +WATCHLIST_FILE = os.path.expanduser("~/.clawdbot/stock_watcher/watchlist.txt") + +def clear_watchlist(): + """Clear the entire watchlist.""" + # Ensure the directory exists + os.makedirs(os.path.dirname(WATCHLIST_FILE), exist_ok=True) + + # Clear the file by opening in write mode and closing immediately + with open(WATCHLIST_FILE, 'w', encoding='utf-8') as f: + pass + + print("Watchlist cleared successfully.") + +if __name__ == "__main__": + clear_watchlist() \ No newline at end of file diff --git a/scripts/config.py b/scripts/config.py new file mode 100644 index 0000000..ed159e5 --- /dev/null +++ b/scripts/config.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +""" +Configuration for stock-watcher skill. +Centralized configuration to avoid path confusion. +""" +import os + +# Standardized watchlist file path +WATCHLIST_DIR = os.path.expanduser("~/.clawdbot/stock_watcher") +WATCHLIST_FILE = os.path.join(WATCHLIST_DIR, "watchlist.txt") + +# Ensure directory exists +os.makedirs(WATCHLIST_DIR, exist_ok=True) \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100644 index 0000000..8d6ffa5 --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Install stock-watcher skill dependencies and initialize watchlist directory + +set -e + +echo "Installing stock-watcher skill dependencies..." + +# Create the watchlist directory +mkdir -p ~/.clawdbot/stock_watcher + +# Create empty watchlist file if it doesn't exist +WATCHLIST_FILE="$HOME/.clawdbot/stock_watcher/watchlist.txt" +if [ ! -f "$WATCHLIST_FILE" ]; then + touch "$WATCHLIST_FILE" + echo "Created empty watchlist file: $WATCHLIST_FILE" +fi + +# Check if required Python packages are available +if ! python3 -c "import requests, bs4" 2>/dev/null; then + echo "Warning: Required Python packages (requests, beautifulsoup4) not found." + echo "You may need to install them with: pip install requests beautifulsoup4" +fi + +echo "Stock-watcher skill installed successfully!" +echo "Watchlist directory: ~/.clawdbot/stock_watcher/" +echo "Watchlist file: ~/.clawdbot/stock_watcher/watchlist.txt" \ No newline at end of file diff --git a/scripts/list_stocks.py b/scripts/list_stocks.py new file mode 100644 index 0000000..89881d2 --- /dev/null +++ b/scripts/list_stocks.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +""" +List all stocks in the user's watchlist. +This script reads from the standard watchlist file and displays the current watchlist. +""" +import sys +import os + +# Standardized watchlist file path +WATCHLIST_FILE = os.path.expanduser("~/.clawdbot/stock_watcher/watchlist.txt") + +def list_stocks(): + """List all stocks in the watchlist.""" + if not os.path.exists(WATCHLIST_FILE): + print("Watchlist is empty.") + return + + with open(WATCHLIST_FILE, 'r', encoding='utf-8') as f: + lines = [line.strip() for line in f if line.strip()] + + if not lines: + print("Watchlist is empty.") + return + + print("Your Stock Watchlist:") + print("-" * 40) + for i, line in enumerate(lines, 1): + parts = line.split('|') + if len(parts) == 2: + code, name = parts + print(f"{i}. {code} - {name}") + else: + print(f"{i}. {line}") + +if __name__ == "__main__": + list_stocks() \ No newline at end of file diff --git a/scripts/remove_stock.py b/scripts/remove_stock.py new file mode 100644 index 0000000..b72c11c --- /dev/null +++ b/scripts/remove_stock.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +""" +Remove stock from watchlist +Usage: python3 remove_stock.py +""" +import sys +import os + +# Standardized watchlist file path +WATCHLIST_DIR = os.path.expanduser("~/.clawdbot/stock_watcher") +WATCHLIST_FILE = os.path.join(WATCHLIST_DIR, "watchlist.txt") + +def remove_stock(stock_code): + """Remove stock from watchlist.""" + if not os.path.exists(WATCHLIST_FILE): + print("Watchlist is empty.") + return False + + # Read existing watchlist + existing_stocks = [] + with open(WATCHLIST_FILE, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line: + existing_stocks.append(line) + + # Find and remove the stock + stock_found = False + updated_stocks = [] + for stock in existing_stocks: + if stock.startswith(f"{stock_code}|"): + stock_found = True + else: + updated_stocks.append(stock) + + if not stock_found: + print(f"Stock {stock_code} not found in watchlist") + return False + + # Write back to file + with open(WATCHLIST_FILE, 'w', encoding='utf-8') as f: + for stock in updated_stocks: + f.write(stock + '\n') + + print(f"Removed stock {stock_code} from watchlist") + return True + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: python3 remove_stock.py ") + sys.exit(1) + + stock_code = sys.argv[1] + remove_stock(stock_code) \ No newline at end of file diff --git a/scripts/summarize_performance.py b/scripts/summarize_performance.py new file mode 100644 index 0000000..66d482f --- /dev/null +++ b/scripts/summarize_performance.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +""" +Summarize the performance of all stocks in the watchlist. +This script fetches current stock data from 10jqka.com.cn for each stock +in the watchlist and provides a summary of their recent performance. +""" +import os +import sys +import requests +from bs4 import BeautifulSoup +import time + +# Standardized watchlist file path +WATCHLIST_FILE = os.path.expanduser("~/.clawdbot/stock_watcher/watchlist.txt") + +def fetch_stock_data(stock_code): + """Fetch stock data from 10jqka.com.cn.""" + url = f"https://stockpage.10jqka.com.cn/{stock_code}/" + + try: + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' + } + response = requests.get(url, headers=headers, timeout=10) + response.encoding = 'utf-8' + + if response.status_code != 200: + return None + + soup = BeautifulSoup(response.text, 'html.parser') + + # Extract basic info + title = soup.find('title') + stock_name = "" + if title: + title_text = title.get_text() + if '(' in title_text and ')' in title_text: + stock_name = title_text.split('(')[0].strip() + + # Look for performance data + performance_data = {} + + # Try to find recent performance indicators + # This is a simplified version - in practice, you'd need more robust parsing + text_content = soup.get_text() + + # Look for key phrases + if '涨跌幅' in text_content: + # Extract percentage changes + import re + percentages = re.findall(r'[-+]?\d+\.?\d*%', text_content) + if percentages: + performance_data['recent_changes'] = percentages[:3] # Get first 3 percentages + + return { + 'code': stock_code, + 'name': stock_name, + 'url': url, + 'performance': performance_data + } + + except Exception as e: + print(f"Error fetching data for {stock_code}: {e}", file=sys.stderr) + return None + +def summarize_performance(): + """Summarize performance of all stocks in watchlist.""" + if not os.path.exists(WATCHLIST_FILE): + return + + with open(WATCHLIST_FILE, 'r', encoding='utf-8') as f: + lines = f.readlines() + + if not lines or all(not line.strip() for line in lines): + return + + # Directly output performance summary without any command prompts + for line in lines: + line = line.strip() + if line: + parts = line.split('|') + if len(parts) == 2: + code, name = parts + + # Fetch data + stock_data = fetch_stock_data(code) + if stock_data: + if stock_data['performance']: + for i, change in enumerate(stock_data['performance'].get('recent_changes', []), 1): + print(f"{code} - {name} - 指标{i}: {change}") + else: + print(f"{code} - {name} - 行情数据暂不可用") + else: + print(f"{code} - {name} - 获取数据失败") + + # Be respectful to the server + time.sleep(1) + +if __name__ == "__main__": + summarize_performance() \ No newline at end of file diff --git a/scripts/uninstall.sh b/scripts/uninstall.sh new file mode 100644 index 0000000..9b37f0f --- /dev/null +++ b/scripts/uninstall.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# Uninstall stock-watcher skill + +set -e + +# Remove watchlist directory and files +WATCHLIST_DIR="$HOME/.clawdbot/stock_watcher" +if [ -d "$WATCHLIST_DIR" ]; then + rm -rf "$WATCHLIST_DIR" + echo "Removed watchlist directory: $WATCHLIST_DIR" +fi + +echo "Stock watcher skill uninstalled successfully." \ No newline at end of file