ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于OpenClaw与Ollama的AI选股系统:10分钟构建自动化量化分析工具

基于OpenClaw与Ollama的AI选股系统:10分钟构建自动化量化分析工具 1. 项目概述为什么我们需要一个AI选股系统在信息爆炸的今天个人投资者每天面对的是海量的财经新闻、公司财报、技术指标和社交媒体情绪。手动筛选和分析这些数据不仅耗时耗力还极易受到情绪和认知偏差的影响。你是否有过这样的经历看到某只股票大涨后追悔莫及或者因为错过一个关键信息而做出错误决策这正是传统人工选股的痛点所在。“10分钟打造你的AI选股系统”这个项目正是为了解决这个核心痛点。它不是一个复杂的量化交易策略而是一个轻量级、自动化、基于规则的“潜力股侦察兵”。其核心价值在于利用OpenClaw这个新兴的AI Agent框架结合实时行情数据构建一个能够每日自动运行、执行预设筛选逻辑并最终将结果推送给你的自动化流程。整个过程从环境搭建到收到第一份股票清单目标是在10分钟内完成初始化。之后系统便会像一个不知疲倦的助手在每天收盘后或你设定的任何时间自动工作为你从茫茫股海中初步筛选出值得进一步关注的5支标的。这个系统适合谁它非常适合有一定编程基础、对金融市场感兴趣、希望将重复性分析工作自动化并想亲身实践AI Agent落地的个人开发者或量化爱好者。你不需要是金融专家或AI科学家只需要跟着步骤操作就能拥有一个属于你自己的、7x24小时待命的初级分析工具。接下来我将带你一步步拆解这个系统的每一个环节从工具选型到核心逻辑再到避坑指南让你不仅能复现更能理解其背后的“所以然”。2. 核心工具与框架选型解析构建这个系统的基石是选择合适的工具。我们的目标是快速、稳定、可扩展同时兼顾学习成本和部署难度。经过对当前技术生态的评估我选择了以下核心组件并解释为什么是它们。2.1 为什么选择OpenClaw作为AI Agent框架在众多AI Agent框架如LangChain、AutoGen、CrewAI中我最终选择了OpenClaw主要是基于以下几点实战考量第一开发语言亲和力。OpenClaw是基于C#开发的。对于广大使用Windows环境、熟悉.NET生态的开发者来说这是一个巨大的优势。你不需要额外配置复杂的Python环境虽然它也支持在Visual Studio或VS Code里就能获得一流的开发体验和调试支持。这大大降低了入门门槛。第二设计理念清晰。OpenClaw强调“技能Skill”和“操作Operation”的模块化。在我们的选股场景中“获取股票列表”、“计算技术指标”、“评估基本面”、“生成报告”都可以被设计成独立的Skill。这种设计让系统的逻辑非常清晰易于维护和扩展。比如未来你想增加“舆情分析”功能只需要开发一个新的Skill并注入到工作流中即可不会影响原有逻辑。第三对大模型的良好支持。OpenClaw可以灵活配置后端大模型。无论是通过API调用云端模型如OpenAI GPT-4、DeepSeek还是本地部署的Ollama运行Llama 3、Qwen等开源模型都能轻松接入。这给了我们成本控制和数据隐私上的灵活性。对于选股这种对实时性要求高、可能需要频繁调用模型的任务使用本地Ollama轻量化模型是性价比极高的方案。第四社区与热度。从提供的热搜词可以看出OpenClaw近期关注度很高围绕其安装、部署、技能开发的教程和讨论正在快速增长。选择一个处于上升期的框架意味着你能更快地找到解决方案和灵感踩坑时也更容易获得帮助。注意网络热词中提到了“openclaw llamap svr operator(): got exception: { “error“: { “code“: 400” 这类错误。这通常是配置不当特别是Ollama服务地址或模型名称错误导致的。在后续配置环节我们会重点规避。2.2 数据源实时行情API的选择与考量AI选股数据是燃料。我们需要稳定、准确、及时的股票数据。这里有几个主流选择免费公开API如AKShare、Yahoo Finance优点是免费适合学习和轻度使用。缺点是稳定性无法保证雅虎API经常变动数据可能延迟且国内访问可能不畅。AKShare是一个优秀的国内开源库数据源丰富但需要一定的Python知识来搭建一个简单的数据服务接口供OpenClaw调用。专业金融数据服务商如Tushare、Baostock、JoinQuant这类数据源通常提供更稳定、更全面的数据包括历史行情、财务数据、板块信息等。Tushare和Baostock有免费的基础接口但高级功能需要积分或付费。对于严肃的选股系统投资一个可靠的数据源是值得的。券商API部分券商为量化交易提供API数据直接、实时但通常需要开户并有资金门槛且绑定特定交易终端灵活性较差。我的建议与选择为了平衡快速启动和系统可靠性本项目采用“AKShare 备用数据源”的策略。我们将用AKShare作为主要数据获取工具因为它免费、开源、支持A股全市场数据且社区活跃。同时我们会设计一个简单的数据访问层Data Access Layer这样未来如果需要切换到Tushare或其他付费API只需修改这个层的实现而不会影响上层的选股逻辑。这是系统可扩展性的一个关键设计。2.3 自动化调度让系统自己“醒来”工作一个不能自动运行的系统价值减半。我们需要一个调度器在每天下午收盘后例如15:30自动触发整个选股流程。Windows系统可以使用系统自带的任务计划程序Task Scheduler。我们可以创建一个任务定时执行一个批处理.bat文件或PowerShell脚本这个脚本负责启动我们的OpenClaw选股程序。Linux/macOS系统首选Cron。这是类Unix系统上最经典、最强大的定时任务工具。一行Cron表达式就能搞定每日定时执行。跨平台方案推荐使用Docker容器来封装整个应用然后在任何系统上使用Docker的调度工具或结合系统级Cron/任务计划来定时启动容器。这是最干净、最一致的部署方式避免了“在我机器上好好的”这类环境问题。这也是为什么“docker部署openclaw”成为热词的原因。在本指南中我将以Docker CronLinux为例作为最终部署方案因为它能确保环境一致性并且部署步骤清晰。对于Windows用户我会额外说明如何使用任务计划程序达到相同效果。3. 系统架构与核心工作流设计在动手写代码之前我们必须理清系统的骨架。一个好的架构能让开发事半功倍也便于后续迭代。我们的AI选股系统核心工作流可以分为四个阶段如下图所示概念图[定时触发器] - [数据获取与预处理] - [AI智能筛选与评分] - [结果生成与通知]3.1 第一阶段定时触发与任务初始化每天下午3点30分A股收盘后Cron服务或Windows任务计划被触发。它执行一个简单的Shell脚本或直接命令。这个命令的核心是启动我们的Docker容器或者直接运行编译好的OpenClaw应用程序。关键设计点我们需要确保每次任务都是“无状态”的。即每次运行都从干净的数据开始避免上次运行的结果影响本次判断。这可以通过在程序开始时清理临时数据、从API重新拉取最新数据来实现。OpenClaw的Agent可以设计成每次启动都重新加载所有Skill和上下文。3.2 第二阶段数据获取与预处理这是整个系统的基石。Agent被触发后首先调用“数据获取Skill”。这个Skill会执行以下操作获取全市场股票列表通过AKShare接口获取当前沪深两市所有上市公司的基本列表包括股票代码、名称、所属板块等。筛选基础池根据一些硬性规则进行初筛例如剔除ST、*ST股票高风险警示。剔除上市不足N天例如60天的次新股数据不稳定。剔除当前停牌的股票。可选剔除某些特定板块或股价过低如低于1元的股票。 这一步的目的是将几千支股票缩小到一个几百支的“基础股票池”减少后续计算量。获取行情与指标数据对基础股票池中的每一支股票并行或批量获取其近期例如最近60个交易日的日K线数据。然后利用这些数据计算出一系列技术指标例如趋势类MA移动平均线如5日、10日、20日、MACD。动量类RSI相对强弱指数、KDJ。波动类Bollinger Bands布林带。 这些计算可以在数据获取Skill中完成也可以拆分成独立的“指标计算Skill”。实操心得批量获取数据时一定要注意API的频率限制。AKShare虽然免费但过于频繁的请求可能导致IP被临时屏蔽。建议在代码中加入适当的延时例如time.sleep(0.5)。更好的做法是如果数据量允许可以一次性获取全市场数据再在内存中处理这比逐支股票调用API高效得多。3.3 第三阶段AI智能筛选与评分这是OpenClaw大显身手的环节。我们将设计一个“选股策略Skill”它接收预处理后的股票数据DataFrame或对象列表并应用我们的核心筛选逻辑。重要认知这里的“AI”并非指一个黑箱模型凭空生成股票代码而是用大模型的语言理解能力来执行我们预先定义好的、可解释的量化筛选规则并可以对结果进行简单的自然语言总结。这是一种“规则引擎AI润色”的模式兼顾了确定性和智能性。我们的筛选逻辑可以分层级量化规则层硬性过滤这是一系列明确的、可编程的条件。例如条件A收盘价站上20日均线且20日均线向上。条件BRSI(6) 大于50但小于70表明处于强势但不过热。条件C成交量大于5日均量线的1.2倍放量。条件D市值在50亿到500亿之间中盘股。 程序会遍历基础股票池选出同时满足所有或满足其中若干组合条件的股票形成一个“候选清单”。AI评分与排序层柔性评估将“候选清单”连同每支股票的关键指标价格、涨跌幅、所属板块、市盈率等一起构造一段Prompt提交给OpenClaw配置的大模型如Llama 3。Prompt可以这样设计“你是一个专业的股票分析师。请根据以下股票列表及其关键数据综合考虑技术面强度、基本面健康度以小市值、低市盈率为佳和近期市场热度从中选出你认为未来一周最具上涨潜力的5支股票。请严格按照JSON格式输出包含股票代码、名称和简要的推荐理由。” 模型会根据其“知识”和上下文理解对候选股票进行排序和筛选最终输出5支股票。为什么这样做纯量化规则可能选出几十支股票我们还需要最后一道“人工智能”的关口来压缩到5支并给出一个像样的理由。这模拟了专业分析师在初步筛选后做最终决策的过程。3.4 第四阶段结果生成与推送“选股策略Skill”输出结果后由“通知推送Skill”接手。它将AI输出的结构化数据JSON格式化成易读的消息。消息模板“【AI选股日报】YYYY-MM-DD\n今日为您筛选的5支潜力股如下\n1. [代码][名称]推荐理由...\n2...”推送渠道根据热搜词我们可以接入飞书或微信。飞书提供了开放的机器人Webhook接口非常简单。微信推送相对复杂通常需要借助企业微信机器人或ServerChan等第三方服务。我强烈建议从飞书机器人开始配置简单成功率高。最终动作推送完成后Agent记录本次任务日志然后正常退出。Docker容器停止等待下一次被Cron唤醒。4. 详细实现步骤与代码剖析理论讲完我们进入实战环节。请跟随以下步骤一步步搭建你的系统。我将以在Ubuntu服务器上使用Docker部署为例同时兼顾本地开发调试的场景。4.1 第一步基础环境准备与OpenClaw部署首先我们需要一个运行环境。使用Docker可以最大程度避免环境冲突。1. 安装Docker与Docker Compose如果你的系统没有安装请参考Docker官方文档。在Ubuntu上通常几条命令就能搞定。2. 获取OpenClaw镜像与配置OpenClaw的Docker镜像可能不在官方仓库我们需要从其项目地址获取。根据网络热词我们需要关注配置细节。# 假设我们从某个Registry拉取镜像这里用示例名 # docker pull some-registry/openclaw:latest # 更常见的做法是克隆源码使用提供的Dockerfile自行构建 git clone OpenClaw的Git仓库地址 cd openclaw3. 关键配置连接大模型Ollama这是最容易出错的一步。我们需要配置OpenClaw使用本地运行的Ollama服务。启动Ollama服务确保Ollama已在后台运行并下载了所需模型如llama3.1:8b。ollama run llama3.1:8b # 第一次会自动拉取模型 # 服务默认运行在 http://localhost:11434配置OpenClaw在OpenClaw的项目目录中找到配置文件通常是appsettings.json或config.json。你需要修改大模型连接设置。{ OpenClaw: { ModelProvider: Ollama, // 指定使用Ollama Ollama: { BaseUrl: http://host.docker.internal:11434, // 关键从容器内访问宿主机服务 DefaultModel: llama3.1:8b // 你下载的模型名 } // ... 其他配置 } }致命坑点详解很多人在Docker中部署时会遇到openclaw llamap svr operator(): got exception: 400错误。这几乎都是因为BaseUrl配置不对。在Docker容器内部localhost指向容器自己而不是宿主机。因此不能配http://localhost:11434。正确做法是在Linux/macOS的Docker Desktop中使用http://host.docker.internal:11434。在原生Linux Docker环境中可能需要使用宿主机的真实IP如http://172.17.0.1:11434或者创建自定义网络。最稳妥的方式是在docker-compose.yml中将Ollama和OpenClaw放在同一个自定义网络内然后通过服务名访问。4. 编写Dockerfile与docker-compose.yml为了管理方便我们使用Docker Compose来定义Ollama和OpenClaw两个服务。docker-compose.yml示例version: 3.8 services: ollama: image: ollama/ollama:latest container_name: ollama ports: - 11434:11434 volumes: - ollama_data:/root/.ollama restart: unless-stopped openclaw-stock: build: . container_name: openclaw-stock depends_on: - ollama environment: - ASPNETCORE_ENVIRONMENTProduction # 将本地项目目录挂载到容器方便开发调试 volumes: - ./:/app - ./data:/app/data # 用于持久化数据或配置 working_dir: /app command: [dotnet, run, --project, YourOpenClawProject.csproj] restart: no # 我们由Cron控制启动所以不自动重启 volumes: ollama_data:Dockerfile位于OpenClaw项目根目录FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY . . RUN dotnet publish YourOpenClawProject.csproj -c Release -o /app/publish FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final WORKDIR /app COPY --frombuild /app/publish . ENTRYPOINT [dotnet, YourOpenClawProject.dll]4.2 第二步开发选股核心Skills现在我们在OpenClaw项目中创建我们的核心Skill。假设项目结构如下OpenClawStock/ ├── Skills/ │ ├── DataFetchSkill.cs │ ├── StockFilterSkill.cs │ └── NotificationSkill.cs ├── Services/ │ └── MarketDataService.cs (封装AKShare调用) ├── appsettings.json └── Program.cs1. DataFetchSkill数据获取技能这个Skill负责与外界数据源交互。它内部会调用一个MarketDataService这个服务封装了所有对AKShare的调用逻辑。// Skills/DataFetchSkill.cs using OpenClaw.Core.Skills; using System.Threading.Tasks; namespace OpenClawStock.Skills { [Skill(Name DataFetch, Description 获取A股市场数据并进行初步清洗)] public class DataFetchSkill { private readonly IMarketDataService _dataService; public DataFetchSkill(IMarketDataService dataService) { _dataService dataService; } [SkillOperation] public async TaskStockDataSet ExecuteAsync() { // 1. 获取全市场股票列表 var allStocks await _dataService.GetAllStockListAsync(); // 2. 应用硬性规则初筛 var basicPool allStocks .Where(s !s.Name.Contains(ST)) // 去ST .Where(s s.ListingDays 60) // 上市超60天 .Where(s s.MarketCap 5_0000_0000) // 市值大于5亿 .ToList(); // 3. 批量获取这些股票的日K线数据 var symbols basicPool.Select(s s.Symbol).ToList(); var historyData await _dataService.GetBatchDailyHistoryAsync(symbols, 60); // 最近60天 // 4. 计算技术指标 (这里可以调用专门的指标计算库如Ta-Lib的.NET绑定) foreach (var data in historyData) { data.Indicators.MA5 CalculateMA(data.ClosePrices, 5); data.Indicators.MA20 CalculateMA(data.ClosePrices, 20); data.Indicators.RSI6 CalculateRSI(data.ClosePrices, 6); // ... 计算其他指标 } // 返回一个包含基础池和行情数据的数据集 return new StockDataSet { BasicPool basicPool, HistoryData historyData }; } private double CalculateMA(Listdouble prices, int period) { /* 实现略 */ } private double CalculateRSI(Listdouble prices, int period) { /* 实现略 */ } } }2. StockFilterSkill股票筛选技能这是大脑它依赖DataFetchSkill获取数据然后应用规则并调用大模型。// Skills/StockFilterSkill.cs using OpenClaw.Core.Chat; using OpenClaw.Core.Skills; using System.Linq; using System.Text.Json; using System.Threading.Tasks; namespace OpenClawStock.Skills { [Skill(Name StockFilter, Description 应用量化规则和AI模型筛选潜力股)] public class StockFilterSkill { private readonly IChatClient _chatClient; // OpenClaw注入的聊天客户端用于调用大模型 private readonly DataFetchSkill _dataFetchSkill; public StockFilterSkill(IChatClient chatClient, DataFetchSkill dataFetchSkill) { _chatClient chatClient; _dataFetchSkill dataFetchSkill; } [SkillOperation] public async TaskListSelectedStock ExecuteAsync() { // 1. 获取数据 var dataSet await _dataFetchSkill.ExecuteAsync(); // 2. 应用量化规则进行硬筛选 var candidates new ListStockWithIndicator(); foreach (var stockData in dataSet.HistoryData) { var last stockData.DailyBars.Last(); var indicators stockData.Indicators; // 示例规则价格上穿20日线且20日线趋势向上RSI健康放量 bool rule1 last.Close indicators.MA20 indicators.MA20 indicators.MA20_PreviousDay; bool rule2 indicators.RSI6 50 indicators.RSI6 75; bool rule3 last.Volume indicators.VolumeMA5 * 1.2; if (rule1 rule2 rule3) { candidates.Add(new StockWithIndicator { Stock stockData.Stock, Indicators indicators, LatestBar last }); } } if (candidates.Count 0) return new ListSelectedStock(); // 3. 如果候选太多10先按某些规则排序截断减少token消耗 var topCandidates candidates .OrderByDescending(c c.LatestBar.ChangePercent) // 按当日涨幅排序 .Take(15) .ToList(); // 4. 构造Prompt调用大模型做最终5选 var prompt BuildPrompt(topCandidates); var modelResponse await _chatClient.GetChatCompletionAsync(prompt); // 5. 解析模型的JSON输出 var selectedStocks ParseModelResponse(modelResponse); return selectedStocks.Take(5).ToList(); // 确保只返回5支 } private string BuildPrompt(ListStockWithIndicator candidates) { var candidateInfo candidates.Select(c $- 代码{c.Stock.Symbol}名称{c.Stock.Name}最新价{c.LatestBar.Close}涨跌幅{c.LatestBar.ChangePercent:F2}%所属板块{c.Stock.Industry}市盈率(PE){c.Stock.PE:F1}).ToList(); string infoString string.Join(\n, candidateInfo); return $你是一个专业的A股投资顾问。请从以下股票列表中综合考虑技术面表现趋势、动量、基本面健康度优先选择市盈率较低、市值适中的以及所属板块的近期热度筛选出5支你认为在未来一周5个交易日内最具上涨潜力的股票。 请严格按照以下JSON格式输出不要有任何额外的解释或标记 {{ selected_stocks: [ {{ symbol: 股票代码, name: 股票名称, reason: 不超过20字的简要推荐理由 }}, ... ] }} 候选股票列表 {infoString}; } private ListSelectedStock ParseModelResponse(string response) { // 使用System.Text.Json解析响应 try { var jsonDoc JsonDocument.Parse(response); var stocks new ListSelectedStock(); // ... 解析逻辑 return stocks; } catch { // 如果模型没有返回标准JSON可以启用一个备用规则例如按涨幅前5名 return new ListSelectedStock(); } } } }4.3 第三步组装Agent与配置工作流在OpenClaw中我们需要在Program.cs或启动配置中注册这些Skill并定义它们的工作流Orchestration。// Program.cs 或 Startup.cs 的简化示例 using OpenClaw.Core.DependencyInjection; using OpenClawStock.Skills; var builder WebApplication.CreateBuilder(args); // 1. 添加OpenClaw核心服务 builder.Services.AddOpenClaw(config { config.ModelProvider ModelProvider.Ollama; config.OllamaBaseUrl builder.Configuration[OpenClaw:Ollama:BaseUrl]; config.DefaultModel builder.Configuration[OpenClaw:Ollama:DefaultModel]; }); // 2. 注册我们自定义的服务和Skill builder.Services.AddSingletonIMarketDataService, AkShareMarketDataService(); builder.Services.AddSkillDataFetchSkill(); builder.Services.AddSkillStockFilterSkill(); builder.Services.AddSkillNotificationSkill(); // 3. 定义一个简单的顺序工作流 builder.Services.AddHostedServiceStockSelectionWorkflow(); var app builder.Build(); app.Run(); // 工作流服务 public class StockSelectionWorkflow : BackgroundService { private readonly StockFilterSkill _filterSkill; private readonly NotificationSkill _notificationSkill; public StockSelectionWorkflow(StockFilterSkill filterSkill, NotificationSkill notificationSkill) { _filterSkill filterSkill; _notificationSkill notificationSkill; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // 这个服务会在应用启动时运行。对于定时任务我们更希望它被外部触发一次。 // 因此我们可以把主要逻辑放在一个可调用的方法里并由Cron启动的进程调用。 // 这里为了示例我们假设是手动触发或一次性任务。 await RunDailySelectionAsync(); } public async Task RunDailySelectionAsync() { Console.WriteLine($[{DateTime.Now}] 开始执行每日选股任务...); try { var selectedStocks await _filterSkill.ExecuteAsync(); await _notificationSkill.ExecuteAsync(selectedStocks); Console.WriteLine($[{DateTime.Now}] 每日选股任务完成。); } catch (Exception ex) { Console.WriteLine($[{DateTime.Now}] 任务执行失败: {ex.Message}); // 这里可以添加失败通知 } } }为了让Cron能调用我们需要一个简单的入口点。可以在项目中创建一个控制台应用项目或者直接暴露一个HTTP API端点来触发RunDailySelectionAsync方法。更简单的方式是将上述工作流编译成控制台程序由Cron直接执行。4.4 第四步配置自动化调度与通知1. 创建执行脚本在项目根目录创建run_selection.shLinux或run_selection.batWindows。#!/bin/bash # run_selection.sh cd /path/to/your/openclaw-stock-docker-compose-directory # 启动服务执行任务然后关闭。使用docker-compose run可以运行一次性命令。 docker-compose run --rm openclaw-stock dotnet /app/YourOpenClawProject.dll --task select假设我们的程序支持一个命令行参数--task select来触发选股工作流。2. 配置Cron定时任务Linux使用crontab -e编辑当前用户的Cron任务。# 每天下午15点35分收盘后5分钟执行选股任务 35 15 * * 1-5 /bin/bash /path/to/your/run_selection.sh /path/to/your/stock_selection.log 211-5表示周一到周五。 ...log 21将标准输出和错误都重定向到日志文件便于排查。3. 配置飞书机器人通知在NotificationSkill中实现飞书Webhook调用。首先在飞书群里添加一个“群机器人”获取它的Webhook URL。然后在Skill中发送HTTP POST请求。// Skills/NotificationSkill.cs using System.Net.Http.Json; using System.Threading.Tasks; public class NotificationSkill { private readonly string _feishuWebhookUrl; private readonly HttpClient _httpClient; public NotificationSkill(IConfiguration config, HttpClient httpClient) { _feishuWebhookUrl config[Feishu:WebhookUrl]; _httpClient httpClient; } [SkillOperation] public async Task ExecuteAsync(ListSelectedStock stocks) { if (stocks null || !stocks.Any()) { await SendMessage(【AI选股日报】今日未筛选出符合条件的潜力股。); return; } var message new { msg_type text, content new { text $【AI选股日报】{DateTime.Now:yyyy-MM-dd}\n string.Join(\n, stocks.Select((s, i) ${i 1}. {s.Symbol} {s.Name}{s.Reason})) } }; var response await _httpClient.PostAsJsonAsync(_feishuWebhookUrl, message); response.EnsureSuccessStatusCode(); } }5. 部署、调试与常见问题排查将代码部署到服务器并让整个流程自动运转起来可能会遇到各种问题。以下是实战中总结的关键步骤和避坑指南。5.1 完整部署清单服务器准备一台有公网IP的Linux服务器如Ubuntu 22.04安装好Docker和Docker Compose。代码上传将你的OpenClawStock项目文件上传到服务器例如/opt/openclaw-stock。环境变量配置在服务器上创建.env文件或直接修改docker-compose.yml填入正确的Ollama BaseUrl在服务器上容器间通信通常用服务名http://ollama:11434。构建与测试cd /opt/openclaw-stock docker-compose build docker-compose up -d ollama # 先启动Ollama # 等待Ollama启动并拉取模型 docker-compose run --rm openclaw-stock dotnet run --task select观察日志看是否成功运行并收到飞书消息。配置Cron编辑crontab -e添加定时任务指向你的run_selection.sh脚本。记得给脚本添加执行权限(chmod x run_selection.sh)。日志监控定期检查stock_selection.log文件确保任务正常运行。5.2 高频问题与解决方案速查表问题现象可能原因排查步骤与解决方案运行报错openclaw llamap svr operator(): got exception: 4001. Ollama服务未启动。2.BaseUrl配置错误容器无法访问Ollama。3. 指定的DefaultModel不存在。1.docker ps检查Ollama容器是否运行。2. 进入OpenClaw容器内部(docker exec -it openclaw-stock bash)尝试curl http://ollama:11434/api/tags看能否连通。3. 在Ollama容器内执行ollama list确认模型名。程序运行后无任何输出或立即退出1. 程序本身有未处理的异常导致崩溃。2. Cron环境变量与交互式Shell不同。1. 在run_selection.sh脚本中增加set -x开启调试或直接手动执行脚本看详细错误。2. 在Cron命令中指定完整的路径或在脚本开头设置必要的环境变量如PATH。飞书/微信消息未收到1. Webhook URL错误或已失效。2. 网络问题服务器无法访问外网。3. 消息内容格式不符合机器人要求。1. 重新在飞书群添加机器人获取新URL。2. 在服务器上curl -X POST webhook_url测试连通性。3. 查阅飞书机器人文档确保JSON格式正确特别是msg_type和content结构。AKShare获取数据失败或很慢1. 数据源网站访问不稳定或已更新。2. 请求频率过高被限制。1. 检查AKShare库版本更新到最新。查看其GitHub Issues看是否有类似问题。2. 在代码中增加请求间隔(Task.Delay)。考虑使用本地缓存避免重复获取同一数据。模型返回的内容不是JSON格式1. Prompt指令不够清晰。2. 模型能力不足或“不听话”。1. 强化Prompt使用“严格按JSON输出”、“不要有任何额外文本”等指令。在Prompt中给出更精确的JSON示例。2. 尝试换用更强大的模型如llama3.1:70b。或者在代码中增加后处理使用正则表达式从模型输出中提取JSON部分。选出的股票总是那几支或结果不合理1. 量化筛选规则过于宽松或严格。2. 模型Prompt引导性不强。3. 数据预处理有问题如复权处理。1. 回测你的筛选规则。调整均线周期、RSI阈值等参数。可以引入更多维度如换手率、资金流向等。2. 优化Prompt明确告诉模型你青睐的股票类型如“中小盘成长股”、“估值修复型”。3. 确保使用的股价数据是前复权数据以保证技术指标计算的连续性。5.3 性能优化与扩展建议当系统稳定运行后你可以考虑以下优化和扩展方向引入缓存股票的基本信息、板块分类等变化不频繁的数据可以缓存到本地数据库如SQLite或文件中避免每次任务都从API拉取大幅提升速度。并行处理获取多支股票的历史数据和计算指标是CPU密集型任务可以使用C#的Parallel.ForEach或Task.WhenAll进行并行处理充分利用多核性能。策略回测框架将筛选规则抽象成可配置的策略并实现一个简单的回测引擎。这样你就可以用历史数据验证不同规则组合的有效性而不仅仅是凭感觉调整参数。多因子评分系统替代简单的规则过滤为每支股票在技术、基本面、资金、舆情等多个维度打分加权求和得到总分再选择排名靠前的股票。这能让筛选逻辑更精细。接入更多数据源除了行情可以接入财经新闻、社交媒体情绪分析通过大模型总结、龙虎榜数据等让AI的决策依据更全面。实现简单的监控告警除了每日推送还可以监控任务是否成功执行。如果Cron任务失败通过检查日志或进程状态可以发送一条告警消息到你的手机。这个“10分钟打造”的系统是一个强大的起点而非终点。它为你打开了一扇门让你能够将想法快速转化为一个自动运行的智能体。最重要的是你通过亲手搭建彻底理解了从数据获取、策略设计、AI调用到任务调度的完整链条。接下来你可以根据自己的投资理念不断迭代和优化其中的每一个模块让它真正成为你投资路上的得力助手。记住所有工具和代码都是为你服务的核心永远是你对市场的独立思考和判断。
返回列表