量化投资笔记(一)

基本格式与下单函数

为了将投资灵感高效地转化成计算机可执行的量化策略,必须基于一种模式来写,框架就是指这种模式。而此框架包含两个部分即初始化与周期循环:

  • 初始化即指策略最开始运行前要做的事。比如,准备好要交易的股票。
  • 周期循环即指策略开始后,随着时间一周期一周期地流逝时,每个周期要做的事。如下例中,周期为天,周期循环的则是每天买100股的平安银行。

其实人本身日常做交易就是符合“初始化+周期循环”框架的,初始化就是已存在人脑的交易思想与知识,周期循环就是每天或每分钟地查看行情、判断、下单等行为。

def initialize(context):#初始化函数
    run_daily(period,time='every_bar')#运行函数
    g.security = '000001.XSHE'#g转换为全局变量
def period(context):#周期函数
    order(g.security, 100)#下单函数

run_daily(func, time=‘9:30’, reference_security)函数:每天内何时运行,func是一个自定义的函数,此函数必须接受context参数,例如自定义函数period(context);time是具体执行时间,time="every_bar"按天会在交易日的开盘时调用一次,按分钟会在交易时间每分钟运行;reference_security是时间的参照标的代码,字符串类型,默认为‘000001.XSHG’。期货策略一定要修改参考标的,建议修改为对应的主力合约。

API:即应用程序编程接口,量化平台的函数,在API文档中查阅。下单函数主要有:

#按股数下单函数
order("000001.XSHE",100)
#参数有5个,分别是security,amount,style,side,pindex。
#深交所(0开头)股票代码后缀为.XSHE,上交所股票代码(6开头)后缀为.XSHG
#amout有正负,最小为1股100手
#style默认市价,side默认多头,pindex选资金仓位
order_target(security,amount)
#含义是通过买卖,将股票仓位稳定在一定数量(单位:股)
order_value(security,value)
#含义是买卖一定价值量(单位:元)股票。比如P=9,V=1万,大概买入1100股
order_target_value(security,value)
#通过买卖,将股票仓位稳定在一定价值量(单位:元)

读取context中的数据

context是一个回测系统建立的Context类型的对象,其中存储了如当前策略运行的时间点、所持有的股票、数量、持仓成本等数据。
在这里插入图片描述

 # context.portfolio.positions的含义是仓位信息,所以为了让它有数据,需要在取之前买入并持有股票。

 def initialize(context):
     run_daily(period,time='every_bar')
     g.security = '000001.XSHE'

 def period(context):
     order(g.security, 100)
     # 打印所有键
     print(context.portfolio.positions.keys())
     # 打印所有值
     print(context.portfolio.positions.values())
     # 打印g.security的开仓均价
     print(context.portfolio.positions[g.security].avg_cost)

  # 执行后日志内容如下
  # ['000001.XSHE']
  # [UserPosition({'avg_cost': 8.539999999999997, 'security': '000001.XSHE', 'closeable_amount': 0, 'price': 8.53, 'total_amount': 100})]
  # 8.54

止损

通过context的数据可以得到持有股票的成本和现价,从而可以算出该股票的盈亏情况,运用条件判断语句根据盈亏情况从而决定是否卖出股票,从而实现止损操作,代码如下:

def initialize(context):
    run_daily(period,time='every_bar')
    g.security = '000001.XSHE'

def period(context):
    # 买入股票
    order(g.security, 100)
    # 获得股票持仓成本
    cost=context.portfolio.positions['000001.XSHE'].avg_cost
    # 获得股票现价
    price=context.portfolio.positions['000001.XSHE'].price
    # 计算收益率
    ret=price/cost-1
    # 打印日志
    print('成本价:%s' % cost)
    print('现价:%s' % price)
    print('收益率:%s' % ret)
    # 如果收益率小于-0.01,即亏损达到1%则卖出股票,幅度可以自己调,一般10%
    if ret<-0.01:
        order_target('000001.XSHE',0)#调整仓位价值为0
        print('触发止损')

止盈的思路也一样,将判断条件改一下即可。比如在23号触发了止损,至23号持有了1700股,由于该日买入了100股,实际上平仓的只有1600股(T+1),平仓以后还剩今天买的100股,若24号未触及平仓则总持仓量为200股。

多股票策略

def initialize(context):
    run_daily(period,time='every_bar')
    # 把两个股票代码作为list存入g.security中
    g.security = ['000001.XSHE','000002.XSHE']

def period(context):
    for stk in g.security:
        order(stk,100)
        # 获得股票持仓成本
        cost=context.portfolio.positions[stk].avg_cost
        # 获得股票现价
        price=context.portfolio.positions[stk].price
        # 计算收益率
        ret=price/cost-1
        # 如果收益率小于-0.01,即亏损达到1%则卖出股票,幅度可以自己调,一般10%
        if ret<-0.01:
            order_target(stk,0)
            print('触发止损')

获取典型常用数据

在聚宽的python版API中,用ctrl+f进行网页搜索可以快速搜索需要的数据。

获取指数成分股

# 获取20180301时,上证50指数(000016.XSHG)成分股
t=get_index_stocks("000016.XSHG","2018-03-01")
print(t[0])
print(t)

# 打印日志如下。股票代码在list中被打印出来前面会带有的u代表是对字符串进行unicode编码,只是显示效果,单独打印t[0]时就没有u。
# 600000.XSHG
#[u'600000.XSHG', u'600016.XSHG', u'600019.XSHG', u'600028.XSHG', u'600029.XSHG', u'600030.XSHG', u'600036.XSHG', u'600048.XSHG', u'600050.XSHG', u'600104.XSHG', u'600111.XSHG', u'600309.XSHG', u'600340.XSHG', u'600518.XSHG', u'600519.XSHG', u'600547.XSHG', u'600606.XSHG', u'600837.XSHG', u'600887.XSHG', u'600919.XSHG', u'600958.XSHG', u'600999.XSHG', u'601006.XSHG', u'601088.XSHG', u'601166.XSHG', u'601169.XSHG', u'601186.XSHG', u'601211.XSHG', u'601229.XSHG', u'601288.XSHG', u'601318.XSHG', u'601328.XSHG', u'601336.XSHG', u'601390.XSHG', u'601398.XSHG', u'601601.XSHG', u'601628.XSHG', u'601668.XSHG', u'601669.XSHG', u'601688.XSHG', u'601766.XSHG', u'601800.XSHG', u'601818.XSHG', u'601857.XSHG', u'601878.XSHG', u'601881.XSHG', u'601985.XSHG', u'601988.XSHG', u'601989.XSHG', u'603993.XSHG']

获取股票行情数据

history可以同时获得多个股票的数据,但只能获得相同的一个数据字段。如获得平安银行,建设银行,农业银行这3只股票,前3天的交易额。history(count, unit=‘1d’, field=‘avg’, security_list=None, df=True, skip_paused=False, fq=‘pre’)

  • count代表展示的行数;
  • unit表示单位时间长度,隔几天或者几分钟,现在支持’Xd’、‘Xm’,X是一个正整数,分别表示X天和X分钟;
  • field: 要获取的数据类型,包含:[‘open’, ’ close’, ‘low’, ‘high’, ‘volume’, ‘money’, ‘factor’, ‘high_limit’,’ low_limit’, ‘avg’, ’ pre_close’, ‘paused’];
  • security_list要获取数据的股票列表;
  • df: 若是True, 返回[pandas.DataFrame], 否则返回一个dict;
  • skip_paused: 是否跳过不交易日期,默认不跳过;
  • fq: 复权选项,默认前复权。
w=history(count=3,unit='5d',field='close', security_list=['000001.XSHE','000002.XSHE'])
print(w)
'''               000001.XSHE  000002.XSHE
2017-03-09         9.01        18.35
2017-03-16         9.15        19.03
2017-03-23         8.84        19.19'''

上述代码中,选择回测时间为2017-3-24,那么就挑出该日之前的3天数据。

attribute_history只能获取单独一个股票的多个字段的数据。如获得平安银行这一只股票,前3天的交易额,交易量,最高价,最低价等。

w=attribute_history(security='000001.XSHE',count=3, fields=['money','high','close'])
print(w)
# 按位置获取某几列.iloc[:,[位置,...]],位置的含义是第几个,从0开始。下文同。
print(w.iloc[:,[0,2]])
'''                 money  high  close
2017-03-21  5.119143e+08  8.90   8.88
2017-03-22  5.193310e+08  8.86   8.80
2017-03-23  3.989866e+08  8.88   8.84

                    money  close
2017-03-21  5.119143e+08   8.88
2017-03-22  5.193310e+08   8.80
2017-03-23  3.989866e+08   8.84'''

获取股票财务数据

get_fundamentals(query_object, date=None, statDate=None),表和字段可以在财务数据文档查看

  • query_object参数是要求传入一个Query对象用于描述所需的数据,这里提供一个快速上手的模板用来产生query_object参数,多数情况下往里套就可以了;

  • date: 查询日期,一个字符串(格式类似’2015-10-15’),传入date时,查询指定日期date收盘后所能看到的最近(对市值表来说, 最近一天, 对其他表来说, 最近一个季度)的数据, 我们会查找上市公司在这个日期之前(包括此日期)发布的数据, 不会有未来函数;

  • statDate: 查询 statDate 指定的季度或者年份的财务数据,财报统计的季度或者年份,有两种格式:季度格式例如’2015q1’,‘2013q4’;年份格式例如: ‘2015’,‘2016’;

  • date和statDate参数只能同时传入其中一个。当 date 和 statDate 都不传入时,相当于使用 date 参数,date 的默认值为回测日期的前一天。

# 快速上手模板
query(.字段).filter(筛选条件).order_by(排序方法).limit(数量上限)
#比较长的话可以分行写
# 例子
# 获取 市值表.股票代码,资产负债表.未分配利润
q=query(valuation.code,balance.retained_profit
# 筛选 市值大于100 并且 市盈率小于10
).filter(valuation.market_cap>100,valuation.pe_ratio < 10
# 排序 按市值从大到小排
).order_by(valuation.market_cap.desc()
# 数量 上限10条数据
).limit(10)
w=get_fundamentals(q)
print(w)
'''2017-03-24 00:00:00 - INFO  -      code  retained_profit
0  601398.XSHG     9.210480e+11
1  601939.XSHG     7.730580e+11
2  601988.XSHG     5.591120e+11
3  601288.XSHG     4.871250e+11
4  600036.XSHG     1.980190e+11
5  601328.XSHG     9.299600e+10
6  600000.XSHG     8.579200e+10
7  601998.XSHG     1.366660e+11
8  600016.XSHG     1.324380e+11
9  601166.XSHG     1.728410e+11'''

查找上证指数成分股中流通市值最大的5个股票的股票代码:

t=get_index_stocks("000001.XSHG")
q=query(valuation.code).filter(valuation.code.in_(t)
).order_by(valuation.circulating_market_cap.desc()).limit(5)
print(get_fundamentals(q).values)
'''[[601857.XSHG]
 [601398.XSHG]
 [601288.XSHG]
 [601988.XSHG]
 [600028.XSHG]]'''

参考文献

https://www.joinquant.com/view/community/detail/8ec7aaaa899cf928550f89a104637f22?type=1

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值