本文是量化交易零基础入门教程中的一篇,点击蓝字链接可查看该系列详情。
现在你听说了这样一件事,小市值股票过去很长一段时间内收益特别好,但最近不太行了。你觉得这件事比较有价值,想要写成策略来回测验证下。请思考下,应该写一个什么样的策略来验证这件事呢?
为了验证灵感,我们把灵感细化成内容如下的这样一个策略。
每天找出市值排名最小的前10只股票作为要买入的股票。
若已持有的股票的市值已经不够小而不在要买入的股票中,则卖出这些股票。
买入要买入的股票,买入金额为当前可用资金的10分之一。
考虑到不一定要选10个股票,股票数量应该是个可以方便调节的变量,因此策略内容改成如下这样更好。
设定好要交易的股票数量stocksnum
每天找出市值排名最小的前stocksnum只股票作为要买入的股票。
若已持有的股票的市值已经不够小而不在要买入的股票中,则卖出这些股票。
买入要买入的股票,买入金额为当前可用资金的stocksnum分之一。
因为最终目的是要写成代码交给计算机回测,因此要逐步把文字的意思用代码实现,首先要把这个策略放到之前讲过的初始化与周期循环的策略框架中,如下。
def initialize(context):
run_daily(period,time='every_bar')
# 代码:设定好要交易的股票数量stocksnum
def period(context):
# 代码:找出市值排名最小的前stocksnum只股票作为要买入的股票
# 代码:若已持有的股票的市值已经不够小而不在要买入的股票中,则卖出这些股票。
# 代码:买入要买入的股票,买入金额为可用资金的stocksnum分之一
接下来,你只需要逐步的把策略的全部内容用代码实现出来,技巧是把复杂的内容拆分成多个简单的内容,逐步实现,对于不确定的东西print打印出来看看。往下读之前,建议自己独立实现下试试,基本都是用讲过的内容。遇到困难可以看下我下面给出提示,所有提示后面会给出参考代码。
参考代码
def initialize(context):
run_daily(period,time='every_bar')
# 设定好要交易的股票数量stocksnum
g.stocksnum = 10
def period(context):
# 代码:找出市值排名最小的前stocksnum只股票作为要买入的股票
# 获取上证指数和深证综指的成分股代码并连接,即为全A股市场所有股票的股票代码
# 用加号可以连接两个list
scu = get_index_stocks('000001.XSHG') get_index_stocks('399106.XSHE')
# 选出在scu内的市值排名最小的前stocksnum只股票
q=query(valuation.code
).filter(
valuation.code.in_(scu)
).order_by(
valuation.market_cap.asc()
).limit(g.stocksnum)
df = get_fundamentals(q)
# 选取股票代码并转为list
buylist=list(df['code'])
# 代码:若已持有的股票的市值已经不够小而不在要买入的股票中,则卖出这些股票。
# 对于每个当下持有的股票进行判断:现在是否已经不在buylist里,如果是则卖出
for stock in context.portfolio.positions:
if stock not in buylist: #如果stock不在buylist
order_target(stock, 0) #调整stock的持仓为0,即卖出
# 代码:买入要买入的股票,买入金额为可用资金的stocksnum分之一
# 将资金分成g.stocksnum份
position_per_stk = context.portfolio.cash/g.stocksnum
# 用position_per_stk大小的g.stocksnum份资金去买buylist中的股票
for stock in buylist:
order_value(stock, position_per_stk)
参考代码
def initialize(context):
run_daily(period,time='every_bar')
# 设定好要交易的股票数量
g.stocksnum = 7
# 设定交易周期
g.period = 13
# 记录策略进行天数
g.days = 0
def period(context):
# 判断策略进行天数是否能被轮动频率整除余1
if g.days % g.period == 0:
# 代码:找出市值排名最小的前stocksnum只股票作为要买入的股票
# 获取上证指数和深证综指的成分股代码并连接,即为全A股市场所有股票的股票代码
# 用加号可以连接两个list
scu = get_index_stocks('000001.XSHG') get_index_stocks('399106.XSHE')
# 选出在scu内的市值排名最小的前stocksnum只股票
q=query(valuation.code
).filter(
valuation.code.in_(scu)
).order_by(
valuation.market_cap.asc()
).limit(g.stocksnum)
df = get_fundamentals(q)
# 选取股票代码并转为list
buylist=list(df['code'])
# 代码:若已持有的股票的市值已经不够小而不在要买入的股票中,则卖出这些股票。
# 对于每个当下持有的股票进行判断:现在是否已经不在buylist里,如果是则卖出
for stock in context.portfolio.positions:
if stock not in buylist: #如果stock不在buylist
order_target(stock, 0) #调整stock的持仓为0,即卖出
# 代码:买入要买入的股票,买入金额为可用资金的stocksnum分之一
# 将资金分成g.stocksnum份
position_per_stk = context.portfolio.cash/g.stocksnum
# 用position_per_stk大小的g.stocksnum份资金去买buylist中的股票
for stock in buylist:
order_value(stock, position_per_stk)
# 策略进行天数增加1
g.days = g.days 1
查看下一篇
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程