前言
在之前两篇文章中涉及价格突破策略,策略经过优化表现任然差劲,本次策略基于价格突破策略的变种版本。
策略思想
指标
使用SMA和收盘价
买入信号
价格连续下跌N根k线
订单
交易价格:昨日收盘价*(1 - C)
止损价格: 交易价格*(1 - L)
止盈价格:交易价格*(1 + S)
交易量:min(可用资金/ SMA,交易量)
回测结果
参数
callback=0.01, # 价格回调比例
period=133, #周期
down_day=6, # 连续下跌次数
stop_loss=133, # 止损比例
take_profit=0.15, # 止盈比例
回测 | Value |
---|---|
初始资金 | 10000 |
期货品种 | ETH |
时间级别 | 1H |
回测时间 | 2017.7.15 - 2022.7.24 |
倍数 | 1 |
手续费 | 1% |
期末资金 | 51469 |
优化参数
参数
rate: 330.97757651248696
‘callback’: 0.070537109375,
‘period’: 164.4775390625,
‘down_day’: 3.427734375,
‘stop_loss’: 0.16975097656250002,
‘take_profit’: 0.07980957031250001
部分调优参数
回测 | Value |
---|---|
初始资金 | 10000 |
期货品种 | ETH |
时间级别 | 1H |
回测时间 | 2017.7.15 - 2022.7.24 |
倍数 | 1 |
手续费 | 1% |
总盈利 | 3309775 |
![]() |
核心代码
加载数据
def load_csv_data(data_path, size=None, start=None, end=None):
return bt.feeds.GenericCSVData(
dataname=data_path,
nullvalue=0.0,
fromdate=start,
todate=end,
dtformat="%Y-%m-%d %H:%M:%S",
timeframe=bt.TimeFrame.Minutes,
datetime=0,
high=1,
low=2,
open=3,
close=4,
volume=5,
openinterest=-1
)
def create_cerebro(cash=10000.0, commission=0.01, stake=1, strategy=None):
"""
:param data: 数据
:param cash: 初始资金
:param commission: 佣金率
:param stake: 交易单位大小
:param strategy: 交易策略
:return:
"""
cerebro = bt.Cerebro()
# 设置启动资金
cerebro.broker.setcash(cash)
# 设置交易单位大小
cerebro.addsizer(bt.sizers.FixedSize, stake=stake)
# 设置佣金率为千分之一
cerebro.broker.setcommission(commission)
# 显示回测过程中的买入和卖出信号
cerebro.addobserver(bt.observers.Value)
# 显示了回测过程中的买入和卖出信号
cerebro.addobserver(bt.observers.BuySell)
return cerebro
策略
import datetime
import optunity
from backtrader import Strategy, Cerebro
import backtrader as bt
from handle import create_cerebro
from utils import load_csv_data
"""
突破策略 版本2
"""
def add_continuous_decline_strategy(c: Cerebro, params=None):
"""
设置策略参数
:param c:
:param params:
:return:
"""
if params is None:
return c.addstrategy(ContinuousDeclineStrategy)
c.addstrategy(ContinuousDeclineStrategy,
callback=params['callback'],
period=int(params['period']),
down_day=int(params['down_day']),
stop_loss=params['stop_loss'],
take_profit=params['take_profit'])
return c
class ContinuousDeclineStrategy(Strategy):
"""
突破策略
买入: 价格连续上涨n天,最后一天价格上涨幅度3%,收盘价格在 sma上
盈库比 止盈率设置为10%,止损率设置为5%
价格回调 2%
"""
params = dict(
callback=0.01, # 价格回调比例
period=133,
up_days=6, # 连续上涨天数
stop_loss=0.15, # 止损比例
take_profit=0.15, # 止盈比例
limdays=3,
limdays2=1000,
hold=10,
)
def __init__(self):
self.holdstart = None
self.dataclose = self.datas[0].close
self.sma = bt.ind.SMA(period=self.p.period, plot=False)
self.order_list = list()
def next(self):
if self.order_list: # order列表,用于存储尚未执行完成的订单
return # 有尚未执行的订单
# 尚未进场
if not self.position:
# 获取近几日收盘价用于判断是否连续上涨
last_closes = list()
for i in range(self.p.up_days + 1):
last_closes.append(self.dataclose[-i])
# 连续N日下跌
if last_closes == sorted(last_closes, reverse=True):
close = self.dataclose[0]
p1 = close * (1.0 - self.p.callback)
p2 = p1 - self.p.stop_loss * close
p3 = p1 + self.p.take_profit * close
# 计算订单有效期
valid1 = datetime.timedelta(self.p.limdays)
valid2 = valid3 = datetime.timedelta(self.p.limdays2)
size = min(self.broker.getcash() / self.sma[0], self.data.volume[0])
# 使用bracket orders设置买入卖出
if size == 0:
size = 1
os = self.buy_bracket(size=size,
price=p1,
valid=valid1,
stopprice=p2,
stopargs=dict(valid=valid2),
limitprice=p3,
limitargs=dict(valid=valid3), )
# 保存激活的的订单
self.orefs = [o.ref for o in os]
"""
优化器(加群获取 2762383426)
......
"""
运行策略
if __name__ == '__main__':
path = "D:\\work\\git\\Tools\\static\\data\\ETHUSDT_1h.csv"
data = load_csv_data(path)
cerebro = create_cerebro()
cerebro.adddata(data)
cerebro.addstrategy(ContinuousDeclineStrategy)
cerebro.run()
cerebro.plot()
使用优化器
if __name__ == '__main__':
path = "D:\\work\\git\\Tools\\static\\data\\ETHUSDT_1h.csv"
data = load_csv_data(path)
op = ContinuousDeclineStrategyOptimizer()
op.set_data(data)
op.set_event_num(500)
op.run()
params = op.get_optimal_parameters()
cerebro = create_cerebro()
cerebro.adddata(data)
add_continuous_decline_strategy(cerebro,params)
cerebro.run()
cerebro.plot()
总结
目前从回测结果来看,该策略表现优异,可持续性盈利。未来10年,实现财富自由,加油!!!!