Files
2025-11-13 08:02:34 +08:00

194 lines
6.2 KiB
Python

#!/usr/bin/env python3
"""
测试不同 Ollama 模型的量化分析能力
评估标准:
1. 响应速度
2. JSON 格式准确性
3. 技术分析质量
4. 推理能力
"""
import httpx
import json
import time
import asyncio
# 测试用的技术指标数据
TEST_INDICATORS = {
"ma5": 270.5,
"ma20": 265.0,
"ma50": 255.0,
"rsi": 65.5,
"macd": 2.3,
"macd_signal": 1.8,
"macd_hist": 0.5,
"current_price": 272.0,
"volume": 50000000
}
# 量化分析 Prompt
QUANT_PROMPT = f"""
请根据以下技术指标分析 AAPL 的交易信号。
技术指标数据:
{json.dumps(TEST_INDICATORS, ensure_ascii=False, indent=2)}
请执行以下分析:
1. MA (移动平均线) 分析:当前价格与 MA5/MA20/MA50 的位置关系,趋势方向
2. RSI (相对强弱指标) 分析:超买/超卖信号,动量变化
3. MACD (指数平滑异同移动平均线) 分析:快线/慢线交叉,直方图趋势
4. 综合判断:BUY/SELL/HOLD 信号
5. 置信度评估:0.0-1.0 之间的置信度分数
6. 风险等级:基于指标波动性和不确定性的 LOW/MEDIUM/HIGH
请输出 JSON 格式(不需要额外说明,直接返回 JSON):
{{
"signal": "BUY|SELL|HOLD",
"confidence": <0-1 的数字>,
"reason": "综合分析理由,100-150 字以内",
"ma_signal": "MA 分析结论",
"rsi_signal": "RSI 分析结论",
"macd_signal": "MACD 分析结论",
"risk_level": "LOW|MEDIUM|HIGH",
"entry_price": <建议入场价或 null>,
"stop_loss": <止损价或 null>,
"take_profit": <止盈价或 null>
}}
"""
# 候选模型列表
CANDIDATE_MODELS = [
"deepseek-r1:70b", # 70B DeepSeek 推理模型
"qwen2.5-coder:32b-instruct", # 32B Qwen 代码模型
"deepseek-coder:33b", # 33B DeepSeek 代码模型
"qwen3-coder:30b-a3b-q8_0", # 30B Qwen 高精度模型
"llama3.3:latest", # 70B Llama 3.3
]
async def test_model(model_name: str, timeout: int = 120) -> dict:
"""测试单个模型"""
print(f"\n{'='*60}")
print(f"Testing: {model_name}")
print(f"{'='*60}")
start_time = time.time()
try:
async with httpx.AsyncClient(timeout=timeout) as client:
response = await client.post(
"http://host.docker.internal:11434/api/generate",
json={
"model": model_name,
"prompt": QUANT_PROMPT,
"stream": False,
"temperature": 0.3,
"top_p": 0.9
}
)
if response.status_code != 200:
return {
"model": model_name,
"success": False,
"error": f"HTTP {response.status_code}",
"time": 0
}
elapsed = time.time() - start_time
result = response.json()
response_text = result.get("response", "")
# 尝试解析 JSON
json_data = None
try:
json_data = json.loads(response_text)
except:
# 尝试从 markdown 提取
if "```json" in response_text:
json_str = response_text.split("```json")[1].split("```")[0]
json_data = json.loads(json_str.strip())
elif "```" in response_text:
json_str = response_text.split("```")[1].split("```")[0]
json_data = json.loads(json_str.strip())
# 评分
score = 0
has_signal = json_data and "signal" in json_data
has_confidence = json_data and "confidence" in json_data
has_reason = json_data and "reason" in json_data and len(json_data.get("reason", "")) > 50
if has_signal: score += 25
if has_confidence: score += 25
if has_reason: score += 25
if elapsed < 30: score += 25
elif elapsed < 60: score += 15
elif elapsed < 90: score += 5
print(f"✅ Success!")
print(f"⏱️ Time: {elapsed:.2f}s")
print(f"📊 Score: {score}/100")
if json_data:
print(f"Signal: {json_data.get('signal', 'N/A')}")
print(f"Confidence: {json_data.get('confidence', 'N/A')}")
print(f"Reason: {json_data.get('reason', 'N/A')[:100]}...")
return {
"model": model_name,
"success": True,
"time": elapsed,
"score": score,
"has_valid_json": json_data is not None,
"response_preview": response_text[:200]
}
except Exception as e:
elapsed = time.time() - start_time
print(f"❌ Failed: {str(e)}")
return {
"model": model_name,
"success": False,
"error": str(e),
"time": elapsed,
"score": 0
}
async def main():
"""主测试函数"""
print("🚀 Starting Ollama Model Quantitative Analysis Test")
print(f"Testing {len(CANDIDATE_MODELS)} models...")
results = []
for model in CANDIDATE_MODELS:
result = await test_model(model)
results.append(result)
await asyncio.sleep(2) # 避免过载
# 排序并显示结果
print("\n" + "="*60)
print("📊 FINAL RESULTS (Ranked by Score)")
print("="*60)
successful = [r for r in results if r["success"]]
successful.sort(key=lambda x: x["score"], reverse=True)
for i, result in enumerate(successful, 1):
print(f"\n{i}. {result['model']}")
print(f" Score: {result['score']}/100")
print(f" Time: {result['time']:.2f}s")
print(f" Valid JSON: {'✅' if result['has_valid_json'] else '❌'}")
if successful:
best = successful[0]
print(f"\n🏆 RECOMMENDED MODEL: {best['model']}")
print(f" Score: {best['score']}/100, Time: {best['time']:.2f}s")
# 失败的模型
failed = [r for r in results if not r["success"]]
if failed:
print("\n❌ Failed Models:")
for result in failed:
print(f" - {result['model']}: {result['error']}")
if __name__ == "__main__":
asyncio.run(main())