Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ DEEPSEEK_API_KEY=your_actual_deepseek_api_key_here
# DeepSeek API基础URL(可选,使用默认值即可)
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1

# DeepSeek 模型名称,为空时取默认值 deepseek-chat
DEEPSEEK_MODEL_NAME=deepseek-chat

# ========== Tushare数据接口(可选)==========
# Tushare Token(可选,用于获取更多金融数据)
Expand Down
20 changes: 19 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,22 @@
.env
/.cursor
/openspec
TradEnv/
TradEnv/
/.idea/inspectionProfiles/profiles_settings.xml
/.idea/inspectionProfiles/Project_Default.xml
/.idea/.gitignore
/.idea/aiagents-stock.iml
/.idea/misc.xml
/.idea/modules.xml
/.idea/vcs.xml
/data/longhubang.db
/data/low_price_bull_monitor.db
/data/main_force_batch.db
/data/portfolio_stocks.db
/data/profit_growth_monitor.db
/data/sector_strategy.db
/data/smart_monitor.db
/data/stock_analysis.db
/data/stock_monitor.db
/migrate_databases.sh
/migrate_databases_by_size.sh
258 changes: 258 additions & 0 deletions AI模型选择说明.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
# AI模型选择机制说明

## 📋 问题回答

### 1. 左侧的AI模型选择会全局默认生效吗?

**答案:部分生效,但不完全全局**

**当前状态**:
- ✅ 模型选择器会保存到 `st.session_state.selected_model`
- ❌ 但很多功能模块**强制使用** `config.DEEPSEEK_MODEL_NAME`(从 `.env` 文件读取),**忽略**了 `session_state` 中的选择
- ✅ 只有部分页面(如"主力选股")会使用页面内的模型选择

**具体表现**:
- **股票分析页面**:强制使用 `config.DEEPSEEK_MODEL_NAME`,忽略侧边栏选择
- **批量分析功能**:强制使用 `config.DEEPSEEK_MODEL_NAME`,忽略侧边栏选择
- **主力选股页面**:使用页面内的模型选择(不是侧边栏的)
- **智策板块页面**:强制使用 `config.DEEPSEEK_MODEL_NAME`

### 2. 如果选择其他模型,模型信息在哪里配置?

**答案:两个地方**

#### 位置1:模型选项列表 - `model_config.py`

**文件路径**:`model_config.py`

**作用**:定义所有可用的AI模型选项

**内容示例**:
```python
model_options = {
"deepseek-chat": "DeepSeek Chat (默认)",
"deepseek-reasoner": "DeepSeek Reasoner (推理增强)",
"qwen-plus": "qwen-plus (阿里百炼)",
# ... 更多模型
}
```

**如何添加新模型**:
1. 在 `model_config.py` 的 `model_options` 字典中添加新项
2. 格式:`"模型ID": "显示名称"`

#### 位置2:默认模型配置 - `.env` 文件

**文件路径**:`.env`(项目根目录)

**作用**:设置系统默认使用的模型

**配置项**:
```bash
DEEPSEEK_MODEL_NAME=deepseek-chat
```

**如何修改默认模型**:
1. 编辑 `.env` 文件
2. 修改 `DEEPSEEK_MODEL_NAME` 的值
3. 值必须是 `model_config.py` 中 `model_options` 的键之一

---

## 🔍 代码实现分析

### 模型选择器(侧边栏)

**位置**:`app.py` 的 `model_selector()` 函数

**代码**:
```python
def model_selector():
"""模型选择器"""
st.sidebar.subheader("🤖 AI模型选择")

# 获取配置文件中的默认模型
default_model = config.DEEPSEEK_MODEL_NAME

# 从 session_state 获取当前选择
current_model = st.session_state.get('selected_model', default_model)

# 显示选择框
selected_model = st.sidebar.selectbox(
"选择AI模型",
options=list(model_options.keys()),
...
)

return selected_model
```

**问题**:虽然保存到 `session_state`,但很多地方不使用它

### 实际使用情况

#### ❌ 不生效的地方(强制使用配置文件)

**1. 股票分析页面** (`app.py` 的 `run_stock_analysis`)
```python
# 强制使用配置文件中的默认模型(忽略 session_state 中的旧值)
config_model = config.DEEPSEEK_MODEL_NAME
if config_model in model_options:
selected_model = config_model
else:
selected_model = list(model_options.keys())[0]

agents = StockAnalysisAgents(model=selected_model) # 使用配置文件的值
```

**2. 批量分析功能** (`app.py` 的 `run_batch_analysis`)
```python
# 强制使用配置文件中的默认模型
config_model = config.DEEPSEEK_MODEL_NAME
if config_model in model_options:
selected_model = config_model
else:
selected_model = list(model_options.keys())[0]
```

**3. 批量分析中的单个股票分析** (`app.py` 的 `analyze_single_stock_for_batch`)
```python
# 强制使用配置文件中的默认模型(忽略传入的旧值)
config_model = config.DEEPSEEK_MODEL_NAME
if selected_model is None or selected_model == "" or selected_model == "deepseek-chat":
selected_model = config_model
```

#### ✅ 生效的地方

**1. 主力选股页面** (`main_force_ui.py`)
```python
# 页面内有自己的模型选择
model = st.selectbox(
"选择AI模型",
list(app_model_options.keys()),
...
)

analyzer = MainForceAnalyzer(model=model) # 使用页面选择的值
```

---

## 🔧 如何让侧边栏选择全局生效?

### 方案1:修改代码使用 session_state(推荐)

修改所有强制使用 `config.DEEPSEEK_MODEL_NAME` 的地方,改为优先使用 `session_state.selected_model`:

```python
# 修改前
config_model = config.DEEPSEEK_MODEL_NAME
selected_model = config_model

# 修改后
selected_model = st.session_state.get('selected_model', config.DEEPSEEK_MODEL_NAME)
if selected_model not in model_options:
selected_model = config.DEEPSEEK_MODEL_NAME
```

**需要修改的文件**:
1. `app.py` - `run_stock_analysis()` 函数
2. `app.py` - `run_batch_analysis()` 函数
3. `app.py` - `analyze_single_stock_for_batch()` 函数

### 方案2:保持现状,使用配置文件

**优点**:
- 配置持久化(重启后仍然有效)
- 不依赖 Streamlit session

**缺点**:
- 需要修改 `.env` 文件才能改变模型
- 不能通过UI快速切换

---

## 📝 模型配置详细说明

### model_config.py 结构

```python
model_options = {
# 键:模型ID(用于API调用)
# 值:显示名称(在UI中显示)
"deepseek-chat": "DeepSeek Chat (默认)",
"deepseek-reasoner": "DeepSeek Reasoner (推理增强)",
# ...
}
```

### 添加新模型的步骤

1. **确定模型ID**:从API文档获取模型标识符
2. **添加到 model_config.py**:
```python
model_options = {
# ... 现有模型
"new-model-id": "新模型显示名称",
}
```
3. **(可选)设置为默认**:在 `.env` 文件中设置
```bash
DEEPSEEK_MODEL_NAME=new-model-id
```

### 当前可用的模型

根据 `model_config.py`,当前支持以下模型:

| 模型ID | 显示名称 | 说明 |
|--------|----------|------|
| `deepseek-chat` | DeepSeek Chat (默认) | 默认模型 |
| `deepseek-reasoner` | DeepSeek Reasoner (推理增强) | 推理能力更强 |
| `qwen-plus` | qwen-plus (阿里百炼) | 阿里云模型 |
| `qwen-plus-latest` | qwen-plus-latest (阿里百炼) | 最新版本 |
| `qwen-flash` | qwen-flash (阿里百炼) | 快速版本 |
| `qwen-turbo` | qwen-turbo (阿里百炼) | 加速版本 |
| `qwen3-max` | qwen-max (阿里百炼) | 最大版本 |
| `qwen-long` | qwen-long (阿里百炼) | 长文本版本 |
| `deepseek-ai/DeepSeek-R1-0528-Qwen3-8B` | DeepSeek-R1 免费(硅基流动) | 免费模型 |
| `Qwen/Qwen2.5-7B-Instruct` | Qwen 免费(硅基流动) | 免费模型 |
| `Pro/deepseek-ai/DeepSeek-V3.1-Terminus` | DeepSeek-V3.1-Terminus (硅基流动) | 专业版 |
| `deepseek-ai/DeepSeek-R1` | DeepSeek-R1 (硅基流动) | R1版本 |
| `Qwen/Qwen3-235B-A22B-Thinking-2507` | Qwen3-235B (硅基流动) | 大模型 |
| `zai-org/GLM-4.6` | 智谱(硅基流动) | 智谱模型 |
| `moonshotai/Kimi-K2-Instruct-0905` | Kimi (硅基流动) | Kimi模型 |
| `Ring-1T` | 蚂蚁百灵 (硅基流动) | 蚂蚁模型 |
| `step3` | 阶跃星辰(硅基流动) | 阶跃模型 |

---

## 🎯 建议

### 短期方案(保持现状)

1. **修改默认模型**:编辑 `.env` 文件,修改 `DEEPSEEK_MODEL_NAME`
2. **主力选股页面**:使用页面内的模型选择(已生效)

### 长期方案(推荐)

修改代码,让侧边栏的模型选择真正全局生效:

1. 修改 `app.py` 中所有使用模型的地方
2. 优先使用 `st.session_state.selected_model`
3. 如果不存在或无效,回退到 `config.DEEPSEEK_MODEL_NAME`

这样可以:
- ✅ 通过UI快速切换模型
- ✅ 配置持久化(通过 `.env`)
- ✅ 用户体验更好

---

## 📚 相关文件

- **模型选项定义**:`model_config.py`
- **默认模型配置**:`.env` 文件中的 `DEEPSEEK_MODEL_NAME`
- **模型选择器**:`app.py` 的 `model_selector()` 函数
- **配置文件加载**:`config.py`
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# 🤖 复合多AI智能体股票团队分析系统

- 初心:在股市摸爬滚打多年,自学自编各种指标,花冤柉钱学习了各种战法各种策略,也曾入各种小班,总是赚少赔多,逐渐失去在股市玩的信心。自从去年deepseek上市,一直探索用ai辅助分析,且近日受tradingagents项目启发(感谢原作),多agent结合跟踪主力资金战法(某指每年收费6000rmb),用各种ai辅助编程,拼凑了这么个小程序,根据软件提供的辅助信息,实盘测试盈率还是挺高的,并且逐步形成了自己的交易系统,近一个月来,账户也慢慢在扰亏为盈。开源此软件的目的,就是为了使像我一样的小散,不再迷范。也许这个软件不能让你发大财,但是他能给你足够的信心。最后提醒:股市有风险,入市需谨慎!
- 初心:在股市摸爬滚打多年,自学自编各种指标,花冤柉钱学习了各种战法各种策略,也曾入各种小班,总是赚少赔多,逐渐失去在股市玩的信心。自从去年deepseek上市,一直探索用ai辅助分析,且近日受tradingagents项目启发(感谢原作),多agent结合跟踪主力资金战法(某指每年收费6000rmb),用各种ai辅助编程,拼凑了这么个小程序,根据软件提供的辅助信息,实盘测试盈率还是挺高的,并且逐步形成了自己的交易系统,近一个月来,账户也慢慢在扰亏为盈。开源此软件的目的,就是为了使像我一样的小散,不再迷范。也许这个软件不能让你发大财,但是他能给你足够的信心。最后提醒:股市有风险,入市需谨慎!欢迎加入qq群聊,群号:1059277514
<img width="310" height="408" alt="QQ_1766893237734" src="https://github.com/user-attachments/assets/c1087858-89cd-470a-80df-70e9ac923f0e" style="display: block; margin: 0 auto;" />

**点击zread图标,查看详细文档**
[![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/oficcejo/aiagents-stock)

## ⭐ 1214更新 - 净利增长策略 📈

Expand Down
23 changes: 20 additions & 3 deletions ai_agents.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
from deepseek_client import DeepSeekClient
from typing import Dict, Any
import time
import config

class StockAnalysisAgents:
"""股票分析AI智能体集合"""

def __init__(self, model="deepseek-chat"):
self.model = model
self.deepseek_client = DeepSeekClient(model=model)
def __init__(self, model=None):
# 调试:打印传入的参数和配置
print(f"[StockAnalysisAgents.__init__] 传入参数: model={model}")
print(f"[StockAnalysisAgents.__init__] 配置文件中的 DEEPSEEK_MODEL_NAME: {config.DEEPSEEK_MODEL_NAME}")

# 强制使用配置文件中的默认模型
# 如果传入的是 None、空字符串或旧的默认值 "deepseek-chat",都使用配置文件的值
if model is None or model == "" or model == "deepseek-chat":
self.model = config.DEEPSEEK_MODEL_NAME
if model == "deepseek-chat":
print(f"[StockAnalysisAgents.__init__] ⚠️ 检测到传入的模型是旧的默认值 'deepseek-chat',强制使用配置文件中的模型: {self.model}")
else:
print(f"[StockAnalysisAgents.__init__] 使用配置文件中的默认模型: {self.model}")
else:
self.model = model
print(f"[StockAnalysisAgents.__init__] 使用传入的模型参数: {self.model}")

print(f"[StockAnalysisAgents.__init__] ✅ 最终使用的模型: {self.model}")
self.deepseek_client = DeepSeekClient(model=self.model)

def technical_analyst_agent(self, stock_info: Dict, stock_data: Any, indicators: Dict) -> Dict[str, Any]:
"""技术面分析智能体"""
Expand Down
Loading