用双均线做一个简单的行情分析与自动化处理框架
最近在整理一个轻量级的行情处理框架,目标不是做复杂策略,而是把“数据获取 → 指标计算 → 信号输出”这一套流程走通。
为了让结构尽量清晰,我选了一个非常基础的逻辑:双均线交叉。
逻辑简单,方便验证系统是否稳定运行,也方便后续替换成其他指标。
一、先从结构拆分开始
一开始是单文件脚本,后来发现不太好维护,于是改成分层结构:
data_layer.py indicator_layer.py strategy_layer.py execution_layer.py main.py
这样做的好处是:
-
数据层只负责获取和整理行情
-
指标层只负责计算技术指标
-
策略层只做信号判断
-
执行层负责处理信号(记录或调用接口)
-
主程序负责调度
拆开之后,每一层逻辑都变得简单很多。
二、数据层:稳定比复杂更重要
自动化系统第一步是数据。
示例结构:
import requests
import pandas as pd
def fetch_kline(symbol, interval="1m", limit=100):
url = "https://api.example.com/market/kline"
params = {
"symbol": symbol,
"interval": interval,
"limit": limit
}
r = requests.get(url, params=params, timeout=5)
data = r.json()
return pd.DataFrame(data)
真实运行时需要考虑:
-
请求超时
-
数据为空
-
返回字段异常
-
请求频率限制
在云服务器环境下(例如部署在 ECS 上),建议增加:
-
异常捕获
-
自动重试
-
日志记录
-
数据完整性校验
否则系统长时间运行后容易因为一次异常退出。
三、指标层:均线计算本身并不复杂
均线计算用 pandas 就可以完成:
def add_ma(df):
df["MA5"] = df["close"].rolling(5).mean()
df["MA10"] = df["close"].rolling(10).mean()
return df
双均线本身只是一个验证逻辑的工具。
它的优势是:
-
行为清晰
-
结果可视化直观
-
容易调试
这里的重点不是指标本身,而是验证数据流是否稳定。
四、策略层:判断“交叉”而不是“状态”
很多初学者会直接写:
if ma5 > ma10: signal = "UP"
但这只是当前状态,不是交叉。
更严谨的方式是比较当前与上一周期的关系:
def generate_signal(df):
df["prev_MA5"] = df["MA5"].shift(1)
df["prev_MA10"] = df["MA10"].shift(1)
buy = (
(df["MA5"] > df["MA10"]) &
(df["prev_MA5"] <= df["prev_MA10"])
)
sell = (
(df["MA5"] < df["MA10"]) &
(df["prev_MA5"] >= df["prev_MA10"])
)
if buy.iloc[-1]:
return "BUY"
elif sell.iloc[-1]:
return "SELL"
return None
这样只在交叉发生的那一刻触发一次信号。
五、执行层:控制重复触发
如果不做状态管理,信号会在连续几根K线内重复出现。
简单处理方式:
-
增加当前持仓状态变量
-
或将状态写入缓存 / 数据库
-
只有状态变化时才处理信号
示例:
current_position = None
def handle_signal(signal):
global current_position
if signal == "BUY" and current_position != "LONG":
current_position = "LONG"
print("状态切换为 LONG")
elif signal == "SELL" and current_position != "SHORT":
current_position = "SHORT"
print("状态切换为 SHORT")
如果是长期运行系统,建议不要使用全局变量,而是用持久化方式记录状态。
六、主循环与异常保护
自动化系统的稳定性通常比算法更重要。
主循环建议加异常保护:
import time
while True:
try:
df = fetch_kline("EURUSD")
df = add_ma(df)
signal = generate_signal(df)
handle_signal(signal)
except Exception as e:
print("异常:", e)
time.sleep(60)
实际部署时可以结合:
-
Docker 容器运行
-
定时任务调度
-
日志系统
-
进程守护工具
七、为什么选择双均线做起点
不是因为它效果最好,而是因为它足够简单。
一个简单逻辑可以帮助验证:
-
数据是否连续
-
系统是否稳定
-
信号是否只触发一次
-
异常是否会导致中断
当这一整套结构稳定后,再替换成其他指标或策略,成本会非常低。
对自动化系统来说,框架稳定远比模型复杂重要。
八、整体结构回顾
这个小框架的核心思路:
-
数据层保证稳定
-
指标层只做计算
-
策略层只做判断
-
执行层负责状态管理
-
主程序负责调度
逻辑不复杂,但结构清晰。
对于刚开始搭建行情分析或自动化处理流程的开发者来说,这样一个最小结构比直接堆复杂模型更容易维护。
后续如果扩展:
-
可以增加更多指标模块
-
可以引入回测模块
-
可以增加日志与监控
-
可以接入消息通知系统
底层框架不需要大改。
- 点赞
- 收藏
- 关注作者
评论(0)