您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# My语言怎么实现SAR量化交易策略
## 一、SAR指标原理与交易逻辑
### 1.1 SAR指标数学定义
抛物线转向指标(Stop and Reverse, SAR)由J. Welles Wilder Jr.在1978年提出,其核心计算公式为:
SAR(n) = SAR(n-1) + AF × (EP - SAR(n-1))
其中:
- AF(加速因子)通常从0.02开始,每创新高/新低增加0.02,最大不超过0.2
- EP(极值点)是多头期间的最高价或空头期间的最低价
### 1.2 交易信号生成规则
1. **多头信号**:当价格从下向上突破SAR值时
2. **空头信号**:当价格从上向下跌破SAR值时
3. **止损机制**:SAR值本身作为动态止损点
## 二、My语言环境配置
### 2.1 开发环境准备
```python
# My语言量化平台基础配置
import myquant as mq
mq.set_backtest(
capital=100000,
commission=0.0003,
slippage=0.001
)
# 获取沪深300指数数据
data = mq.get_history(
symbol='000300.SH',
frequency='1d',
fields=['open','high','low','close'],
start_date='20200101',
end_date='20231231'
)
def calculate_sar(data, af_start=0.02, af_step=0.02, af_max=0.2):
"""
SAR指标计算函数
:param data: 包含OHLC的DataFrame
:param af_start: 初始加速因子
:param af_step: 加速因子步长
:param af_max: 最大加速因子
:return: 添加SAR列的DataFrame
"""
high = data['high'].values
low = data['low'].values
close = data['close'].values
sar = np.zeros(len(close))
trend = np.zeros(len(close), dtype=int)
ep = np.zeros(len(close))
af = np.zeros(len(close))
# 初始化前两日值
sar[0:2] = close[0:2]
trend[0:2] = 1
ep[0:2] = high[0:2]
af[0:2] = af_start
for i in range(2, len(close)):
# 趋势延续处理
if trend[i-1] == 1:
sar[i] = sar[i-1] + af[i-1] * (ep[i-1] - sar[i-1])
if low[i] < sar[i]:
trend[i] = -1
sar[i] = ep[i-1]
ep[i] = low[i]
af[i] = af_start
else:
trend[i] = 1
if high[i] > ep[i-1]:
ep[i] = high[i]
af[i] = min(af[i-1] + af_step, af_max)
else:
ep[i] = ep[i-1]
af[i] = af[i-1]
else:
sar[i] = sar[i-1] + af[i-1] * (ep[i-1] - sar[i-1])
if high[i] > sar[i]:
trend[i] = 1
sar[i] = ep[i-1]
ep[i] = high[i]
af[i] = af_start
else:
trend[i] = -1
if low[i] < ep[i-1]:
ep[i] = low[i]
af[i] = min(af[i-1] + af_step, af_max)
else:
ep[i] = ep[i-1]
af[i] = af[i-1]
# 价格跳空处理
if trend[i] == 1:
sar[i] = min(sar[i], low[i-1], low[i-2])
else:
sar[i] = max(sar[i], high[i-1], high[i-2])
data['SAR'] = sar
data['Trend'] = trend
return data
def generate_signals(data):
signals = []
position = 0 # 0:无持仓, 1:多头, -1:空头
for i in range(1, len(data)):
current_close = data['close'].iloc[i]
prev_sar = data['SAR'].iloc[i-1]
current_sar = data['SAR'].iloc[i]
# 多头信号
if position <= 0 and current_close > prev_sar:
signals.append(1)
position = 1
# 空头信号
elif position >= 0 and current_close < prev_sar:
signals.append(-1)
position = -1
else:
signals.append(0)
data['Signal'] = signals + [0] # 补齐最后一日
return data
def backtest(data):
returns = []
position = 0
entry_price = 0
for i in range(len(data)):
signal = data['Signal'].iloc[i]
close = data['close'].iloc[i]
if signal == 1 and position != 1:
if position == -1:
# 空头平仓
returns.append((entry_price - close)/entry_price)
# 开多头
position = 1
entry_price = close
elif signal == -1 and position != -1:
if position == 1:
# 多头平仓
returns.append((close - entry_price)/entry_price)
# 开空头
position = -1
entry_price = close
# 计算累计收益
cumulative_returns = np.cumprod([1 + r for r in returns])
return cumulative_returns
def optimize_parameters(data):
af_range = np.arange(0.01, 0.05, 0.01)
max_af_range = np.arange(0.15, 0.25, 0.05)
best_sharpe = -np.inf
best_params = {}
for af in af_range:
for max_af in max_af_range:
temp_data = calculate_sar(data.copy(), af_start=af, af_max=max_af)
temp_data = generate_signals(temp_data)
returns = backtest(temp_data)
if len(returns) > 0:
sharpe = np.mean(returns)/np.std(returns) * np.sqrt(252)
if sharpe > best_sharpe:
best_sharpe = sharpe
best_params = {'af_start': af, 'af_max': max_af}
return best_params
class SAR_Trader:
def __init__(self, af_start=0.02, af_max=0.2):
self.af_start = af_start
self.af_max = af_max
self.prev_data = None
def process_tick(self, new_tick):
if self.prev_data is None:
self.prev_data = new_tick
return 0
# 合成最新K线
current_bar = {
'high': max(self.prev_data['high'], new_tick['price']),
'low': min(self.prev_data['low'], new_tick['price']),
'close': new_tick['price']
}
# 计算SAR值
sar_value = self.calculate_sar(current_bar)
# 生成交易信号
if new_tick['price'] > sar_value:
return 1 # 买入信号
elif new_tick['price'] < sar_value:
return -1 # 卖出信号
return 0
def risk_management(position, portfolio, max_drawdown=0.2):
current_value = portfolio['cash'] + portfolio['position_value']
peak_value = max(portfolio['peak_value'], current_value)
drawdown = (peak_value - current_value)/peak_value
if drawdown > max_drawdown:
# 触发风控平仓
if position > 0:
return -1 # 平多
elif position < 0:
return 1 # 平空
return 0
指标名称 | 计算公式 | 达标阈值 |
---|---|---|
年化收益率 | (最终价值/初始价值)^(252/天数)-1 | >15% |
最大回撤 | Max(峰值-谷值)/峰值 | <30% |
胜率 | 盈利交易数/总交易数 | >55% |
盈亏比 | 平均盈利/平均亏损 | >1.5 |
注:实际应用中需注意My语言的版本差异,部分函数可能需要根据具体平台API调整实现方式。建议先在模拟盘运行至少3个月再投入实盘资金。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。