大数跨境
0
0

10分钟学会多股票策略

10分钟学会多股票策略 JoinQuant聚宽
2017-03-24
0
导读:快上车 | 量化交易快速入门:学会使用for语句和list数据类型学会写多股票策略学前需推荐阅读

摘要:

  • 学会使用for语句和list数据类型

  • 学会写多股票策略

学前推荐阅读《十行代码带你量化交易入门


【确定策略内容】

在推荐阅读中,单股票的均线策略的内容是:

若昨日收盘价 > 过去20日平均价

=>今天开盘买入股票
若昨日收盘价 < 过去20日平均价

=>今天开盘卖出股票


现在,我们想利用计算机强大的数据处理能力,同时监视市场上多只股票,若满足条件就进行相应交易。简言之,对多个股票分别实行单股票策略,内容是:

若多只股票中的某只昨日收盘价 > 过去20日平均价

=>今天开盘买入该股票
若多只股票中的某只昨日收盘价 < 过去20日平均价

=>今天开盘卖出该股票


那怎么用代码说给计算机听呢?

老办法,先想清楚人要做的话是什么步骤,再一点点翻译成代码。


1.确定股票的范围
(计算姬:让我帮你观察,总要告诉我都观察谁吧!)

2.每天看看每一只股票昨日收盘价是否高出过去20日平均价,是的话开盘就买入,不是开盘就卖出。每天都这么做,循环下去。

(计算姬:哪个股票有动作,我就带着小钱们杀过去~)

3.接下来就按之前讲得基本框架的套路出牌就好了,即初始化加周期循环。
(计算姬:想要学习好,套路不能少~)


【用list数据类型初始化股票列表】

我们要确定股票的选择范围,此处举例就简单点只选两只股,比如 兔宝宝(002043) 和 好想你(002582)。代码如下:

def initialize(context):
   g.security = ['002043.XSHE','002582.XSHE']# 存入兔宝宝、好想你的股票代码

对比下,单股票策略中初始化代码是:

def initialize(context):
   g.security = '002043.XSHE'
   #存入兔宝宝的股票代码

可以看到,多个股票代码之间用逗号隔开了,并且两侧被中括号包在了一起。这种被中括号包在一起的数据的类型叫做list。形如:

[x1,x2,x3,...,xn]


当多个股票代码被包在一起成为一个list后就是一个整体,我们就可以给他们一起命名(例如此处命名是g.security)。就好像我们把多个股票代码包在一个盒子里,在盒子外面写上名字,以后计算机可以直接拿盒子来计算里面的股票,只要久跟她讲g.security,她就知道是那个盒子了,而不必把每个股票名字再一一交代。

PS:list的详细介绍 Python入门(2)- 数据类型之列表

初始化完成,开始周期循环的部分。


【for语句】

之前我们已经发现了,所谓的多股票策略,就是对多个股票逐个地实行单股票策略,所以对于所选股票只有两个的时候,只要把原本单股票策略对每个股票再写一遍就好了,比如这样:

def initialize(context):    g.security1 = '002043.XSHE'    g.security2 = '002582.XSHE'def handle_data(context, data):    last_price = data[g.security1].close    average_price = data[g.security1].mavg(20, 'close')    cash = context.portfolio.cash    if last_price > average_price:        order_value(g.security1, cash)    elif last_price < average_price:        order_target(g.security1, 0)    last_price = data[g.security2].close    average_price = data[g.security2].mavg(20, 'close')    cash = context.portfolio.cash    if last_price > average_price:        order_value(g.security2, cash)    elif last_price < average_price:        order_target(g.security2, 0)
                                           (
注释省略,详见推荐阅读)

基本上就是原来的单股票代码写两遍,两只股票写两遍,上千只股票的话还不写死掉...

所以我们要用到for,来告诉计算机,对多只股票都逐个进行相同的一系列的操作。for的用法如下:

# 把x中的数据依次取出暂时放入i中
# 其中x的数据类型需要是list。
for i in x:
               描述操作的代码

这段代码的含义可以理解成面试:“x”像一队等待面试的人,“i”像面试的房间,“操作”像面试的过程。

取出x中的第一个数据放到i中,进行操作。

(排在最前面的人进去面试,然后出来)

然后从x中再取出第二个数据覆盖掉i中原本的数据,进行操作。

(第二个人进去面试,然后出来)

如此继续,直到x中最后一个数据取到并进行操作。

(直到最后一个人面试完)


for应用在多股票策略中之后,策略就是:

def initialize(context):    # 存入兔宝宝、好想你 的股票代码    g.security = ['002043.XSHE','002582.XSHE']def handle_data(context, data):    # 把g.security中的股票代码依次取出
   # 逐个进行单股票均线策略    for i in g.security:        # 获取取得最近日收盘价,命名为last_price        last_price = data[i].close        # 获取近二十日股票收盘价的平均价
       # 命名为average_price        average_price=data[i].mavg(20,'close')        # 获取当前现金数量,命名为cash        cash = context.portfolio.cash        # 判断昨日收盘价是否高出二十日平均价
       # 是则买入,否则卖出。        if last_price > average_price:            order_value(i, cash)
           # 用per_cash的资金量买入股票i        elif last_price < average_price:            order_target(i, 0)
           # 将股票仓位调整到0,即全卖出

至此,已经是一个完整的可运行的策略了。

但是,我们应用原本单股票策略的买入卖出方法到多股票后,逻辑上会出现这样一种情况:只要多只股票中一只股票满足买入条件了,就用所有资金买入了。从而没有资金买别的股票了,即便余下的股票也有满足条件的,即策略一直最多持有一只股票。


当然,这种买入卖出逻辑并没什么错,但一般来说,多股票策略相比单股票的策略的优势,除了可以更大范围内的寻找机会外,能同时持有多只股票能帮助我们分散风险


故,我们有必要继续研究下每次花多少钱去买股票,使策略可同时持有多只股票。


PS:for的详细介绍 Python入门(5)条件与循环:if、while、for

QA:从x中取出的次序?x的数据类型是list,list类型里面的数据是有次序的,所以从x中取出的次序就是x里自带的次序。如for i in [2,7,3]的取出次序就是,如所见到的从左到右2,7,3的次序。([2,7,3]是个list)


【各个股票买多少?】

每次交易信号发生,不全额交易,该交易多少额度呢?这是个复杂的问题,每个人对于每个策略都可能有不同的看法,并无定法。此处只做简单的处理,即将资金按股票数量分配预留,哪只股票发出信号,就将该股票的那份资金全额交易。详细表述与代码如下:

1.将资金平分成两份("兔宝宝"一份,"好想你"一份),每份资金量为per_cash.

# cash除以g.security中的股票数,得到per_cashper_cash = cash/len(g.security)

QA:len(g.security)什么意思?len()是用来求list长度,即list中包含多少个东西。本例中len(g.security)就是求g.security中的股票数,结果为2。


 2.如果昨日收盘价高出二十日平均价, 则用per_cash的资金量买入的该股票;否则卖出全部该股票。翻译成代码:

if last_price > average_price:
   order_value(i, per_cash)# 用per_cash的资金量买入股票ielif last_price < average_price:
   order_target(i, 0)# 将股票i持有量调整到0,即全卖出


【策略写完,如何回测】

增加买入卖出的代码,策略就写完了,如下:

def initialize(context):
   # 存入兔宝宝、好想你 的股票代码
   g.security = ['002043.XSHE','002582.XSHE']def handle_data(context, data):# 把g.security中的股票代码依次取出,逐个进行单股票均线策略
   for i in g.security:
       # 获取取得最近日收盘价,命名为last_price
       last_price = data[i].close
       # 获取近二十日股票收盘价的平均价,命名为average_price
       average_price = data[i].mavg(20, 'close')
       # 获取当前现金数量,命名为cash
       cash = context.portfolio.cash
       # cash除以g.security中的股票数,得到per_cash
       per_cash = cash/len(g.security)
       # 如果昨日收盘价高出二十日平均价, 则买入,否则卖出。
       if last_price > average_price:
           order_value(i, cash)# 用当前所有资金买入股票
       elif last_price < average_price:
           order_target(i, 0)# 将股票仓位调整到0,即全卖出

现在,点击运行回测,如果你代码没有问题,就会顺利的进行回测,回测结果如下图:

至此,你就完成了一个简单策略的回测了。


QA:代码编辑区上方的“编译运行”按钮是什么?编译是简化版的回测,相比回测少做了很多统计工作,比如每日持仓,交易详情等,所以运行会快很多。所以策略前期需要反复调试的时候,点编译运行,而策略完善后需要生成详细的报告,就点运行回测。两个都试试就知道了。


【自测与自学】

1.能否理解并学会使用list数据类型。

2.能否理解并学会使用for语句。

3.试着调整多股票的数量,比如将选股范围调整为沪深300指数的成分股。(提示:使用获取指数成份股的API)

4.试着调整买入卖出条件,比如将买买卖条件变为:如果昨日收盘价高出二十日平均价5%, 则买入;如果昨日收盘价低出二十日平均价5%,则卖出。(提示:乘法的代码是" * ",a的5%用代码表示为:a * 0.05)



点击『阅读原文』,到JoinQuant社区参与讨论


长按指纹,关注JoinQuant

【声明】内容源于网络
0
0
JoinQuant聚宽
JoinQuant(聚宽)量化交易平台官方账号
内容 249
粉丝 0
JoinQuant聚宽 JoinQuant(聚宽)量化交易平台官方账号
总阅读202
粉丝0
内容249