query()生成一个 query 对象

3.2万
0
2023-10-04 21:20:12
5
投币
收藏
2
主要发布:数学思维与文化、少儿编程、发明创造、《新概念英语》背诵相关视频
3317.6万播放
简介
讲完基于单均线的股票模型
00:16
record(stock_price=current_price)
00:07
画出上一时间点价格
00:12
log.info( Selling %s % (security))
00:07
剪切选择的单元格
00:07
主要给大家提供几个大范围的量化思路
00:06
本篇为第一讲,举了一个技术指标的例子
00:09
收益曲线非常可观
00:17
小结
00:05
我们这里是量化课堂的第三部分
00:08
在这里,小编提供一个同时持有股票数 N 的选择的小tips
00:13
如果想分散风险,可以多选一些股票
00:05
因为手续费是有最低限制的
00:05
但是,分到每个股票的资金最好不要少于两万
00:07
如果风险承受能力强的话可以少选一点
00:08
各位读者可以自己尝试修改参数
00:07
是不是很棒?
00:07
看看参数应该如何选取
00:06
你会发现在大部分时间里面,策略的收益比基准收益高
00:08
从2005开始回测至今
00:16
好啦,看看小编选了5个股票的回测结果吧
00:10
最大可以同时持有N只股票
00:06
用于实现这个策略的主函数可以参考回测代码块1和2
00:10
死叉了就卖出
00:05
按日进行判断和交易
00:05
哪只金叉了就买入
00:06
在交易日前,同时对多个股票进行判断
00:08
其中pi表示前一天的收盘价,且
00:08
除了改为指数移动平均线以外,小编还加入多股票实现方法
00:09
多股票
00:08
就可以轻松的在不同的参数之间来回切换,比较收益
00:08
如果写出这样的子函数,那么在主程序里面只要改一下函数输入参数
00:10
怎么样?是不是有点挑战性?
00:05
写出来没?如果没写出来的话可以参考回测代码块3和4(里面有代码和注释)
00:11
EMA 公式分析
00:31
公式简单分析
00:34
因此这可能是个有点挑战的地方
00:06
主要区别在于指数移动平均需要进行一个迭代
00:08
指数移动平均和算术平均或者加权平均
00:10
可以试一下计算指数移动平均的函数
00:06
接下来,如果你想挑战更高难度
00:07
也可以参考回测代码块5(里面有代码和注释)
00:07
各位读者可以先自己进行尝试
00:07
然后计算一个算术平均数就可以了
00:07
方法不难,获得前N天的收盘价
00:12
我想 改造一个指 数 均线呢?
00:06
我想改造一个指数均线呢?
00:06
比如说,我想对均线进行加权呢?
00:06
对一些现有的策略进行改造
00:10
有时候我们也许会根据自己的需要对一些现有的策略进行改造
00:07
还有几个股票模型的代码
00:31
当然不行
00:06
老师,可以了嘛?
00:05
直接复制粘贴就能运行,是不是很简单呢?
00:10
单均线策略讲解完毕
00:12
有关技术指标的文章,百度上一搜一大把
00:09
我们平台里也有很多相关的帖子
00:06
python公开库ta-lib里也收录了很多指标
00:09
大家想进一步研究可以实现一下
00:07
也可以结合其他选股策略
00:06
或者根据需要制订资金等分的份数或者控制仓位等方法提高策略的收益
00:12
或者根据需要制订资金 等分的份数或者控制 仓位等方法 提高策略的收益
00:06
python 公开库 ta-lib 里 也收录了很多指标
00:13
不存在万能指标。参数也很重要
00:13
主函数 思维导图
00:09
主函数 思维 导图
00:09
第一部分是 初始化函数
00:13
开盘前选择股票池
00:08
开盘后 分析数据进行卖出和买入操作
00:14
准备 克隆策略
00:08
克隆策略完成
00:28
双均线策略-py3-Clone
00:09
双均线策略-4股-2010至今
00:42
2010年开始回测数据
00:14
回测数据段设置
00:16
结束时间是 2023-9-28
00:11
资金额度 10000000
00:18
点击 运行回测 看看结果
00:09
2010年的行情
00:27
2011年的表现,不佳
00:05
2012年的表现还好
00:07
2013年的表现
00:09
2014年的表现不错
00:11
2015年的表现先扬后抑
00:07
2016年的表现比较惨
00:12
2017年的表现不错
00:08
2018年就是贸易战的年份
00:10
2019年很不错
00:08
2020年也很不错
00:09
2021年比较震荡
00:09
2022年比较糟糕
00:09
2023年也不太有利
00:10
正在进行整体交易记录的汇总计算
00:37
整体效果不佳不如前期的 单品种系统
00:18
模型表现不佳,我们分析代码
00:29
https www.joinquant.com post 1398
00:12
代码 来自 双均线 文章
00:33
网页回退,来到前期的 API 文档中
00:09
标题:【量化课堂】双均线策略
00:06
作者:JoinQuant量化课堂
00:08
双均线策略
00:05
2015-01-01 到 2016-03-08, ¥2000000, 每天
00:10
多行注释
00:07
总体回测前
00:05
总体回测前要做的事情
00:07
def initialize(context)
00:06
initialize(context)
00:22
设置策略参数
00:12
set_params()
00:08
设置中间变量
00:05
set_variables()
00:06
设置回测条件
00:05
set_backtest()
00:06
# 设置策略参数
00:08
def set_params()
00:07
调仓频率
00:07
g.tc = 15
00:12
g.tc = 15
00:09
持仓数目
00:09
g.N = 4
00:06
g.N = 4 四只股票
00:12
设置股票池
00:07
g.security = []
00:07
g.security = [] 股票代码 列表
00:14
不是连续代码。部分股票退市
00:09
事后知道已经退市
00:11
已经包含了未来数据
00:15
# 设置中间变量
00:08
def set_variables()
00:08
return 无设置,直接返回
00:07
def set_variables() - 占位函数
00:13
#设置回测条件
00:06
def set_backtest() 回测函数
00:06
用真实价格交易
00:06
set_option('use_real_price', True)
00:06
set_option('use_real_price', True) 代码分析
00:22
log.set_level('order', 'error')
00:20
每天开盘前
00:13
每天开盘前要做的事情
00:10
def before_trading_start(context)
00:08
before_trading_start(context) - contex 作为参数
00:08
set_slip_fee(context)
00:15
根据不同的时间段设置滑点与手续费
00:07
不同时期,手续费不同
00:11
通过空格分开函数
00:10
将滑点设置为0
00:05
set_slippage(FixedSlippage(0))
00:08
FixedSlippage( 0 )
00:09
set_slippage( FixedSlippage(0) )
00:14
根据不同的时间段设置手续费
00:10
dt = context.current_dt
00:10
if dt 大于 datetime.datetime(2013, 1, 1)
00:10
set_commission(PerTrade(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
00:12
PerTrade(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)
00:12
buy_cost=0.0003, sell_cost=0.0013, min_cost=5
00:13
set_commission( PerTrade(buy_cost=0.0003, sell_cost=0.0013, min_cost=5) )
00:09
elif dt datetime.datetime(2011,1, 1)
00:09
datetime.datetime(2011,1, 1)
00:11
set_commission(PerTrade(buy_cost=0.001, sell_cost=0.002, min_cost=5))
00:06
PerTrade(buy_cost=0.001, sell_cost=0.002, min_cost=5)
00:08
buy_cost=0.001, sell_cost=0.002, min_cost=5
00:11
set_commission( PerTrade(buy_cost=0.001, sell_cost=0.002, min_cost=5) )
00:15
elif dt datetime.datetime(2009,1, 1)
00:09
datetime.datetime(2009,1, 1)
00:13
set_commission(PerTrade(buy_cost=0.002, sell_cost=0.003, min_cost=5))
00:08
PerTrade(buy_cost=0.002, sell_cost=0.003, min_cost=5)
00:09
buy_cost=0.002, sell_cost=0.003, min_cost=5
00:08
set_commission( PerTrade(buy_cost=0.002, sell_cost=0.003, min_cost=5) )
00:06
else 其他 时期的 成本
00:09
set_commission(PerTrade(buy_cost=0.003, sell_cost=0.004, min_cost=5))
00:09
PerTrade(buy_cost=0.003, sell_cost=0.004, min_cost=5)
00:09
buy_cost=0.003, sell_cost=0.004, min_cost=5
00:13
set_commission( PerTrade( buy_cost=0.003, sell_cost=0.004, min_cost=5 ) )
00:11
每天交易时
00:05
def handle_data(context, data)
00:07
(context, data)
00:06
将总资金等分为g.N份,为每只股票配资
00:08
capital_unit = context.portfolio.portfolio_value g.N
00:08
capital_unit = context.portfolio.portfolio_value g.N - 代码分析
00:14
toSell = signal_stock_sell(context,data)
00:08
signal_stock_sell( context,data )
00:10
toBuy = signal_stock_buy(context,data)
00:06
代码块进行空格分隔
00:15
执行卖出操作以腾出资金
00:05
for i in range(len(g.security))
00:09
for i in range(len(g.security)) - 代码分析
00:22
if toSell[i]==1
00:11
if toSell[i] == 1 - 存在要卖出的股票
00:15
order_target_value(g.security[i],0)
00:15
order_target_value(g.security[i],0) 清空这支股票的仓位
00:15
执行买入操作
00:05
for i in range(len(g.security))
00:10
len(g.security)
00:13
if toBuy[i]==1
00:06
if toBuy[i]==1 是否需要买入
00:25
order_target_value(g.security[i],capital_unit)
00:09
order_target_value(g.security[i],capital_unit) - 代码分析
00:24
if not (1 in toBuy) or (1 in toSell)
00:37
if not (1 in toBuy) or (1 in toSell) 判断是否有操作
00:15
# log.info('今日无操作')
00:08
log.info('今日无操作') 日志里面写清楚
00:10
send_message('今日无操作') 代码分析
00:06
Ctrl + H,替换双引号 为 单引号
00:12
成功替换,方便保存文件名
00:11
['000001.XSHE','000002.XSHE','000006.XSHE','000007.XSHE','000009.XSHE'] # 设
00:11
获得卖出信号
00:09
输入:context, data
00:06
输出:sell - list
00:09
def signal_stock_sell(context,data)
00:10
sell = [0] len(g.security)
00:25
生成有多个元素的列表
00:27
新建一个 Python 3 的 Notebook
00:10
lst = [0] 5
00:23
生成 有多个元素 的列表
00:16
给研究环境改名
00:31
for i in range(len(g.security))
00:18
算出今天和昨天的两个指数移动均线的值
00:10
我们这里假设长线是60天,短线是1天(前一天的收盘价)
00:10
长线和短线之间有明显的时间差距
00:16
(ema_long_pre,ema_long_now)
00:31
结果为元组数据
00:14
get_EMA(g.security[i],60,data)
00:12
get_EMA(g.security[i],60,data) 代码分析
00:24
(ema_short_pre,ema_short_now)
00:07
get_EMA(g.security[i],1,data)
00:07
如果短均线从上往下穿越长均线,则为死叉信号,标记卖出
00:12
ema_short_now ema_long_now
00:27
ema_short_pre 大于 ema_long_pre
00:10
context.portfolio.positions[g.security[i]].sellable_amount 大于 0
00:26
sell[i]=1
00:14
return sell
00:06
循环分析每一只股票的情况
00:57
获得买入信号
00:08
输入:context, data
00:06
输出:buy - list
00:06
def signal_stock_buy(context,data)
00:11
buy = [0] len(g.security)
00:12
for i in range(len(g.security))
00:07
算出今天和昨天的两个指数移动均线的值
00:09
我们这里假设长线是60天,短线是1天(前一天的收盘价)
00:09
(ema_long_pre , ema_long_now)
00:13
get_EMA(g.security[i], 60, data)
00:09
(ema_short_pre , ema_short_now)
00:06
get_EMA(g.security[i], 1, data)
00:06
如果短均线从下往上穿越长均线,则为金叉信号,标记买入
00:10
同样是 3 个条件来确定
00:15
ema_short_now 大于 ema_long_now
00:09
ema_short_pre 小于 ema_long_pre
00:07
context.portfolio.positions[g.security[i]].sellable_amount == 0
00:10
买入条件分析
00:22
buy[i]=1
00:08
满足 3 个条件,可以买入股票
00:25
return buy
00:05
计算移动平均线数据
00:08
输入:股票代码-字符串,移动平均线天数-整数
00:08
输出:算术平均值-浮点数
00:06
def get_MA(security_code,days)
00:06
获得前days天的数据,详见API
00:10
a=attribute_history(security_code, days, '1d', ('close'))
00:09
security_code, days, '1d', ('close')
00:16
定义一个局部变量sum,用于求和
00:06
sum = 0
00:05
对前days天的收盘价进行求和
00:06
for i in range(1,days+1)
00:08
for i in range(1,days+1) 代码分析
00:15
sum+=a['close'][-i]
00:08
for 循环实现了所有收盘价都累加在一起
00:12
求和之后除以天数就可以的得到算术平均值啦
00:08
return sum 除以 days
00:05
计算指数移动平均线数据
00:11
指数移动平均线数据
00:12
输入:股票代码-字符串,移动指数平均线天数-整数,data
00:07
输出:今天和昨天的移动指数平均数-浮点数
00:07
def get_EMA(security_code,days,data)
00:12
如果只有一天的话,前一天的收盘价就是移动平均
00:12
获得前两天的收盘价数据,一个作为上一期的移动平均值,后一个作为当期的移动平均值
00:13
t = attribute_history(security_code, 2, '1d', ('close'))
00:15
return t['close'][-2],t['close'][-1]
00:15
attribute_history(security_code, 2, '1d', ('close'))
00:15
如果全局变量g.EMAs不存在的话,创建一个字典类型的变量,用来记录已经计算出来的EMA值
00:25
if 'EMAs' not in dir(g)
00:10
g.EMAs={}
00:05
字典的关键字用股票编码和天数连接起来唯一确定
00:11
以免不同股票或者不同天数的指数移动平均弄在一起了
00:08
key='%s%d' %(security_code,days)
00:13
如果关键字存在,说明之前已经计算过EMA了,直接迭代即可
00:11
if key in g.EMAs
00:09
计算alpha值
00:19
alpha=(days-1.0) (days+1.0)
00:07
获得前一天的EMA(这个是保存下来的了)
00:05
EMA_pre=g.EMAs[key]
00:07
EMA_now=EMA_pre alpha+data[security_code].close (1.0-alpha)
00:11
写入新的EMA值
00:05
g.EMAs[key]=EMA_now
00:07
给用户返回昨天和今天的两个EMA值
00:07
return (EMA_pre,EMA_now)
00:04
需要两个 EMA 值来判断金叉和死叉
00:12
获得days天的移动平均
00:06
ma=get_MA(security_code,days)
00:05
如果滑动平均存在(不返回NaN)的话,那么我们已经有足够数据可以对这个EMA初始化了
00:10
if not(isnan(ma))
00:09
g.EMAs[key]=ma
00:08
因为刚刚初始化,所以前一期的EMA还不存在
00:06
return (float('nan'),ma)
00:16
移动平均数据不足days天,只好返回NaN值
00:09
每天收盘后
00:05
每日收盘后要做的事情(本策略中不需要)
00:06
def after_trading_end(context)
00:07
return
00:04
五一算法-讲解版-5股-2010年至今
00:14
导入函数库
00:07
import jqdata
00:07
from jqlib.technical_analysis import 星
00:10
from jqdata import 星
00:09
import warnings
00:06
初始化函数
00:07
def initialize(context)
00:07
滑点高(不设置滑点的话用默认的0.00246)
00:09
set_slippage(FixedSlippage(0.02))
00:09
沪深300指数作为基准
00:04
set_benchmark('000300.XSHG')
00:08
用真实价格交易
00:06
set_option('use_real_price', True)
00:07
双引号改成单引号
00:31
set_option('avoid_future_data', True)
00:11
过滤order中低于error级别的日志
00:08
log.set_level('order', 'error')
00:10
过滤不重要的日志信息
00:33
warnings.filterwarnings('ignore')
00:09
选股参数
00:07
g.stock_num = 5 # 持仓数
00:10
g.position = 1 # 仓位
00:12
手续费
00:08
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0005, close_commi
00:20
设置交易时间
00:05
run_monthly(my_trade, monthday=1, time='10 00', reference_security='000300.XS
00:32
开盘时运行函数
00:11
def my_trade(context)
00:07
获取选股列表并过滤掉:st,st ,退市,涨停,跌停,停牌
00:15
check_out_list = get_stock_list(context)
00:18
log.info('今日自选股:%s' % check_out_list)
00:11
adjust_position(context, check_out_list)
00:14
选出资产负债率后20%且大于0,优质资产周转率前20%,roa改善最多的股票列表
00:19
def get_stock_list(context)
00:18
curr_data = get_current_data()
00:16
yesterday = context.previous_date
00:16
df_stocknum = pd.DataFrame(columns=['当前符合条件股票数量'])
00:20
过滤次新股
00:06
by_date = yesterday - datetime.timedelta(days=1200) # 三年
00:29
datetime.timedelta(days=1200)
00:27
get_all_securities(date=by_date).index.tolist()
00:29
initial_list
00:12
所以 2005 年出开始回测。还没有记录
00:21
0.st,今天涨跌停的,停牌的
00:13
stock for stock in initial_list
00:54
if not
00:06
(curr_data[stock].day_open == curr_data[stock].high_limit) 过滤涨停
00:41
(curr_data[stock].day_open == curr_data[stock].low_limit)
00:09
curr_data[stock].paused
00:14
('ST' in curr_data[stock].name)
00:12
('' in curr_data[stock].name)
00:07
('退' in curr_data[stock].name)
00:10
对不符合条件的股票做过滤
00:51
一般聚宽提供的代码没有过滤掉 ST 股票
00:15
df_stocknum.append({'当前符合条件股票数量':len(initial_list)}, ignore_index=True)
00:59
了解满足条件的股票数量
00:23
选出资产负债率由高到低后70%的,low_liability_list
00:18
get_fundamentals()
00:39
balance.code, balance.total_liability, balance.total_assets
00:08
filter() 过滤条件
00:07
valuation.code.in_(initial_list)
00:18
.dropna()
00:19
df = df.fillna(0)
00:11
df['ratio'] = df['total_liability'] 除法 df['total_assets'] # 资产负债率
00:16
df = df.sort_values(by = 'ratio',ascending=False)
00:27
low_liability_list = list(df.code)[int(0.3 len(list(df.code))) ]
01:03
股票代码转换成列表
00:26
[int(0.3 len(list(df.code))) ]
00:55
选出资产负债率由高到低后70%的
00:16
df_stocknum = df_stocknum.append({'当前符合条件股票数量': len(low_liability_list)}, ig
00:20
从low_liability_list中选出不良资产比率在总体中[20%-80%]范围内的的股票,proper_receivable_list
00:14
query(balance.code
00:12
balance.total_assets, # 总资产
00:06
balance.bill_receivable, # 应收票据
00:07
balance.account_receivable, # 应收账款
00:07
balance.other_receivable, # 其他应收款
00:06
balance.good_will, # 商誉
00:06
balance.intangible_assets, # 无形资产
00:08
balance.inventories, # 存货
00:07
balance.constru_in_process,# 在建工程
00:11
balance.code.in_(low_liability_list)
00:12
df1 = df1.fillna(0)
00:13
df1.sum(axis=1) - df1['total_assets']
00:35
df1['ratio1'] = df1['bad_assets'] 除法 df1['total_assets']
00:12
df1 = df1.sort_values(by = 'ratio1',ascending=False)
00:20
proper_receivable_list
00:06
list(df1.code)
00:11
[int(0.1 len(list(df1.code))) int(0.9 len(list(df1.code)))]
00:47
df_stocknum = df_stocknum.append({'当前符合条件股票数量' len(proper_receivable_list)}
00:11
从proper_receivable_list中选出优质资产周转率前75%的公司,proper_receivable_list1
00:22
df2 = get_fundamentals()
00:34
df2 = df2.fillna(0)
00:06
df2['good_assets']
00:13
df2['total_assets'] - (df2.sum(axis=1) - df2['total_assets'] - df2['total_op
00:34
df2['ratio2'] = df2['total_operating_revenue'] 除法 df2['good_assets']
00:13
df2 = df2.sort_values(by = 'ratio2',ascending=False)
00:13
proper_receivable_list1 = list(df2.code)[ int(0.75 len(list(df2.code)))]
00:57
df_stocknum = df_stocknum.append({'当前符合条件股票数量'
00:07
if len(proper_receivable_list1) == 0
00:07
从proper_receivable_list1中过去十二个季度ROA增长最多(前20%)的股票,按照ROA`增长量降序排列,roa_list
00:21
get_history_fundamentals()
00:18
get_history_fundamentals() 读取 ROA 数据
00:46
计算 ROA 增长量
01:09
ROA 增长量,降序排序
00:14
list(s_delta_avg[ int(0.2 len(s_delta_avg))].index)
00:16
从过去四个季度ROA增长量前20%的股票中选出市净率大于0的按照资产负债率升序排列选出前g.stock_num个,final_list
00:30
pb_list = get_fundamentals()
00:13
valuation.code.in_(roa_list)
00:14
valuation.pb_ratio 大于 0.7
00:17
valuation.ps_ratio 小于 3
00:06
valuation.pb_ratio.asc()
00:13
按要求过滤股票,并按照 PB 升序排列
00:23
final_list = pb_list[ g.stock_num]
00:14
return final_list
00:09
def adjust_position(context, buy_stocks)
00:12
for stock in context.portfolio.positions
00:05
if stock not in buy_stocks
00:10
order_target(stock, 0)
00:05
position_count = len(context.portfolio.positions)
00:15
if g.stock_num 大于 position_count
00:20
context.portfolio.cash 星 g.position 除法 (g.stock_num - position_count)
00:38
仓位计算
00:30
for stock in buy_stocks
00:11
if stock not in context.portfolio.positions
00:20
order_target_value(stock, value)
00:07
if len(context.portfolio.positions) == g.stock_num
00:12
break 持仓满足条件就中断循环
00:15
调仓模块比较简单
00:09
清仓多少,买入多少
00:26
一买一卖模型
00:19
def get_stock_list(context) 晒选排序股票最复杂
00:16
过滤次新股是先决条件
00:09
垃圾股过滤
00:18
多重财务指标反复筛选
00:50
对于五一算法的一些重要内容再详细介绍
00:23
set_option('avoid_future_data', True)
00:19
打开 API 文档
00:17
查找 set_option 函数
00:55
发现大量和 set_option 相关的设置
02:00
set_option() 在股票、期货、融资融券中有大量设置
00:14
过滤order中低于error级别的日志
00:10
log.set_level('order', 'error')
00:08
查询 log.set_level 发现有 8 处介绍
00:20
找到 log.set_level 相关函数介绍
00:48
设定log级别:log.set_level
00:09
log.set_level(name, level)
00:07
设置不同种类的log的级别, 低于这个级别的log不会输出
00:12
所有log的默认级别是debug
00:10
为了降低排查问题的难度,建议日志级别保持为默认级别
00:11
不设置日志级别,或者设置log.set_level('order', 'info')
00:11
参数 name 字符串, log种类
00:12
必须是'order', 'history', 'strategy'中的一个
00:10
order 调用order系列API产生的log
00:10
history 调用history系列API(history attribute_history get_price) 产生的log
00:09
strategy 您自己在策略代码中打的log
00:09
system 统日志,除以上三类之外的日志
00:06
level 字符串, 必须是'debug', 'info', 'warning', 'error'中的一个
00:10
级别 逐步加大 debug info warning error
00:10
返回 None
00:08
设置日志级别为debug
00:07
log.set_level('order', 'debug')
00:05
尽量设置日志级别为debug,或者不设置(使用系统默认级别),有利于您快速的发现问题
00:08
模拟交易中,需要修改日志级别,可以在after_code_changed中,重新设置日志级别
00:10
log.set_level(name, level) 详细讲解完毕
00:25
在日志中输出该函数运行的时间
00:06
def filter_stocks(context)
00:06
筛选、排序股票,生成待交易股票列表
00:08
run_weekly(market_open,1,'10 00') 代码介绍
00:14
run_weekly(market_open,1,'10 00')
00:12
开盘后 10 00 进行开仓、调仓操作
00:07
run_weekly(filter_stocks,1,'09 30') 代码介绍
00:16
run_weekly(filter_stocks,1,'09 30')
00:09
筛选、过滤生成待买入股票列表为交易做准备
00:08
开盘时运行 filter_stocks() 函数
00:08
每周只在第一个交易日进行股票筛选、过滤、排序、开仓、调仓等操作
00:09
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commi
00:07
股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣 5 元钱
00:18
run_daily(stoploss, '9 45')
00:07
止损函数调用时间在开仓、调仓函数之前
00:07
经典小市值策略-10股-2010年至今
00:11
来自聚宽上我们自己的文章
00:39
标题:【详细注释】经典小市值策略
00:07
作者:加百力
00:06
导入函数库
00:06
from jqdata import
00:08
初始化函数,设置基准等等
00:07
08、context 是由系统维护的上下文环境
00:08
包含买入均价、持仓情况、可用资金等资产组合相关信息
00:09
def initialize(context
00:06
g. 开头的是全局变量
00:06
一经声明整个程序都可以使用
00:06
设置持股数量
00:05
g.stocknum = 10
00:05
待买入股票列表
00:06
g.buylist = []
00:11
设置沪深300股指作为基准
00:06
如果不设置,默认的基准也是沪深300股指
00:06
set_benchmark('000300.XSHG')
00:11
开启动态复权模式(使用真实价格)
00:07
set_option('use_real_price', True)
00:09
交易量不超过实际成交量的 0.1
00:07
set_option('order_volume_ratio', 0.1)
00:08
在日志中写入字符串
00:09
整个回测过程中,只会在开始阶段写入一次
00:07
log.info('初始函数开始运行且全局只运行一次')
00:07
过滤掉order系列API产生的比error级别低的log
00:09
默认是 'debug' 参数。最低的级别,日志信息最多
00:09
系统推荐尽量使用'debug'参数或不显式设置,方便找出所有错误
00:08
log.set_level('order', 'error')
00:06
设置滑点
00:05
0.02 的滑点设置还比较高
00:07
set_slippage(FixedSlippage(0.02))
00:07
止损函数在每个交易日的 9 45 都被调用一次
00:07
主要是为了尽量控制风险
00:06
回测历史数据时就是当时的日期时间
00:07
log.info(str('函数运行时间(filter_stocks):' + str(context.current_dt.time())))
00:08
log.info(str('函数运行时间(filter_stocks):' + str(context.current_dt.time()))) 代码介
00:24
获取当前时间的行情数据
00:08
获取当前单位时间(当天 当前分钟)的涨跌停价, 是否停牌,当天的开盘价等
00:14
回测时, 通过其他获取数据的API获取到的是前一个单位时间(天 分钟)的数据
00:13
而有些数据, 我们在这个单位时间是知道的, 比如涨跌停价, 是否停牌, 当天的开盘价
00:11
curr_data = get_current_data()
00:11
获取 上证综指和深证综指 的成份股
00:07
这个股票范围也很关键
00:05
如果换成其他一些股票指数的成分股,收益率可能大幅下降
00:09
过滤 开盘就涨停、跌停 的股票
00:07
过滤 当日暂停交易 的股票
00:06
过滤 含有 ST、 及退市标签 的股票
00:06
外围 [] 用于生成列表
00:05
内部是一个 for...in 表达式
00:06
针对 scu 股票列表中的每一只股票代码做分析过滤
00:08
括号里面是连续的 or 逻辑表达式,只要满足一个条件就为 True
00:09
小括号外面 not 取否。任何一个条件成立都会被过滤掉
00:11
[stock for stock in scu if not (
00:19
(curr_data[stock].day_open == curr_data[stock].high_limit) or
00:16
(curr_data[stock].day_open == curr_data[stock].low_limit) or
00:09
curr_data[stock].paused or
00:09
('ST' in curr_data[stock].name) or
00:07
('' in curr_data[stock].name) or
00:08
('退' in curr_data[stock].name)
00:08
获取市值最小的股票列表
00:06
query()生成一个 query 对象
00:05
query(valuation.code,valuation.market_cap) 查询 valuation 表的 股票代码、总市值 字段
00:14
filter(valuation.code.in_(scu))。过滤条件是股票代码必须在 scu 列表中。注意不是 in 而是 in_
00:19
order_by(valuation.market_cap.asc())。按照市值升序排列。小市值股票在前,大市值股票在后
00:15
limit(g.stocknum) 限制只取 g.stocknum 数量的股票
00:09
q = query(valuation.code,valuation.market_cap).filter(valuation.code.in_(scu)
00:09
get_fundamentals() 读取指定日期的股票查询数据
00:07
date = context.previous_date。对前一个交易日的股票数据做筛选、排序
00:09
读取结果以数据框的形式赋值给 df
00:06
df = get_fundamentals(q,date = context.previous_date)
00:08
将 df 数据框中的 code 列数据转换成列表类型数据
00:08
stocklist = list(df['code'])
00:07
将待买入股票列表赋值给全局变量
00:06
g.buylist = stocklist
00:05
止损函数
00:08
每天检查是否有股票触发止损条件
00:06
如有触发则立即卖出平仓
00:05
def stoploss(context)
00:05
使用 for 循环遍历 context.portfolio.positions 当前持仓的每一只股票
00:10
for stock in context.portfolio.positions
00:08
读取每只持仓股票的买入均价赋值给 cost 变量
00:07
cost = context.portfolio.positions[stock].avg_cost
00:08
cost = context.portfolio.positions[stock].avg_cost
00:27
读取每只持仓股票的当前价格
00:06
price = context.portfolio.positions[stock].price
00:10
price = context.portfolio.positions[stock].price 代码分析
00:17
计算每只持仓股票当前的收益率
00:07
ret = price cost-1
00:06
如果收益率小于 -0.2 表示浮亏已经突破 -20%
00:06
if ret 小于 -0.2
00:07
清仓该只股票
00:04
order_target() 将该只股票的持仓量调整为 0
00:07
order_target(stock,0)
00:05
在日志中写入 触发止损 这个字符串
00:05
log.info('触发止损')
00:11
分析了止损函数相关内容
00:08
context.portfolio.positions 看到他们的价值
00:24
context.portfolio.positions[stock].avg_cost 可能多次买入
00:11
context.portfolio.positions[stock].price
00:15
context 系统维护非常重要
00:10
log.info(str('函数运行时间(stoploss)' + str(context.current_dt.time())))
00:29
log.info(str('函数运行时间(stoploss)' + str(context.current_dt.time())))
00:47
过滤函数是 9 点半运行
00:21
return
00:12
50、order_target_value(i, every_stock)
00:15
开盘时运行函数
00:07
def market_open(context)
00:13
在日志中写入函数运行时间
00:07
在日志中写入 函数 运行时间
00:22
str(context.current_dt.time())
00:15
str('函数运行时间(market_open):'+str(context.current_dt.time()))
00:13
log.info() 写入日志中
00:08
如果待买入股票列表长度为 0,表示没有要操作的股票
00:07
则直接返回
00:08
len(g.buylist) == 0
00:12
if(len(g.buylist) == 0)
00:08
待买入股票列表中有要买入的股票
00:07
则调用 rebalance() 函数开仓或调仓
00:07
rebalance() 函数开仓或调仓
00:18
rebalance(context,g.buylist)
00:08
调仓 rebalance() 函数
00:06
第一个参数为上下文环境
00:05
第二个参数为待买入股票列表
00:05
def rebalance(context,buylist)
00:08
根据当前资产组合的价值,计算每只股票应持仓金额
00:08
context.portfolio.portfolio_value 除以 len(buylist)
00:15
every_stock = context.portfolio.portfolio_value 除以 len(buylist)
00:12
如果当前没有持仓就全部买入。等额分配资金
00:10
context.portfolio.positions.keys()
00:15
list(context.portfolio.positions.keys())
00:11
if len(list(context.portfolio.positions.keys())) == 0
00:13
for 循环对待买入列表中的每只股票都进行购买操作
00:12
for stock_to_buy in buylist
00:13
根据 every_stock 价值买入股票
00:07
根据 every_stock 价值 买入股票
00:08
如果有持仓,先卖出已经持有但不在待买入列表中的股票
00:11
卖出已经过时的股票
00:07
else 有持仓的情况
00:22
遍历每一只持仓股票代码
00:07
for stock_to_sell in list(context.portfolio.positions.keys())
00:12
如果这只股票代码不在买入列表中,说明已经过时应该清仓
00:08
if stock_to_sell not in buylist
00:07
清仓这只股票
00:05
股票的持仓价值额度为0
00:05
order_target_value(stock_to_sell, 0)
00:08
为buylist里的每支股票调整仓位
00:07
这句非常重要
00:06
一方面会买入当前未持仓的列表中的股票
00:12
另一方面也会影响其他持仓股票的仓位
00:07
低于资产组合平均价值的股票会加仓
00:06
高于资产组合平均价值的股票会减仓
00:06
实验证明调仓对于提高收益率很有帮助
00:06
for i in buylist
00:07
2-2 选股模块
00:08
导入模块
00:49
def initialize(context) 详细介绍
07:10
def get_factor_filter_list(context,stock_list,jqfactor,sort,p1,p2) 详细介绍
06:35
def get_stock_list(context) 详细介绍
06:56
def prepare_stock_list(context) 准备多个用于交易的股票列表
09:20
def weekly_adjustment(context) 每周调整仓位
06:54
def check_limit_up(context)
02:16
股票过滤函数,过滤 ST 股、有涨停的个股等等
02:52
def filter_limitup_stock(context, stock_list)
00:44
def filter_limitdown_stock(context, stock_list)
00:35
def filter_kcbj_stock(stock_list)
00:45
def filter_new_stock(context, stock_list, d) 过滤次新股
00:42
order_target_value_(security, value) 自定义下单函数
00:56
def open_position(security, value) 自定义开仓函数
00:56
def close_position(position) 自定义平仓函数
01:38
def print_position_info(context) 打印每日持仓信息
02:00
ETF二八轮动-2013年至今-沪深300-14点30
00:29
导入函数库
00:18
进行初始化设置
00:21
计算前 N 日涨幅
00:27
g.N = 10
00:10
两只股指ETF的收益率差距的阈值
00:10
g.rise_threshold = 0
00:45
产生信号和交易的时间
00:06
g.signal_time = '14 30'
00:23
股指ETF基金的持仓比例
00:18
g.ratio = 0.8
00:06
set_benchmark('000300.XSHG')
00:15
set_option('use_real_price',True)
00:08
log.set_level('order','error')
00:13
基金类交易手续费是
00:15
set_slippage(FixedSlippage(0),type='fund')
00:32
基金池:沪深300ETF,创业板ETF,国债ETF 黄金ETF等
00:27
基金池的规模比较大,多品种反复测试
00:36
首先使用指数测试,最后提交ETF版本
00:47
每月第一个交易日调用 CheckTrade() 函数
00:10
run_monthly(CheckTrade, 1, g.signal_time)
00:11
每个月第一个交易日处理
00:12
run_weekly(CheckTrade, 1, g.signal_time)
00:28
改成按周为单位运行,效果一般
01:39
按月线运行有 6 倍多的总收益率
01:52
def CheckTrade(context)
00:15
signal = create_signal(context, g.fund_list, g.N, g.rise_threshold)
00:19
在日志中记录交易信号
00:06
log.info('signal=%s', signal)
00:34
根据交易信号,交易股指ETF
00:07
trade(context, signal, g.fund_list, g.ratio)
00:12
余钱全部买债券ETF
00:06
trade_bond(context, g.fund_list, 1)
00:10
return 无返回值。返回结果
00:10
产生程序信号,返回 signal
00:15
def create_signal(context, fund_list, N, rise_threshold)
00:28
price_rise = [0,0]
00:25
计算基金数量
00:10
security_round_num = int(len(fund_list)除以2)
00:36
债券不参与计算信号标的
00:12
for i in range(security_round_num - 1)
00:21
stk = fund_list[i乘以2]
00:25
attribute_history 获取历史数据,可查询单个标的多个数据字段,返回数据格式为 DataFrame 或 Dict(字典)
00:20
只有两只 指数ETF 要查询,使用此函数很方便
00:09
查看某一支股票的历史数据, 可以选这只股票的多个属性, 默认跳过停牌日期
00:18
当取天数据时, 不包括当天的, 即使是在收盘后;分钟数据不包括当前分钟的数据,没有未来
00:15
这个API没有当天数据,没有未来函数
00:31
his_data = attribute_history(stk, N, '1d', ['close'], skip_paused=True)
00:27
price_rise[i] = his_data['close'][-1] 除以 his_data['close'][-N] - 1
01:13
log.info('fund%s, price_rise=%s, yesterday=%s, prev_N = %s'
00:37
两轮循环完成两只ETF基金的收益率计算
00:39
diff_price_rise = price_rise[0] - price_rise[1]
00:20
if diff_price_rise 大于 rise_threshold and price_rise[0] 大于 0
00:50
signal = 1
00:11
第二只ETF上涨较大。超过阈值,并且涨幅为正
00:08
第一只ETF上涨较大。超过阈值,并且涨幅为正
00:08
elif diff_price_rise 小于 -rise_threshold and price_rise[1] 大于 0
00:29
signal = 2
00:07
两只ETF都下跌
00:07
signal = 3
00:27
return signal
00:06
分析基金前 10 个交易日的行情数据,判断应该如何操作
00:50
根据交易信号,交易指定指数ETF
00:17
def trade(context, signal, security_round_list, ratio)
00:26
security_round_num = int(len(security_round_list) 除法 2)
00:08
context.portfolio.total_value
00:12
total_value:总的权益, 包括现金, 保证金(期货)或者仓位(股票)的总价值, 可用来计算收益
00:33
total_value = context.portfolio.total_value
00:07
log.info('current total value: %s', total_value)
00:08
卖出股指ETF操作
00:09
for i in range(security_round_num)
00:40
if i != (signal-1)
00:12
signal 为 1,清仓第 2 只基金
03:23
siganl 为 2 。第一只基金先平仓
01:18
signal为1,债券基金如何操作
01:44
siganl 为 2 。第一只基金先平仓
01:18
signal 为 2 。第二只基金不动
00:28
signal 为 2 时。债券基金处理分析
00:59
signal 为 3 时,第一、第二只基金都被平仓。第三只满仓
01:22
对应基金反而不处理,非对应的基金和第三只基金单独处理
02:18
signal 为 3 的时候第一、第二只基金被清仓
01:11
signal 为 1 时,对第一只基金按照 g.ratio 的比例买入
00:11
signal 为 2 时,对第二只基金按照 g.ratio 的比例买入
00:10
signal 为 3 时,上面已经返回不会进行下面的操作
00:07
根据 signal 的数值, 确定要操作的基金代码
00:06
stk = security_round_list[(signal-1) 2+1]
00:30
根据账户总权益和 g.ratio 的比例计算第一、第二只基金买入额度
00:08
target_value = context.portfolio.total_value g.ratio
00:08
根据计算的额度买入第一或第二只基金
00:06
order_value(stk, target_value)
00:06
买入了那只基金,额度是多少,写入日志
00:06
log.info('buy stk %s to target_value %s', stk, target_value)
00:12
第三只基金补充交易
00:08
signal 为 1 或 2 的时候,第一、第二只基金处理完毕。可能还有剩余资金
00:09
还有剩余资金
00:12
signal 为 3 时,前面的函数已经清空第一、第二只基金
00:07
有大量资金可以继续买入第三只基金
00:05
def trade_bond(context, security_round_list, ratio)
00:09
log.info('进入第三只基金补充交易函数')
00:07
获取基金数量信息
00:05
security_round_num = int(len(security_round_list) 2)
00:13
此时对应的时第三只基金
00:05
stk = security_round_list[security_round_num 2-1]
00:12
ratio 为 1
00:06
计算剩余资金的规模
00:05
cash = context.portfolio.available_cash ratio
00:09
所有剩余资金都买入第三只基金
00:05
order_value(stk, cash)
00:05
日志中记录购买第三只基金的名称和额度
00:19
log.info('buy bond %s, avail_cash %s', stk, cash)
00:18
前两只轮动,第三只避险
00:15
有大量基金代码可以组合实验.mp4
00:11
08-自由现金流-5股-2010年至今
00:28
导入函数模块
00:34
中性化、去极值化、标准化是模型特点
00:13
def initialize(context)
00:20
设置核心参数
00:34
初始化全局变量
00:40
全局变量应该在初始化函数中设置
00:49
查找全局变量,发现没有了
00:57
如果不设置滑点和交易成本则默认使用聚宽的设置
00:15
这样做的好处是,有利于对比不同算法的整体表现
00:14
每日获取昨日涨停股票列表
00:32
似乎加了 止损模块 反而收益率大幅下降了
00:24
每个月进行一次调仓操作
00:11
按周为单位运行也没问题
00:16
把昨日涨停今天没涨停的股票卖出
00:09
自由现金流模型对昨日涨停股票做单独处理
00:14
每月第一个交易日 16-00 收盘后在日志中输出市值、股价等数据
00:40
选股模块。根据财务要求和数据计算分析获取待交易股票列表
00:14
获取 365 天之前的日期。yesterday 还是用起来
01:35
生成初始股票列表
00:49
详细解释公式中用到的财务数据含义
05:33
读取满足条件的股票信息
01:13
对比值因子和roe因子做单独处理并加起来作为分数项
04:13
获取昨日涨停股票列表
01:23
调整持仓。平仓被淘汰的股票买入新股
02:47
集中过滤股票的代码不清晰
00:42
过滤停牌股票
00:43
过滤ST及其他具有退市标签的股票
00:16
过滤涨跌停股票
00:46
过滤科创板
00:15
交易模块-自定义下单
00:24
交易模块-开仓
00:24
交易模块-平仓
00:28
止损模块编写方法
01:25
g.stocks 并不是程序的一部分。直接删除
00:27
有止损版本
00:35
有止损模块的回测
00:43
有止损模块回测,实时分析图
00:21
无止损模块的回测结果更好
00:24
2015年一度回撤较大,但很快崛起
00:24
查看市值和股价信息,非小市值模型
01:13
调整昨日涨停股票
00:34
一年涨三倍以上牛股分析(最近6年)
00:30
导入所需的函数库
01:40
设置滚动天数和涨幅阈值参数
00:36
计算起始日期
01:06
获取起始日期时上市股票代码
00:32
获取当前日期
00:31
获取当前日期时上市的股票代码
00:17
输出起始和当前日期和股票数量
00:42
计算新增上市股票数量
00:29
days = [str(d)[ 冒号 10] for d in stk_price.index.values]
00:47
定义一个保存牛股的列表
00:11
zip() 将股票代码值(行索引)和股票名称值生成 zip 对象。用于for循环枚举
00:36
zip(now_stks.index.values
00:33
读取每只股票的价格数据
00:56
if len(stk_price) 小于 N_INCR_DAYS + 1
00:34
ROC() 变动率指标
01:13
roc = np.round(ROC(stk_price['close'].values, N_INCR_DAYS), 2)
00:33
np.nanmax() 取变动率中的最大值
00:59
生成 牛股 的交易日期字符串列表。为截取暴涨时间段做准备
00:39
输出上市公司名称和 days 数据观察
00:35
返回包含 na 的收益率数据中最大值的索引
00:19
loc = np.nanargmax(roc)
00:48
bull_stks 是由单个牛股列表组成的大列表
00:28
单个牛股列表包含:股票代码、股票名称、价格起点、价格终点、收益率
00:09
特别注意:价格起点未必是 行情启动点
00:22
完全可能出现价格起点之后,跌的更重,然后反弹最终超过涨幅阈值的情况
00:10
bull_stks += [[stk, stk_name, days[loc - N_INCR_DAYS], days[loc], roc[loc]]]
02:04
cols = ['代码', '名称', '起始', '终止', '涨幅']
00:12
bull_stks = pd.DataFrame(bull_stks, columns=cols)
00:39
bull_stks 调用 sort_valuse() 方法排序
00:58
bull_stks.sort_values(by=['涨幅'], ascending=False, inplace=True)
00:50
bull_stks.index.values[ ] = np.arange(1,len(bull_stks) + 1)
01:12
输出牛股数量和涨幅中位数
00:54
输出全部牛股信息
00:12
将牛股数据保存在 CSV 文件中
00:44
输出结果展示
01:29
print(bull_stks.head(40))
00:31
print( bull_stks.head(40) )
00:13
bull_stks[bull_stks['起始'].values 大于等于 '2021-01-01']
00:35
rows = len(stks2021)
00:08
输出2021年以来的牛股数据框
00:13
print(stks2021.to_string())
00:19
2021年以来共有 79 只股票,一年涨幅达到3倍及以上
00:20
10-期货-多品种-双均线-ATR
00:17
导入函数库
00:34
def initialize(context)
00:49
设定账户为期货账户
00:54
期货类每笔交易时的手续费
00:55
删除手续费设置,还是正常交易
04:04
删除保证金比列设置。使用系统默认设置
00:54
开盘时运行
00:31
收盘后运行
00:18
def set_info(context)
01:19
参数设置
00:49
交易的期货品种信息
00:28
set_future_list(context)
00:16
遍历待交易期货品种列表中的每一个品种
01:23
idx = get_future_code(ins)
00:32
dom = get_dominant_future(ins)
00:55
g.MappingIndex[ins] = idx
00:23
g.MappingReal[ins] = dom
00:36
把主力合约名称加入到期货列表中
00:18
将新的主力合约加入列表中
01:09
开盘时运行函数
00:17
遍历待交易期货品种,分析主力合约是否切换
00:43
计算、分析交易信号并做交易
00:12
初始化指数和主力合约数据,做初步判断
04:20
计算两条均线的数据
01:12
判断当前 快线、慢线 的交叉情况
01:36
收盘后输出当天的成交记录
00:42
处理交易的函数
00:07
发现了一个非常隐蔽的 BUG
02:24
def Trade(context,RealFuture)
01:16
context.portfolio.short_positions[RealFuture].total_amount
00:28
移仓换月模块逻辑
01:01
def replace_old_futures(context,ins,dom)
00:53
如果旧合约名称出现在空头持仓中
00:43
通过字典数据将 期货品种字符串 与 品种指数 对应起来
00:19
def get_future_code(symbol)
00:46
交易所信息不同。需要查表解决
00:19
def get_lots(context,symbol)
00:42
future_Contract_Size
00:19
计算交易手数,并且取整
01:55
def get_CCFX_end_date(future_code)
00:41
11-小零花-沪金周五做多 模型- 原始版
00:15
import datetime as dt
00:13
import matplotlib.pyplot as plt
00:13
因为是 日内交易,收盘平仓 使用 主连合约 没有问题
00:14
start_date = '2008-1-9'
00:14
end_date = dt.datetime.now()
00:08
weekday = 5
00:08
读取沪金主连合约的历史行情数据
00:08
au_df = get_price(symbol
00:37
计算有多少个交易日
00:13
以当日开盘价开多单,收盘价平仓
00:16
从 DatetimeIndex 中提取星期几数据
00:08
au_df['wd']= au_df.index.dayofweek + 1
00:21
au_df = au_df[ au_df['wd'] == weekday ]
00:14
减去 0.01 是为了扣除开仓手续费
00:33
au_df.to_csv('小零花-沪金周五做多模型.csv', float_format='%.2f', encoding='utf-8')
00:11
trade_times = len(au_df)
00:28
计算盈利交易次数
00:23
计算盈利概率
00:24
输出沪金做多盈利概率
00:15
计算总的盈利金额
00:51
print('总盈利:',win_value
00:09
计算总的亏损金额
00:30
print('总亏损:',lose_value
00:17
计算总的盈亏比
00:18
计算累计盈亏
00:25
计算亏损交易次数
00:25
计算单笔盈亏比
00:25
单笔交易的盈亏比并不高
00:18
plt.figure(dpi=200)
00:17
x = au_df.index
00:13
y = au_df['delt'].cumsum() 1000
00:18
plt.title('小零花-沪金周五做多 模型')
00:10
plt.xlabel('年份')
00:11
plt.ylabel('累计盈亏金额(一手)')
00:09
plt.plot(x, y)
00:07
plt.show()
00:06
open_low_times = len(au_df[ au_df['open'] == au_df['low'] ])
00:24
开盘价就是最低价共出现
00:13
绘制散点图
00:35
plt.scatter(x, y,c='red',s=0.3)
00:25
为什么不设置止损?
00:16
如果要设止损,应该参考什么标准比较合适?
00:08
是固定止损更好,还是追踪止损更好?
00:08
头寸规模如何动态调整,以适应账户盈亏变化?
00:08
一定要在开盘时进场吗?
00:07
一定要在收盘时出场吗?如果处于浮亏有没有办法解决?
00:08
有没有办法继续提高胜率和盈亏比?
00:07
一定要每个周五都进场吗?
00:09
如果将来这个模型完全失效。周五下跌行情比较多怎么办?
00:08
沪金是否在其他日期也有类似效应?
00:06
其他品种是否也有类似效应?
00:06
天蝎座-除夕-2021年至今
00:43
天蝎座-除夕-编译运行,查看情况
01:56
导入函数库是基本操作
00:28
初始化函数进行系统参数设置
01:16
设置每日买入或卖出股票的时间
01:23
买入、卖出函数简介
01:16
处理日期相关函数
00:14
过滤函数
00:34
每日初始股票池和相关处理函数
00:59
date = transform_date(context.previous_date, 'str')
00:38
昨日涨停列表
00:44
前一日有涨停股票的要进行处理
00:27
获取非连板涨停的股票列表
01:41
计算相对位置
01:14
读取股票历史数据
01:55
计算今日开盘价相对于昨日收盘价的变化率
00:40
低开越多风险越大,选择3个多点即可
01:47
买入低开股票
02:00
def sell(context) 卖出股票操作
00:16
获取基础的日期和股票行情数据
00:28
上午收盘前卖出有浮盈但又没有涨停的股票
02:35
全天收盘前分析个股,如果未涨停则卖出平仓
01:33
print('— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —'
00:22
再次运行代码,查看是否正常
00:55
def transform_date(date, date_type)
00:15
对输入的日期时间数据进行类型转换
02:48
def get_shifted_date(date, days, days_type='T')
00:09
根据交易日、自然日的信息做日期转换处理
03:25
def filter_new_stock(initial_list, date, days=250)
00:48
def filter_st_stock(initial_list, date)
01:13
def filter_kcbj_stock(initial_list)
00:34
def filter_paused_stock(initial_list, date)
00:48
def prepare_stock_list(date)
00:31
def get_hl_stock(initial_list, date)
01:09
def get_hl_count_df(hl_list, date, watch_days, df)
01:53
def get_continue_count_df(hl_list, date, watch_days)
00:14
分析计算涨停股票连板的次数
03:09
计算股票处于一段时间内相对位置
00:08
def get_relative_position_df(stock_list, date, watch_days)
00:21
计算股票在高低点之间的价格
02:10
未使用财务数据,只有涨停信号
00:32
过滤ST、科创板、北交所等股票
00:53
只使用前一日涨停信号来下单
00:25
连续涨停时跟风进场,风险非常大
01:06
低开幅度不能太大,否则风险比较大
01:07
不能买入最近一直很强势的个股。相对位置低一些更有优势
01:10
用近期结果推导后一段时间的结果
00:36
低开4个百分点以内,试试看
01:45
交易股票数量明显增加了
00:40
客服
顶部
赛事库 课堂 2021拜年纪