python+openai兼容api实现ai自动分析a股行情股票数据自动交易代码
代码语言:python
所属分类:其他
代码描述:python+openai兼容api实现ai自动分析a股行情股票数据自动交易代码,行情数据是实时真实的,交易是模拟的,可以看到ai模拟的交易决策买入卖出能否帮你挣钱。
代码标签: python openai 兼容 api ai 自动 分析 a股 行情 股票 数据 自动 交易 代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
# -*- coding: utf-8 -*-
"""
AI 模拟炒股系统 Web 版
功能:
1. 内嵌HTML页面操作
2. 可添加自定义股票
3. 每只股票独立账户、独立初始资金、独立收益
4. 每只股票一个独立AI交易任务
5. 可开始/暂停每只股票的AI交易
6. 显示实时行情、资金、收益、K线图
7. AI日志独立记录,最新日志在前,日志带时间卡片
8. 使用本地SQLite模拟买入卖出
9. 交易日时间段自动运行AI交易
10. 后期可替换为真实券商交易API
依赖:
pip install flask requests openai
环境变量:
DASHSCOPE_API_KEY=你的通义千问/百炼API Key
运行:
python ai_stock_web.py --port 8899
非交易时间测试成交:
python ai_stock_web.py --allow-off-hours
"""
import os
import re
import sys
import json
import time
import sqlite3
import argparse
import threading
import datetime
from concurrent.futures import ThreadPoolExecutor
import requests
from flask import Flask, jsonify, request, Response
from openai import OpenAI
# =====================
# 全局配置
# =====================
app = Flask(__name__)
# =====================
# 内嵌HTML页面
# =====================
HTML_PAGE = r"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>AI 模拟炒股控制台</title>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--bg: #0a0e17;
--card: #121a2b;
--border: #203051;
--text: #e8edf5;
--sub: #7d8db0;
--up: #ef4444;
--down: #22c55e;
--flat: #7d8db0;
--accent: #3b82f6;
--accent-hover: #2563eb;
--danger: #ef4444;
}
body {
background: var(--bg);
color: var(--text);
font-family: "SF Pro Display", "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
min-height: 100vh;
}
header {
position: sticky;
top: 0;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
flex-wrap: wrap;
padding: 18px 28px;
border-bottom: 1px solid var(--border);
background: rgba(10, 14, 23, 0.82);
backdrop-filter: blur(10px);
}
h1 {
font-size: 22px;
font-weight: 800;
}
#globalStatus {
color: var(--sub);
font-size: 13px;
}
.toolbar {
padding: 18px 28px 8px;
}
.add-form {
display: flex;
gap: 10px;
flex-wrap: wrap;
align-items: center;
}
input {
background: var(--card);
border: 1px solid var(--border);
color: var(--text);
border-radius: 10px;
padding: 10px 12px;
outline: none;
font-size: 14px;
}
input:focus {
border-color: var(--accent);
}
#symbolInput {
width: 220px;
}
#initialInput,
#intervalInput {
width: 130px;
}
button {
border: none;
border-radius: 10px;
padding: 10px 16px;
font-size: 14px;
font-weight: 700;
cursor: pointer;
background: var(--accent);
color: white;
transition: 0.15s;
}
button:hover {
background: var(--accent-hover);
}
button:disabled {
opacity: 0.45;
cursor: not-allowed;
}
button.danger {
background: rgba(239, 68, 68, 0.12);
color: var(--danger);
border: 1px solid rgba(239, 68, 68, 0.25);
}
button.danger:hover {
background: rgba(239, 68, 68, 0.2);
}
.tip {
margin-top: 10px;
color: var(--sub);
font-size: 12px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
gap: 16px;
padding: 18px 28px 30px;
}
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 18px;
padding: 18px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
}
.card.up {
border-left: 4px solid var(--up);
}
.card.down {
border-left: 4px solid var(--down);
}
.card.flat {
border-left: 4px solid var(--flat);
}
.card-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 10px;
margin-bottom: 10px;
}
.stock-name {
font-size: 20px;
font-weight: 800;
}
.stock-code {
color: var(--sub);
font-size: 12px;
margin-top: 3px;
}
.badge {
padding: 5px 10px;
border-radius: 999px;
font-size: 12px;
font-weight: 800;
white-space: nowrap;
}
.badge.up {
background: rgba(239, 68, 68, 0.12);
color: var(--up);
}
.badge.down {
background: rgba(34, 197, 94, 0.12);
color: var(--down);
}
.badge.flat {
background: rgba(125, 141, 176, 0.12);
color: var(--flat);
}
.price-row {
display: flex;
align-items: baseline;
gap: 10px;
margin-bottom: 14px;
}
.price {
font-size: 34px;
font-weight: 900;
}
.change {
font-size: 15px;
font-weight: 800;
}
.up-text {
color: var(--up);
}
.down-text {
color: var(--down);
}
.flat-text {
color: var(--flat);
}
.kv-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px 14px;
margin-bottom: 14px;
}
.kv {
display: flex;
justify-content: space-between;
gap: 8px;
font-size: 13px;
color: var(--sub);
}
.kv b {
color: var(--text);
font-weight: 750;
text-align: right;
font-variant-numeric: tabular-nums;
}
.kv.full {
grid-column: 1 / -1;
}
.ai-line {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
font-size: 12px;
color: var(--sub);
margin-bottom: 10px;
}
.pill {
padding: 4px 10px;
border-radius: 999px;
font-weight: 800;
}
.pill.on {
background: rgba(34, 197, 94, 0.12);
color: var(--down);
}
.pill.off {
background: rgba(125, 141, 176, 0.14);
color: var(--flat);
}
.pill.warn {
background: rgba(245, 158, 11, 0.14);
color: #fbbf24;
}
.log-title {
font-size: 12px;
color: var(--sub);
font-weight: 800;
margin-bottom: 6px;
}
.log-list {
display: flex;
flex-direction: column;
gap: 8px;
max-height: 220px;
overflow: auto;
margin-bottom: 12px;
padding-right: 2px;
}
.log-item {
border: 1px solid var(--border);
background: rgba(255, 255, 255, 0.02);
border-radius: 12px;
padding: 8px 10px;
}
.log-meta {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 4px;
font-size: 11px;
color: var(--sub);
}
.log-time {
font-weight: 800;
font-variant-numeric: tabular-nums;
}
.log-level {
padding: 2px 6px;
border-radius: 6px;
font-size: 10px;
font-weight: 900;
}
.level-info {
background: rgba(59, 130, 246, 0.12);
color: #60a5fa;
}
.level-error {
background: rgba(239, 68, 68, 0.12);
color: #f87171;
}
.level-warning {
background: rgba(245, 158, 11, 0.12);
color: #fbbf24;
}
.level-trade {
background: rgba(34, 197, 94, 0.12);
color: #4ade80;
}
.level-final {
background: rgba(168, 85, 247, 0.12);
color: #c084fc;
}
.level-tool {
background: rgba(125, 141, 176, 0.14);
color: #a3b3d2;
}
.log-text {
font-size: 12px;
line-height: 1.45;
white-space: pre-wrap;
word-break: break-word;
}
.log-empty {
color: var(--sub);
font-size: 12px;
padding: 10px;
border: 1px dashed var(--border);
border-radius: 12px;
}
.actions {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.empty {
grid-column: 1 / -1;
padding: 80px 20px;
text-align: center;
color: var(--sub);
}
.modal-overlay {
display: none;
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.68);
backdrop-filter: blur(4px);
z-index: 1000;
align-items: center;
justify-content: center;
padding: 20px;
}
.modal-overlay.active {
display: flex;
}
.modal {
width: 100%;
max-width: 1000px;
background: var(--card);
border: 1px solid var(--border);
border-radius: 18px;
overflow: hidden;
box-shadow: 0 30px 100px rgba(0, 0, 0, 0.45);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 18px;
border-bottom: 1px solid var(--border);
font-weight: 800;
}
.modal-close {
width: 34px;
height: 34px;
border-radius: 10px;
background: transparent;
color: var(--sub);
border: 1px solid var(--border);
}
.modal-close:hover {
color: var(--danger);
border-color: var(--danger);
background: rgba(239, 68, 68, 0.08);
}
.kline-chart {
width: 100%;
height: 560px;
padding: 10px;
}
.log-modal-list {
max-height: 620px;
overflow: auto;
padding: 16px;
display: flex;
flex-direction: column;
gap: 10px;
}
.loading {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
min-height: 120px;
color: var(--sub);
}
.log-refresh-b.........完整代码请登录后点击上方下载按钮下载查看














网友评论0