别再手动盯盘了!用Python+Supermind API,5分钟搭建你的第一个量化策略(附完整代码)
零基础玩转量化交易:用Python+Supermind实现你的第一个自动交易策略
第一次听说量化交易时,我盯着屏幕上那些复杂的数学公式和代码直发懵——这玩意儿真的适合普通投资者吗?直到有一天,我用Python写出了一个简单的双均线策略,看着它自动执行买卖操作并生成收益曲线时,那种"原来我也能做到"的成就感简直难以形容。今天,就让我们抛开那些晦涩的理论,直接从最实用的代码入手,带你体验量化交易的魅力。
1. 准备工作:搭建你的量化工具箱
在开始编写策略前,我们需要准备好三样工具:Python环境、Supermind账号和必要的代码库。别担心,即使你昨天才安装Python,跟着下面的步骤也能顺利完成。
1.1 Python环境配置
推荐使用Anaconda来管理Python环境,它能帮你轻松处理各种依赖关系。安装完成后,创建一个专用于量化交易的虚拟环境:
conda create -n quant python=3.8
conda activate quant
接着安装量化交易必备的几个库:
pip install pandas numpy matplotlib requests
提示:如果遇到网络问题,可以尝试使用国内镜像源,例如加上
-i https://pypi.tuna.tsinghua.edu.cn/simple
1.2 Supermind平台注册与API获取
- 访问Supermind官网完成注册
- 进入"开发者中心"申请API Key
- 记录下你的
API Key和Secret Key(这些信息后续会用到)
Supermind提供了丰富的金融数据接口,包括:
| 数据类型 | 覆盖范围 | 更新频率 |
|---|---|---|
| 股票行情 | 沪深A股、ETF | 实时 |
| 财务数据 | 资产负债表、利润表等 | 季度 |
| 行业指数 | 申万一级/二级行业 | 每日 |
| 衍生品数据 | 股指期货、期权 | 实时 |
1.3 连接Supermind API
让我们先测试API连接是否正常。创建一个 sm_api.py 文件,写入以下代码:
import requests
import json
def get_token():
url = "https://api.supermind.com/v1/auth/token"
headers = {"Content-Type": "application/json"}
data = {
"api_key": "你的API_KEY",
"secret_key": "你的SECRET_KEY"
}
response = requests.post(url, headers=headers, data=json.dumps(data))
return response.json()["data"]["token"]
# 测试获取上证指数数据
def get_sh_index(token):
url = "https://api.supermind.com/v1/quote/kline"
params = {
"symbol": "000001.SH",
"start_time": "2023-01-01",
"end_time": "2023-12-31",
"frequency": "1d"
}
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(url, headers=headers, params=params)
return response.json()
if __name__ == "__main__":
token = get_token()
data = get_sh_index(token)
print(data[:2]) # 打印前两条数据
运行这个脚本,如果看到返回了上证指数的K线数据,说明环境配置成功!
2. 双均线策略:量化交易的"Hello World"
在量化领域,双均线策略就像编程界的"Hello World"——简单却蕴含精髓。它的逻辑非常直观:当短期均线上穿长期均线时买入,下穿时卖出。
2.1 策略逻辑解析
假设我们选择:
- 短期均线(快线):5日均线
- 长期均线(慢线):20日均线
策略信号生成规则:
- 当5日均线从下方穿过20日均线(金叉),买入信号
- 当5日均线从上方穿过20日均线(死叉),卖出信号
- 其余时间保持现有仓位
为什么这个策略有效?因为它本质上捕捉的是趋势的形成和反转。当短期均线向上突破长期均线,往往意味着新趋势的开始;反之则可能预示趋势结束。
2.2 获取并处理股票数据
让我们先获取一只股票的历史数据并进行均线计算。以贵州茅台(600519.SH)为例:
import pandas as pd
def calculate_ma(data):
"""计算均线指标"""
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['trade_date'])
df.set_index('date', inplace=True)
df['ma5'] = df['close'].rolling(5).mean()
df['ma20'] = df['close'].rolling(20).mean()
return df.dropna()
# 假设data是从API获取的K线数据
maotai_data = get_stock_data("600519.SH", "2022-01-01", "2023-12-31")
maotai_df = calculate_ma(maotai_data)
2.3 策略信号生成
现在我们来编写信号生成的代码:
def generate_signals(df):
"""生成交易信号"""
df['signal'] = 0 # 0表示无信号,1表示买入,-1表示卖出
# 金叉:5日均线上穿20日均线
df.loc[(df['ma5'].shift(1) <= df['ma20'].shift(1)) &
(df['ma5'] > df['ma20']), 'signal'] = 1
# 死叉:5日均线下穿20日均线
df.loc[(df['ma5'].shift(1) >= df['ma20'].shift(1)) &
(df['ma5'] < df['ma20']), 'signal'] = -1
return df
signals_df = generate_signals(maotai_df)
print(signals_df[['close', 'ma5', 'ma20', 'signal']].tail(10))
这段代码会在符合条件的位置标记1(买入)或-1(卖出),其余时间为0。
3. 回测:验证策略的有效性
策略写好了,但它真的能赚钱吗?我们需要通过历史数据来回测它的表现。
3.1 回测框架搭建
一个完整的回测需要包含以下几个部分:
- 初始资金设置
- 交易手续费计算
- 仓位管理
- 收益率计算
def backtest(df, initial_capital=100000, commission=0.0003):
"""策略回测"""
position = 0 # 持仓数量
cash = initial_capital # 现金
portfolio_value = [initial_capital] # 组合价值记录
for i in range(1, len(df)):
current_price = df.iloc[i]['close']
signal = df.iloc[i]['signal']
# 执行买入信号
if signal == 1 and position == 0:
position = cash // current_price
cash -= position * current_price * (1 + commission)
# 执行卖出信号
elif signal == -1 and position > 0:
cash += position * current_price * (1 - commission)
position = 0
# 记录当日组合价值
daily_value = cash + position * current_price
portfolio_value.append(daily_value)
df['portfolio'] = portfolio_value
df['returns'] = df['portfolio'].pct_change()
return df
3.2 回测结果分析
让我们运行回测并可视化结果:
import matplotlib.pyplot as plt
result_df = backtest(signals_df)
plt.figure(figsize=(12, 8))
plt.plot(result_df.index, result_df['close'] / result_df['close'].iloc[0], label='贵州茅台')
plt.plot(result_df.index, result_df['portfolio'] / result_df['portfolio'].iloc[0], label='策略收益')
plt.plot(result_df.index, result_df['ma5'] / result_df['ma5'].iloc[0], label='5日均线', alpha=0.5)
plt.plot(result_df.index, result_df['ma20'] / result_df['ma20'].iloc[0], label='20日均线', alpha=0.5)
plt.legend()
plt.title('双均线策略回测结果')
plt.show()
通过对比策略收益和股票本身收益,我们可以直观看到策略的表现。此外,还可以计算一些关键指标:
def calculate_metrics(df):
"""计算策略评价指标"""
total_return = df['portfolio'].iloc[-1] / df['portfolio'].iloc[0] - 1
annual_return = (1 + total_return) ** (252/len(df)) - 1
volatility = df['returns'].std() * np.sqrt(252)
sharpe_ratio = annual_return / volatility
max_portfolio = df['portfolio'].cummax()
drawdown = (df['portfolio'] - max_portfolio) / max_portfolio
max_drawdown = drawdown.min()
return {
"总收益率": total_return,
"年化收益率": annual_return,
"波动率": volatility,
"夏普比率": sharpe_ratio,
"最大回撤": max_drawdown
}
metrics = calculate_metrics(result_df)
for k, v in metrics.items():
print(f"{k}: {v:.2%}")
4. 策略优化与进阶思考
基础策略跑通了,但你可能已经发现了一些问题:交易信号过于频繁?在某些市场环境下表现不佳?这正是量化交易最有意思的部分——不断优化和改进。
4.1 常见优化方向
- 参数优化 :
- 尝试不同的均线组合(如10/30、5/60)
- 使用网格搜索寻找最优参数
from itertools import product
def optimize_ma(df, short_range, long_range):
results = []
for short, long in product(short_range, long_range):
if short >= long:
continue
temp_df = df.copy()
temp_df['ma_short'] = temp_df['close'].rolling(short).mean()
temp_df['ma_long'] = temp_df['close'].rolling(long).mean()
# 生成信号和回测(代码略)
# ...
metrics = calculate_metrics(temp_df)
metrics.update({'short': short, 'long': long})
results.append(metrics)
return pd.DataFrame(results).sort_values('夏普比率', ascending=False)
# 测试5-30日的各种组合
optimization_results = optimize_ma(maotai_data, range(5, 11), range(20, 31))
print(optimization_results.head())
-
过滤假信号 :
- 加入成交量过滤(如成交量需大于20日均量)
- 加入波动率过滤(如ATR指标)
-
仓位管理 :
- 动态调整仓位大小
- 加入止损止盈机制
4.2 策略组合与风险管理
单一策略往往难以适应所有市场环境。成熟的量化交易者通常会:
- 同时运行多个不相关策略
- 根据市场状态调整策略权重
- 严格控制单策略最大回撤
一个简单的多策略组合示例:
strategies = {
'双均线': signals_df,
'动量策略': momentum_df,
'均值回归': mean_reversion_df
}
portfolio_weights = {'双均线': 0.5, '动量策略': 0.3, '均值回归': 0.2}
combined_returns = sum(df['returns'] * weight for df, weight in zip(strategies.values(), portfolio_weights.values()))
4.3 实盘前的最后检查
在将策略投入实盘前,务必进行:
- 样本外测试 :使用回测期间之后的数据验证
- 参数稳定性测试 :检查最优参数是否在不同时间段都有效
- 交易成本测试 :考虑滑点、手续费等实际成本
- 极端行情测试 :模拟股灾、熔断等特殊市场环境
def stress_test(df, crash_dates):
"""极端行情测试"""
for date in crash_dates:
crash_period = df[df.index >= date].iloc[:10] # 检查崩盘后10天表现
drawdown = (crash_period['portfolio'].min() - crash_period['portfolio'].iloc[0]) / crash_period['portfolio'].iloc[0]
print(f"{date} 市场下跌期间策略回撤: {drawdown:.2%}")
第一次看到自己的策略在历史数据上产生交易信号时,那种感觉就像看着自己组装的小车终于能跑起来一样兴奋。记得最早我测试的一个简单策略,在2015年股灾期间竟然成功避免了大部分下跌,那一刻我突然明白为什么专业机构如此依赖量化方法。当然,后来也遇到过策略失效的时候,但正是这些经历让我学会了永远要有备选方案。
更多推荐
所有评论(0)