一、前言
黄金期货(SHFE.au)是全球最重要的避险资产之一,具有波动相对平稳、趋势性强的特点。对于量化交易者来说,黄金是一个非常适合趋势跟踪策略的品种。
本文将介绍:
- 黄金期货品种特性
- 与国际金价的联动
- 趋势跟踪策略实现
- 避险属性的利用
二、为什么选择天勤量化(TqSdk)
在众多期货量化工具中,**天勤量化(TqSdk)**是目前国内最受欢迎的开源期货量化框架之一:
| 完全免费 | 开源免费,无需付费即可获取实时行情 |
| 数据全面 | 支持国内所有期货交易所的实时行情和历史数据 |
| 上手简单 | 几行Python代码即可获取数据 |
| 文档完善 | 官方文档详细,示例代码丰富 |
安装方法:
pip install tqsdk
三、黄金期货基础知识
3.1 合约信息
| 交易所 | 上海期货交易所(SHFE) |
| 合约代码 | au |
| 合约单位 | 1000克/手 |
| 最小变动价位 | 0.02元/克 |
| 每跳盈亏 | 20元/手 |
| 保证金比例 | 约8%-12% |
| 交易时间 | 日盘+夜盘 |
3.2 交易时间
| 日盘上午 | 09:00 – 10:15, 10:30 – 11:30 |
| 日盘下午 | 13:30 – 15:00 |
| 夜盘 | 21:00 – 次日02:30 |
3.3 黄金的避险属性
| 经济衰退 | 上涨 | 避险需求 |
| 地缘冲突 | 上涨 | 避险买盘 |
| 通胀上升 | 上涨 | 保值需求 |
| 美元走弱 | 上涨 | 负相关性 |
| 股市大跌 | 上涨 | 资金转移 |
3.4 影响因素
| 美元指数 | ⭐⭐⭐⭐⭐ | 负相关 |
| 美联储政策 | ⭐⭐⭐⭐⭐ | 利率预期 |
| 国际金价 | ⭐⭐⭐⭐⭐ | COMEX黄金 |
| 地缘政治 | ⭐⭐⭐⭐ | 避险情绪 |
| 通胀数据 | ⭐⭐⭐ | CPI等 |
四、获取黄金数据
4.1 实时行情
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:获取黄金期货实时行情
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth
api = TqApi(auth=TqAuth("快期账户", "快期密码"))
# 黄金主力合约
SYMBOL = "SHFE.au2506"
quote = api.get_quote(SYMBOL)
print("=" * 60)
print(f"黄金期货实时行情 – {SYMBOL}")
print("=" * 60)
api.wait_update()
print(f"最新价: {quote.last_price:.2f} 元/克")
print(f"涨跌: {quote.last_price – quote.pre_close:+.2f}")
print(f"涨跌幅: {(quote.last_price – quote.pre_close) / quote.pre_close:+.2%}")
print(f"开盘价: {quote.open:.2f}")
print(f"最高价: {quote.highest:.2f}")
print(f"最低价: {quote.lowest:.2f}")
print(f"成交量: {quote.volume} 手")
# 计算合约价值
contract_value = quote.last_price * 1000 # 1000克/手
margin = contract_value * 0.10 # 假设10%保证金
print(f"\\n合约价值: {contract_value:.0f} 元/手")
print(f"预估保证金: {margin:.0f} 元/手")
print(f"每跳盈亏: 20元 (0.02元×1000克)")
api.close()
4.2 波动特性分析
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:分析黄金波动特性
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth
import pandas as pd
import numpy as np
api = TqApi(auth=TqAuth("快期账户", "快期密码"))
SYMBOL = "SHFE.au2506"
klines = api.get_kline_serial(SYMBOL, 86400, 60)
api.wait_update()
df = pd.DataFrame({
'high': klines['high'],
'low': klines['low'],
'close': klines['close'],
})
# 日内波幅
df['range'] = df['high'] – df['low']
df['range_pct'] = df['range'] / df['close'] * 100
# 日收益率
df['return'] = df['close'].pct_change() * 100
# ATR
df['tr'] = np.maximum(
df['high'] – df['low'],
np.maximum(
abs(df['high'] – df['close'].shift(1)),
abs(df['low'] – df['close'].shift(1))
)
)
df['atr14'] = df['tr'].rolling(14).mean()
print("=" * 60)
print("黄金波动特性分析")
print("=" * 60)
print(f"平均日内波幅: {df['range'].mean():.2f} 元/克")
print(f"平均日内波幅率: {df['range_pct'].mean():.2f}%")
print(f"日收益率标准差: {df['return'].std():.2f}%")
print(f"最大日涨幅: {df['return'].max():.2f}%")
print(f"最大日跌幅: {df['return'].min():.2f}%")
print(f"14日ATR: {df['atr14'].iloc[–1]:.2f}")
print("\\n特点总结:")
print(" – 波动率较低,适合趋势跟踪")
print(" – 趋势持续性强")
print(" – 与美元负相关")
api.close()
五、黄金量化策略
5.1 趋势跟踪策略
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:黄金趋势跟踪策略
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth, TqSim
from tqsdk.lib import TargetPosTask
import numpy as np
# ============ 策略参数 ============
SYMBOL = "SHFE.au2506"
FAST_MA = 10 # 快线周期
SLOW_MA = 30 # 慢线周期
ATR_PERIOD = 14
ATR_STOP = 2.5 # 止损ATR倍数(黄金波动小,可用更大倍数)
LOTS = 1
# ============ 初始化 ============
api = TqApi(TqSim(init_balance=500000), auth=TqAuth("快期账户", "快期密码"))
klines = api.get_kline_serial(SYMBOL, 3600, SLOW_MA + ATR_PERIOD + 10) # 小时线
account = api.get_account()
position = api.get_position(SYMBOL)
target_pos = TargetPosTask(api, SYMBOL)
print("=" * 60)
print("黄金趋势跟踪策略")
print("=" * 60)
print(f"合约: {SYMBOL}")
print(f"均线参数: MA{FAST_MA}/{SLOW_MA}")
print(f"止损: {ATR_STOP}倍ATR")
print("-" * 60)
entry_price = 0
stop_loss = 0
current_direction = 0
while True:
api.wait_update()
if api.is_changing(klines.iloc[–1], "datetime"):
close = klines["close"].values
high = klines["high"].values
low = klines["low"].values
# 计算均线
fast_ma = np.mean(close[–FAST_MA:])
slow_ma = np.mean(close[–SLOW_MA:])
# 计算ATR
tr = np.maximum(
high[–ATR_PERIOD:] – low[–ATR_PERIOD:],
np.abs(high[–ATR_PERIOD:] – close[–ATR_PERIOD–1:–1])
)
atr = np.mean(tr)
current_price = close[–1]
current_pos = position.pos_long – position.pos_short
# ============ 交易信号 ============
# 金叉做多
if fast_ma > slow_ma and current_direction != 1:
if current_direction == –1:
# 先平空
target_pos.set_target_volume(0)
target_pos.set_target_volume(LOTS)
entry_price = current_price
stop_loss = entry_price – atr * ATR_STOP
current_direction = 1
print(f"\\n[金叉做多] 价格={current_price:.2f} 止损={stop_loss:.2f}")
# 死叉做空
elif fast_ma < slow_ma and current_direction != –1:
if current_direction == 1:
target_pos.set_target_volume(0)
target_pos.set_target_volume(–LOTS)
entry_price = current_price
stop_loss = entry_price + atr * ATR_STOP
current_direction = –1
print(f"\\n[死叉做空] 价格={current_price:.2f} 止损={stop_loss:.2f}")
# ============ 止损与移动止损 ============
if current_direction == 1:
if current_price < stop_loss:
target_pos.set_target_volume(0)
print(f"\\n[止损平多] 价格={current_price:.2f}")
current_direction = 0
else:
# 移动止损
new_stop = current_price – atr * ATR_STOP
if new_stop > stop_loss:
stop_loss = new_stop
elif current_direction == –1:
if current_price > stop_loss:
target_pos.set_target_volume(0)
print(f"\\n[止损平空] 价格={current_price:.2f}")
current_direction = 0
else:
new_stop = current_price + atr * ATR_STOP
if new_stop < stop_loss:
stop_loss = new_stop
print(f"\\r价格={current_price:.2f} 快MA={fast_ma:.2f} 慢MA={slow_ma:.2f} "
f"ATR={atr:.2f} 止损={stop_loss:.2f}", end="")
5.2 突破回踩策略
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
功能:黄金突破回踩策略
说明:本代码仅供学习参考
"""
from tqsdk import TqApi, TqAuth, TqSim
from tqsdk.lib import TargetPosTask
import numpy as np
# ============ 策略参数 ============
SYMBOL = "SHFE.au2506"
CHANNEL_PERIOD = 20 # 通道周期
PULLBACK_RATIO = 0.382 # 回踩比例(斐波那契)
ATR_PERIOD = 14
LOTS = 1
# ============ 初始化 ============
api = TqApi(TqSim(init_balance=500000), auth=TqAuth("快期账户", "快期密码"))
klines = api.get_kline_serial(SYMBOL, 3600, CHANNEL_PERIOD + ATR_PERIOD + 10)
position = api.get_position(SYMBOL)
target_pos = TargetPosTask(api, SYMBOL)
print("=" * 60)
print("黄金突破回踩策略")
print("=" * 60)
print(f"通道周期: {CHANNEL_PERIOD}")
print(f"回踩比例: {PULLBACK_RATIO}")
print("-" * 60)
# 状态变量
breakout_high = 0 # 突破时的高点
breakout_low = 0 # 突破时的低点
waiting_pullback = 0 # 0=无信号, 1=等待回踩做多, -1=等待回踩做空
entry_price = 0
stop_loss = 0
while True:
api.wait_update()
if api.is_changing(klines.iloc[–1], "datetime"):
close = klines["close"].values
high = klines["high"].values
low = klines["low"].values
# 计算通道
channel_high = np.max(high[–CHANNEL_PERIOD–1:–1])
channel_low = np.min(low[–CHANNEL_PERIOD–1:–1])
channel_mid = (channel_high + channel_low) / 2
# ATR
tr = np.maximum(high[–ATR_PERIOD:] – low[–ATR_PERIOD:],
np.abs(high[–ATR_PERIOD:] – close[–ATR_PERIOD–1:–1]))
atr = np.mean(tr)
current_price = close[–1]
current_pos = position.pos_long – position.pos_short
# ============ 突破检测 ============
if current_pos == 0 and waiting_pullback == 0:
# 上突破
if current_price > channel_high:
breakout_high = current_price
breakout_low = channel_mid
waiting_pullback = 1
print(f"\\n[上突破] 等待回踩 目标={breakout_low + (breakout_high–breakout_low)*PULLBACK_RATIO:.2f}")
# 下突破
elif current_price < channel_low:
breakout_high = channel_mid
breakout_low = current_price
waiting_pullback = –1
print(f"\\n[下突破] 等待回踩 目标={breakout_high – (breakout_high–breakout_low)*PULLBACK_RATIO:.2f}")
# ============ 回踩入场 ============
if waiting_pullback == 1 and current_pos == 0:
pullback_target = breakout_low + (breakout_high – breakout_low) * PULLBACK_RATIO
if current_price <= pullback_target:
target_pos.set_target_volume(LOTS)
entry_price = current_price
stop_loss = breakout_low – atr
waiting_pullback = 0
print(f"\\n[回踩做多] 价格={current_price:.2f} 止损={stop_loss:.2f}")
elif waiting_pullback == –1 and current_pos == 0:
pullback_target = breakout_high – (breakout_high – breakout_low) * PULLBACK_RATIO
if current_price >= pullback_target:
target_pos.set_target_volume(–LOTS)
entry_price = current_price
stop_loss = breakout_high + atr
waiting_pullback = 0
print(f"\\n[回踩做空] 价格={current_price:.2f} 止损={stop_loss:.2f}")
# ============ 止损检查 ============
if current_pos > 0 and current_price < stop_loss:
target_pos.set_target_volume(0)
print(f"\\n[止损平多]")
elif current_pos < 0 and current_price > stop_loss:
target_pos.set_target_volume(0)
print(f"\\n[止损平空]")
# 超时取消等待
if waiting_pullback != 0:
# 简化:价格远离突破点则取消
if waiting_pullback == 1 and current_price > breakout_high * 1.02:
waiting_pullback = 0
print("\\n[取消等待] 价格过高")
elif waiting_pullback == –1 and current_price < breakout_low * 0.98:
waiting_pullback = 0
print("\\n[取消等待] 价格过低")
status = "等待回踩" if waiting_pullback != 0 else "监控中"
print(f"\\r价格={current_price:.2f} 通道=[{channel_low:.2f}, {channel_high:.2f}] "
f"状态={status} 持仓={current_pos}", end="")
六、风险控制
6.1 黄金交易特点
| 波动温和 | 日波幅约1% | 可用较大仓位 |
| 趋势性强 | 趋势持续时间长 | 趋势跟踪有效 |
| 夜盘活跃 | 与伦敦金联动 | 关注夜盘 |
| 避险属性 | 危机时上涨 | 注意事件 |
6.2 仓位建议
| 30万 | 1手 | <20% |
| 60万 | 1-2手 | <20% |
| 100万 | 2-3手 | <20% |
七、总结
| 品种特点 | 避险资产、趋势性强、波动温和 |
| 合约价值 | 约55万元/手(按550元/克) |
| 适合策略 | 趋势跟踪、突破回踩 |
| 止损设置 | 2-3倍ATR |
| 关注因素 | 美元、美联储、地缘政治 |
| 交易时段 | 夜盘与伦敦金联动 |
免责声明:本文仅供学习交流使用,不构成任何投资建议。期货交易有风险,入市需谨慎。
更多资源:
- 天勤量化官网:https://www.shinnytech.com
- GitHub开源地址:https://github.com/shinnytech/tqsdk-python
- 官方文档:https://doc.shinnytech.com/tqsdk/latest



