策略思路:传统网格策略需要设定参数为网格间距、仓位权重。

相当于把收盘价分成数个网格、价格移动到下个网格则成交。

传统网格策略需提前设置格子数量、若价格走到无格子的位置时则不产生交易。

本文主要参考网格策略的思想,取消格子数量限制,选用日内Tick级别高频数据,专注于下单策略及成交情况。

引入必要库、读取数据(可以使用Tick级别、分钟级别,不支持日级别)

import pandas as pd
import warnings
import datetime
import numpy as np
from pyecharts import options as opts
from pyecharts.globals import ThemeType
from pyecharts.charts import Kline, Line,Grid,Scatterdata = pd.read_csv('你的数据源.csv')
data.index = data['tradetime']# 打上时间标签为后续记录做准备
data['time'] = data.index.map(lambda x: x.time())

初始化必要参数、可以将后续代码设置为函数

# 设置买买双边报单价格
sell_price = data['close'][0]*1.01
buy_price = data['close'][0]*0.99# 记录每日最初股票持仓、现金持仓
s_inday = 5000
cash_inday = 1000000# 记录实时股票持仓、
s = s_inday
c = cash_inday# 初始化卖单买单记录
sell = []
buy = []

遍历所有数据,记录交易情况,网格间距为1%

# 最后一个时点要做平仓、循环时不遍历
for i in range(0, len(data)-1):# 假设时点的最高价>卖单报价,且有足够股票持仓则卖单成交      if ((data['high'][i]>sell_price) & (s_inday > 200)):# 记录成交时点、报单成交价格、成交数量sell.append([data.index[i], sell_price.round(2), 200])# 更新当日可出售股票持仓记录、全部股票持仓、现金持仓记录s_inday -= 200s -= 200c += 200*data['close'][i]*0.998# 重置双边报价buy_price = sell_price *0.99sell_price = sell_price*1.01# 假设时点的最低价<卖单报价,且有足够现金持仓则买单成交elif ((data['low'][i]<buy_price) & (cash_inday > data.close[i]*200)):# 记录成交时点、报单成交价格、成交数量buy.append([data.index[i], buy_price.round(2),200])# 更新当日可用于购买现金持仓记录、全部股票持仓、现金持仓记录cash_inday -= data.close[i]*200c -= data.close[i]*200s += 200# 重置双边报价sell_price = buy_price*1.01buy_price = buy_price*0.99# 每日15:00确定次日可用股票、及现金持仓 if data['time'][i]==datetime.time(15, 0):s_inday =scash_inday =c

平仓、数据整理

# 循环结束后平仓
if len(sell) - len(buy)> 0:buy.append([data.index[-1], data['close'][-1],(len(sell) - len(buy))*200])
elif len(sell) - len(buy)< 0:sell.append([data.index[-1], data['close'][-1],(len(buy) - len(sell))*200])# 整理数据
sell = pd.DataFrame(sell,columns = ['卖出时间','卖出价格', '卖出数量'])
sell.index = sell['卖出时间']
buy = pd.DataFrame(buy,columns = ['买入时间','买入价格', '买入数量'])
buy.index = buy['买入时间']
data = data.join(sell[['卖出价格', '卖出数量']])
data = data.join(buy[['买入价格', '买入数量']])

绘图查看买点卖点

data_plot = data
ochl = data_plot[['open','close','low','high']]
k = [ochl.iloc[i].tolist() for i in range(len(ochl))]# K线图
K = (Kline().add_xaxis(data_plot.index.tolist()).add_yaxis("kline",k).set_global_opts(yaxis_opts=opts.AxisOpts(is_scale=True),xaxis_opts=opts.AxisOpts(is_scale=True),title_opts=opts.TitleOpts(title="网格交易策略"),datazoom_opts=[opts.DataZoomOpts(type_='inside')]))#买点卖点散点图
S_ = (Scatter().add_xaxis(data_plot.index.tolist()).add_yaxis("卖出",data_plot['卖出价格'].tolist()).add_yaxis("买入",data_plot['买入价格'].tolist()).set_global_opts(yaxis_opts=opts.AxisOpts(is_scale=True),xaxis_opts=opts.AxisOpts(is_scale=True),datazoom_opts=[opts.DataZoomOpts(type_='inside')]))K.overlap(S_) #将均线叠加到K线上
K.render_notebook()

整理数据查看盈利情况

data = data.fillna(0)
data['敞口'] = (data['买入数量'].cumsum()-data['卖出数量'].cumsum())
data['实现盈利'] = (data['卖出数量']*data['卖出价格']).cumsum()*0.998-(data['买入数量']*data['买入价格']).cumsum()
data['净值'] = (data['敞口']+5000)*data['close']+(data['实现盈利']+1000000)
data['净值'] = data['净值'].round(2)
data['净值'][-1]-data['净值'][0]
# 输出289001.5

绘图查看净值变化、股价变化

# 用了一年的Tick级别数据回测,为方便展示做了数据降频
df = data[['close','净值']].resample('1D').last()
df = df.dropna()L_ = (# 换个可爱的风格 :DLine(init_opts=opts.InitOpts(theme=ThemeType.MACARONS, width='900px', height='500px')).add_xaxis(df.index.tolist()).add_yaxis("收盘价",df['close'].tolist(),yaxis_index=1).add_yaxis("净值",df['净值'].tolist()).extend_axis(yaxis=opts.AxisOpts(axislabel_opts=opts.LabelOpts(formatter="{value}元")))  # 添加一条蓝色的y轴.set_global_opts(yaxis_opts=opts.AxisOpts(is_scale=True),xaxis_opts=opts.AxisOpts(is_scale=True),datazoom_opts=[opts.DataZoomOpts(type_='inside')]))L_.render_notebook()

网格策略受单边行情影响严重、可以看出策略运行一段时间后就没有再发生交易、由于敞口原因与股价呈现同比波动。最后能得到正盈利主要是因为回测区间的整体涨跌幅度不大。

考虑到上述情况、可以采取按一定周期(每月、每周)平仓并重新开始策略的方案:

将之前的计算过程封装入函数

def grid_strategy(data):sell_price = data['close'][0]*1.01buy_price = data['close'][0]*0.99# 记录每日开盘持有股票、现金的初始值s_inday = 10000cash_inday = 10000000s = s_indayc = cash_indaysell = []buy = []for i in range(0, len(data)-1):        if ((data['high'][i]>sell_price) & (s_inday > 200)):sell.append([data.index[i], sell_price.round(2), 200])s_inday -= 200s -= 200c += 200*data['close'][i]*0.998buy_price = sell_price *0.99sell_price = sell_price*1.01elif ((data['low'][i]<buy_price) & (cash_inday > data.close[i]*200)):buy.append([data.index[i], buy_price.round(2),200])cash_inday -= data.close[i]*200c -= data.close[i]*200s += 200sell_price = buy_price*1.01buy_price = buy_price*0.99if data['time'][i]==datetime.time(15, 0):s_inday =scash_inday =c# 循环结束后平仓if len(sell) - len(buy)> 0:buy.append([data.index[-1], data['close'][-1],(len(sell) - len(buy))*200])elif len(sell) - len(buy)< 0:sell.append([data.index[-1], data['close'][-1],(len(buy) - len(sell))*200])# 整理数据sell = pd.DataFrame(sell,columns = ['卖出时间','卖出价格', '卖出数量'])sell.index = sell['卖出时间']buy = pd.DataFrame(buy,columns = ['买入时间','买入价格', '买入数量'])buy.index = buy['买入时间']data = data.join(sell[['卖出价格', '卖出数量']])data = data.join(buy[['买入价格', '买入数量']])profit = (sell['卖出价格'] * sell['卖出数量']).sum() - (buy['买入价格'] * buy['买入数量']).sum()fee = (sell['卖出价格'] * sell['卖出数量']).sum() * 0.002net_profit = profit - feereturn data

重新整理数据、并打上月份标签

data = pd.read_csv('你的数据源.csv')
data.index = data['tradetime']
data['time'] = data.index.map(lambda x: x.time())
data['month'] = data.index.map(lambda x: x.strftime('%Y.%m'))

利用循环跑出计算结果

也可以将盈亏计算过程写入函数、返回值改为区间盈亏

使用pandas 分组聚合的方式来计算: data.groupby('month').apply(grid_strategy)

results = pd.DataFrame()
for month in data['month'].unique():df = data[(data['month']==month)]result = grid_strategy(df)results = pd.concat([results, result])

整理并画图、此处排除持仓影响、专注于净盈亏

data = results.fillna(0)
data['敞口'] = (data['买入数量'].cumsum()-data['卖出数量'].cumsum())
data['实现盈利'] = (data['卖出数量']*data['卖出价格']).cumsum()*0.998-(data['买入数量']*data['买入价格']).cumsum()
data['净盈亏'] = (data['敞口'])*data['close']+(data['实现盈利'])
data['净盈亏'] = data['净盈亏'].round(2)
data['净盈亏'][-1]-data['净盈亏'][0]
# 输出-65330.16df = data[['close','净盈亏']].resample('1D').last()
df = df.dropna()L_ = (Line(init_opts=opts.InitOpts(theme=ThemeType.MACARONS, width='900px', height='500px')).add_xaxis(df.index.tolist()).add_yaxis("收盘价",df['close'].tolist(),yaxis_index=1).add_yaxis("净值",df['净盈亏'].tolist()).extend_axis(yaxis=opts.AxisOpts(axislabel_opts=opts.LabelOpts(formatter="{value}元")))  # 添加一条蓝色的y轴.set_global_opts(yaxis_opts=opts.AxisOpts(is_scale=True),xaxis_opts=opts.AxisOpts(is_scale=True),title_opts=opts.TitleOpts(title="网格交易策略--净盈亏、股价变化情况"),datazoom_opts=[opts.DataZoomOpts(type_='inside')]))L_.render_notebook()

可以看出震荡行情时表现良好、单边行情时不适用

最后附上DolphinDB API代码,选用逐笔成交聚合成3秒K线的方法

symbol = '688001'
起始日期 = '2022.01.01'
截止日期 = '2022.12.31'script = '''
select tradetime, open, high, low, close
from (select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume
from (select symbol, TradingTime, TradeVolume as volume, TradePrice as price
from loadTable("dfs://CSMAR_SEL2_TRANSACTION_H", 'data')
where Symbol in ['{}'],
tradingdate between {}:{},
tradingtime.minute() between 09:30m:15:01m)
group by symbol, dailyAlignedBar(TradingTime, 09:30:00.000, 3*1000) as Tradetime)
'''.format(str(symbol), 起始日期, 截止日期)
x = s.run(script)
x.index =x['tradetime']
data = x

【Python】 网格策略回测(日内高频数据)相关推荐

  1. python 量化策略回测_在python中创建和回测对交易策略

    python 量化策略回测 Pairs trading is one of the many mean-reversion strategies. It is considered non-direc ...

  2. Excel-VBA 股票网格交易策略回测

    大家好,我是陈小虾,是一名自动化方向的IT民工.写博客是为了记录自己的学习过程,通过不断输出倒逼自己加速成长.功能说明:由于水平有限,博客中难免会出现一些BUG,或者有更优方案恳请各位大佬不吝赐教!微 ...

  3. A股 港股 美股策略回测 RSI KDJ EMA 美股行情 美股数据 通达信转python

    https://download.csdn.net/download/repay3/16460847 A股 港股 K线数据 https://download.csdn.net/download/rep ...

  4. Python双均线策略回测(2021-10-12)

    Python双均线策略回测 1.择时策略简介 根据百度百科的解释,择时交易是指利用某种方法来判断大势的走势情况,是上涨还是下跌或者是盘整.如果判断是上涨,则买入持有:如果判断是下跌,则卖出清仓,如果是 ...

  5. 可转债网格交易策略回测

    什么是网格交易策略:基于股票波动高抛低吸策略,自动化反复买卖赚取差价.投资者借助条件单,把资金分成多份,从基准价开始,每跌x%就自动买入一份,每涨y%就自动卖掉一份.股价越波动高抛低吸的机会越多 什么 ...

  6. python 策略回测期货_量化投资实战教程(1)—基于backtrader的简单买入卖出策略

    都说Python可以用于量化投资,但是很多人都不知道该怎么做,甚至觉得是非常高深的知识,其实并非如此,任何人都可以在只有一点Python的基础上回测一个简单的策略. Backtrader是一个基于Py ...

  7. python 股票回测书籍推荐_python实现马丁策略回测3000只股票

    python实现马丁策略回测3000只股票 批量爬取股票数据 这里爬取数据继续使用tushare,根据股票代码来遍历,因为爬取数据需要一定时间,不妨使用多线程来爬取,这里要注意tushare规定每分钟 ...

  8. 【邢不行|量化小讲堂系列56-实战篇】量化策略回测表现好,但实盘却很差?可能是底层数据就错啦!

    引言: 邢不行的系列帖子"量化小讲堂",通过实际案例教初学者使用python进行量化投资,了解行业研究方向,希望能对大家有帮助. [历史文章汇总]请点击此处 [必读文章] [邢不行 ...

  9. 我想用python写一个股票交易策略回测软件,请给出框架及步骤等建议

    当然,我很愿意为您提供关于使用 Python 写股票交易策略回测软件的建议.以下是一般的步骤和框架: 数据获取:首先,您需要获取所需的历史股票数据.您可以使用各种数据源,例如 Yahoo Financ ...

最新文章

  1. Linux2.6--Linus电梯
  2. 今晚直播 | 强化学习在比赛和自动机器学习中的应用简析
  3. 从输入网址到网页显示过程
  4. 后台系统可扩展性学习笔记(五)负载均衡
  5. 《scikit-learn》交叉验证
  6. SensorManager
  7. Chrome OS 开发者版现可备份和恢复 Linux 容器
  8. MyBatis和Spring总结
  9. 企业版微信公众号从零开始之二(申请认证流程)
  10. echarts图表应用
  11. 达梦数据库授权到期替换key文件
  12. Mask R-CNN网络详解
  13. 赵小楼《天道》《遥远的救世主》深度解析(35)你觉得叶晓明、冯世杰、刘冰是底层吗?
  14. Codeforces Round #521 (Div. 3) B. Disturbed People 思维
  15. 嵌入式--深入理解单片机(一)单片机程序是如何运行起来的以及单片机的ROM和RAM
  16. 软考成绩什么时候出来?
  17. java poi 水印_JAVA不使用POI给Word文档添加水印
  18. input标签能换行么?textarea标签属性
  19. 数据分析师对年龄有限制吗,是不是靠青春吃饭?
  20. 如何使用计算机处理文件,如何设置电脑自动清理文件

热门文章

  1. Atitit 职业资格证书分类等级 目录 1. 等级 :初级(五级)、中级(四级)、高级(三级)、技师(二级)和高级技师(一级)。 1 2. 折叠分类 2 2.1. 生产、运输设备操作人员 2 2
  2. 嵌入式软件开发工程师求职要求
  3. Linux查找目录或文件
  4. Intel仿人类大脑研发“神经元”芯片,可以解读人的喜怒哀乐
  5. Chia官方矿池测试版正式上线!?
  6. 给tensor增加维度 或 减少维度
  7. CSS笔记(CSS禅意花园+CSS揭秘)
  8. 大公司研发部门普遍存在的问题(日常吐槽)
  9. 全面理解-Flutter(万字长文,【性能优化实战】
  10. subprocess用法,官方文档