龙头战法之掘金量化实盘版
声明:本文只用于量化研究交流,不作为投资依据,如导致经济损失,本作者概不负责!
龙头战法是量化投资中的经典战法,而结合了情绪周期的龙头战法,则是在情绪冰点或情绪转折点时进行买入,不继续封住涨停板果断卖出。将交易风险控制在最低,将利润最大化,很好的体现了量化投资中的“截断亏损,让利润奔跑”原则。
本策略基于聚宽社区里的公开源码策略龙头战法,聚宽版原始策略可参考文章《龙头战法聚宽版》。在此代码基础上保留情绪周期核心思想,进行修改才有了这个实盘版策略。原始策略为聚宽平台,属于tick级别的策略。然而由于聚宽实盘版本一创聚宽并不支持tick信号(tick信号珍贵,好多平台不会免费支持),导致本策略只能回测及模拟,无法实盘自动化交易。
为了解决实盘及追涨停买入难问题,有了该掘金实盘版本。但本策略绝不是简单的对原策略进行实盘化,而是在实盘化的同时,加入了自己的一些思考和对原策略某些问题的修正。
各个版本的修改内容代码中进行了详细注释,主要的改进如下
基于掘金量化平台将该策略进行了实盘化,同时作者也已经实盘交易了一个多月,针对实盘中出现的问题都进行了修复,是一个真正经受过实盘考验的策略。
掘金量化平台最大的优势就是免费支持tick信号,而且本地化部署程序,可以非常方便的调试。但数据API远没有聚宽平台友好易用。所以作者将聚宽的数据SDK进行了整合,完美实现了两者融合。
加入实时仓位控制,减少交易风险。
增加流通盘大小一系列实战经验指标
针对追击涨停无法买入情况,本策略给出了一个较为理想的解决方案。
详细的代码注释,利于研究学习该策略思路
由于掘金量化平台只支持3个月的tick数据,所以这里只能贴出3个月的回测结果。
一月份开始实盘收益情况如下图。
二月份自己手贱,手工介入买了两只策略没买的股,结果栽进去了,不具实际参考意义。但同时也告诉我们了量化的意义,很大一部分就是避免人为主观情绪影响导致的损失。
试读源码
# 标题:龙头战法
# author:张连重
# version 1.1.0
# date: 20201219 21:24
# description: 开盘追涨龙头,基于聚宽策略做掘金的实盘实现,整合聚宽数据SDK和掘金交易SDK
# version 1.12.0
# date: 20210101 10:24
# description: 改为集合竞价追涨龙头,加大筹码买入概率
# version 1.3.0
# date: 20210105 19:30
# description: 修改买入条件,修改卖出止损点,降低买入风险,减小收益回撤
# version 1.4.0
# date: 20210106 19:30
# description: 加入实时仓位控制
# version 1.5.0
# date: 20210108 19:49
# description: 集合竞价以涨停价申报,预期以开盘价买入.集合竞价抢筹
# version 1.6.0
# date: 20210110 18:00
# description: 盘前统计涨停连板次数,对于已经持仓的不再作为青睐对象
# version 1.7.0
# date: 20210112 13:00
# description: 修改情绪周期指标
# version 1.8.0
# date: 20210119 18:20
# description: 空仓状态下,市场赚钱效益良好时,追涨趋势良好个股,避免空仓
# version 1.9.0
# date: 20210120 12:30
# description: 修复今日突然停牌,集合竞价数据为空导致的异常
# version 2.0.0
# date: 20210126 18:28
# description: 情绪周期,修改空仓状态下情绪高涨判断逻辑
# version 2.1.0
# date: 20210127 12:28
# description: 集合竞价加入买一 卖一数量 buy_volumn >= sell_volumn*0.85
# version 2.2.0
# date: 20210127 22:13
# description:
# 1.检测持仓 10点时没有封住减仓一半
# 2.基于流通市值剔除不易持续涨停的股
# version 2.3.0
# date: 20210201 01:00
# description:
# 1.剔除流通市值大于150的
# 2.流通市值在100亿到150亿之间,加入待观察股
# 导入函数库
from gm.api import *
from datetime import datetime
import pandas as pd
from jqdatasdk import *
import numpy as np
import time
import random
from decimal import Decimal, Context, ROUND_HALF_UP,ROUND_DOWN
# jqdata login 需填入在聚宽平台的个人账号用于授权
auth('15520768082','ZXXXXXXX')
# 初始化函数,设定基准等等
def init(context):
context.security = [] #存放聚宽股票代码
context.security_stock_juejin = [] #存放掘金股票代码
context.security_observe = [] #待观察股票
context.sell_list = []
context.small_cyc = 3
context.small_cyc_befor = 3
context.big_cyc = 3
context.big_cyc_befor = 3
context.limit_stocks = []
context.summary_call_auction_askp1_data = {} #集合竞价卖一价格数据
context.summary_call_auction_askbuy_volume_data = {} #集合竞价买一卖一数量数据
context.black_stock_code = [] ##交易黑名单列表,防止意外卖出 如:['SZSE.002714','SZSE.300498']
context.call_auction_orderedlist = [] #集合竞价已买入清单
context.org_tick = {} # 原始tick数据
context.smoothed_tick = {} #平滑过后的tick数据
context.limit_up_summary = pd.DataFrame(columns = ["股票代码掘金","股票代码聚宽","股票名称","昨日涨停高度","昨日收盘价"]) # 涨停数统计
context.limit_up_summary.set_index(["股票代码掘金"], inplace=True)
add_parameter(key='small_cyc_befor', value=context.small_cyc_befor, min=1, max=20, name='samll cycle before', intro='昨日情绪小周期', group='emotioncyle', readonly=False)
add_parameter(key='big_cyc_befor', value=context.big_cyc_befor, min=1, max=20, name='big cycle before', intro='昨日情绪大周期', group='emotioncyle', readonly=False)
add_parameter(key='small_cyc', value=context.small_cyc, min=1, max=20, name='samll cycle', intro='情绪小周期', group='emotioncyle', readonly=False)
add_parameter(key='big_cyc', value=context.big_cyc, min=1, max=20, name='big cycle', intro='情绪大周期', group='emotioncyle', readonly=False)
# 开盘前运行
schedule(schedule_func=before_market_open, date_rule='1d', time_rule='09:00:00')
# 集合竞价尾期运行
schedule(schedule_func=analyse_call_auction, date_rule='1d', time_rule='09:24:44')
# 开盘时运行
schedule(schedule_func=market_open, date_rule='1d', time_rule='09:30:00')
# 收盘后运行
schedule(schedule_func=after_market_close, date_rule='1d', time_rule='15:01:00')
## 盘中运行函数
# 1、开盘后没封住,跌幅超过%5,盘中卖出
# 2、快收盘时,没封住涨停,盘中卖出
# 3、仓位控制,根据涨停数决定当日仓位
def on_bar(context, bars):
monitor_in_market(context,bars)
monitor_still_limit(context,bars)
realtime_position_controll(context,bars)
# 每个订阅的股票有数据,都会推送一次
def on_tick(context, tick):
##获取所订阅的股票集合竞价期间的tick数据
current_time = context.now.strftime("%H:%M:%S")
today = context.now.strftime("%Y-%m-%d")
if context.now.strftime("%H:%M:%S") >= '09:15:00' and context.now.strftime("%H:%M:%S") < '09:24:44':
源码完全公开,不带有任何加密接口。详细完整源码如下。顺便强调一下,过往效果不代表未来一直有效,投资肯定是一个有风险的事情,实盘需谨慎。实盘可参考掘金量化实盘指导。
详细完整源码已在码云上公开,感兴趣的可以自行下载,地址如下,欢迎更多有能力有想法的朋友参与进来,继续优化!
https://gitee.com/zhanglianzhong/TrackLeader.git
量化交易交流群,欢迎加入,一起用技术实现财富自由