请选择 进入手机版 | 继续访问电脑版
楼主: 唉人好累66
2161 3

[原创博文] 【干货分享】从零开始学量化:16二八轮动策略 [推广有奖]

  • 0关注
  • 41粉丝

讲师

55%

还不是VIP/贵宾

-

威望
1
论坛币
1457 个
通用积分
5.0477
学术水平
11 点
热心指数
14 点
信用等级
11 点
经验
3660 点
帖子
214
精华
0
在线时间
119 小时
注册时间
2016-9-24
最后登录
2020-4-8

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
1. 策略原理:
1)获取指数000300000905前一日收盘价以及前20日数据;
2)计算前20日变动;
3)获取ETF300510300)及ETF500510500)的持仓数据;
4
       a. 如果000300趋势下降且有持仓,则卖出ETF300
       b. 如果000905趋势下降且有持仓,则卖出ETF500
       c. 如果300指数增幅大于500指数增幅,且300指数增幅大于0,且ETF300ETF500无持仓,则买入ETF300
       d. 如果300指数增幅小于500指数增幅,且500指数增幅大于0,且ETF300ETF500无持仓,则买入ETF500

2. 代码解读:
   2.1 strategy.ini
  1. [strategy]
  2. username=
  3. password=
  4. mode=4
  5. td_addr=localhost:8001
  6. strategy_id=
  7. subscribe_symbols=SHSE.000300.bar.daily,SHSE.000905.bar.daily
  8. [backtest]
  9. start_time = 2015-05-01 09:00:00
  10. end_time = 2015-5-31 16:00:00
  11. ;策略初始资金
  12. initial_cash=1000000

  13. ;委托量成交比率,默认=1(每个委托100%成交)
  14. transaction_ratio=1

  15. ;手续费率,默认=0(不计算手续费)
  16. commission_ratio=0

  17. ;滑点比率,默认=0(无滑点)
  18. slippage_ratio=0

  19. [para]
  20. #bar_type=60
  21. window_size=20

  22. market_exchange_a=SHSE
  23. market_secid_a=000300

  24. market_exchange_b=SHSE
  25. market_secid_b=000905


  26. trade_exchange_a=SHSE
  27. trade_secid_a=510300
  28. trade_unit_a=100

  29. trade_exchange_b=SHSE
  30. trade_secid_b=510500
  31. trade_unit_b=100

  32. #hour=14
  33. #minute=53

  34. #sigma=2.34

  35. ##############################################################
  36. # logger settings
  37. ##############################################################
  38. [loggers]
  39. keys=root

  40. [logger_root]
  41. level=DEBUG
  42. handlers=console,file

  43. [handlers]
  44. keys=console,file

  45. [handler_file]
  46. class=handlers.RotatingFileHandler
  47. ;args=('strategy_sa.log','a','maxBytes=10000','backupCount=5')
  48. args=('strategy_sa.log','a',10000,5)
  49. formatter=simple

  50. [handler_console]
  51. class=StreamHandler
  52. args = (sys.stdout,)
  53. formatter=simple

  54. [formatters]
  55. keys = simple

  56. [formatter_simple]
  57. format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
  58. datefmt=
复制代码
   2.2 strategy.py
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Tue Jan 24 13:32:56 2017

  4. @author: Lenovo
  5. """

  6. #!/usr/bin/env python
  7. # encoding: utf-8

  8. from gmsdk.api import StrategyBase
  9. import numpy as np
  10. from collections import deque
  11. #from gmsdk import *
  12. #import arrow
  13. #from math import log

  14. eps = 1e-6

  15. class StatArb(StrategyBase):
  16.     '''
  17.         statistics arbitrage demo
  18.     '''
  19.     def __init__(self, *args, **kwargs):
  20.         #import pdb; pdb.set_trace()
  21.         super( StatArb, self).__init__(*args, **kwargs)
  22.         # 策略初始化工作在这里写,从外部读取静态数据,读取策略配置参数等工作,只在策略启动初始化时执行一次。

  23.         # 从配置文件中读取配置参数
  24.         self.market_exchange_a = self.config.get('para', 'market_exchange_a') or 'SHSE'
  25.         self.market_secid_a = self.config.get('para', 'market_secid_a') or '000300'
  26.         self.market_symbol_a = ".".join([self.market_exchange_a, self.market_secid_a])
  27.       

  28.         self.market_exchange_b = self.config.get('para', 'market_exchange_b') or 'SHSE'
  29.         self.market_secid_b = self.config.get('para', 'market_secid_b') or '000905'
  30.         self.market_symbol_b = ".".join([self.market_exchange_b, self.market_secid_b])
  31.          
  32.         
  33.         self.trade_exchange_a = self.config.get('para', 'trade_exchange_a') or 'SHSE'
  34.         self.trade_secid_a = self.config.get('para', 'trade_secid_a') or '510300'
  35.         self.trade_symbol_a = ".".join([self.trade_exchange_a, self.trade_secid_a])
  36.       

  37.         self.trade_exchange_b = self.config.get('para', 'trade_exchange_b') or 'SHSE'
  38.         self.trade_secid_b = self.config.get('para', 'trade_secid_b') or '510500'
  39.         self.trade_symbol_b = ".".join([self.trade_exchange_b, self.trade_secid_b])
  40.      

  41.        # self.hour = self.config.get('para','hour') or '14'
  42.        # self.minute = self.config.get('para','minute') or '53'

  43.         self.window_size = self.config.getint('para','window_size') or 20

  44.         self.trade_unit_a = self.config.getint('para','trade_unit_a') or 100
  45.         self.trade_unit_b = self.config.getint('para','trade_unit_b') or 100
  46.    
  47.                
  48.         self.closes_a_buffer = deque(maxlen=self.window_size)
  49.         self.closes_b_buffer = deque(maxlen=self.window_size)
  50.         
  51.         last_closes_a = [bar.close for bar in self.get_last_n_dailybars(self.market_symbol_a,self.window_size,end_time=self.start_time)]
  52.         last_closes_a.reverse()
  53.       
  54.         last_closes_b = [bar.close for bar in self.get_last_n_dailybars(self.market_symbol_b,self.window_size,end_time=self.start_time)]
  55.         last_closes_b.reverse()
  56.       
  57.         self.closes_a_buffer.extend(last_closes_a)
  58.         self.closes_b_buffer.extend(last_closes_b)

  59.     def on_bar(self, bar):
  60.         if bar.sec_id == self.market_secid_a:
  61.             self.closes_a_buffer.append(bar.close)
  62.             self.last_price_a = bar.close
  63.         elif bar.sec_id == self.market_secid_b:
  64.             self.closes_b_buffer.append(bar.close)
  65.             self.last_price_b = bar.close
  66.        # t=arrow.get(bar.utc_time)
  67.        # if t.hour == self.hour and t.minute == self.minute:
  68.         self.algo_action()
  69.     def open_side_a(self):
  70.         self.open_long(self.trade_exchange_a, self.trade_secid_a, self.last_price_a, self.trade_unit_a)
  71.         #self.open_long(self.trade_exchange_a, self.trade_secid_a, 0, self.trade_unit_a)
  72.      
  73.     def open_side_b(self):     
  74.         self.open_long(self.trade_exchange_b, self.trade_secid_b, self.last_price_b, self.trade_unit_b)
  75.        # self.open_long(self.trade_exchange_b, self.trade_secid_b, 0, self.trade_unit_b)

  76.     def close_side_a(self):
  77.         Position_a = self.get_position(self.trade_exchange_a,self.trade_secid_a,1)
  78.         self.close_long(self.trade_exchange_a, self.trade_secid_a, self.last_price_a, Position_a.volume)
  79.        # self.close_long(self.trade_exchange_a, self.trade_secid_a, 0, Position_a.volume)
  80.         
  81.     def close_side_b(self):
  82.         Position_b = self.get_position(self.trade_exchange_b,self.trade_secid_b,1)
  83.         self.close_long(self.trade_exchange_b, self.trade_secid_b, self.last_price_b, Position_b.volume)
  84.         #self.close_long(self.trade_exchange_b, self.trade_secid_b, 0, Position_b.volume)

  85.     def algo_action(self):
  86.         close_a = np.asarray(self.closes_a_buffer)
  87.         close_b = np.asarray(self.closes_b_buffer)
  88.         Change_a = (close_a[self.window_size-1]-close_a[0])/close_a[0]
  89.         Change_b = (close_b[self.window_size-1]-close_b[0])/close_b[0]
  90.         Position_a = self.get_position(self.trade_exchange_a,self.trade_secid_a,1)
  91.         Position_b = self.get_position(self.trade_exchange_b,self.trade_secid_b,1)
  92.         av = Position_a.volume if Position_a else 0
  93.         bv = Position_b.volume if Position_b else 0
  94.         diff = Change_a - Change_b   
  95.         if diff > eps and Change_a > 0 and av == 0 and bv == 0:
  96.             self.open_side_a()
  97.         elif diff < eps and Change_b > 0 and av == 0 and bv == 0:
  98.             self.open_side_b()
  99.         elif Change_a < 0 and av > 0:
  100.             self.close_side_a()
  101.         elif Change_b < 0 and bv > 0:
  102.             self.close_side_b()
  103.    
  104. if __name__ == '__main__':
  105.     #import pdb; pdb.set_trace()
  106.     dm = StatArb(config_file='strategy.ini')
  107.     ret = dm.run()
  108.     print ("Statistics Arbitrage: ", ret, dm.get_strerror(ret))
复制代码


3. Python相关函数

   3.1 Python标准函数:

功能函数原型参数返回值
参数名含义
join连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串。'sep'.join(seq)sep分隔符。可以为空返回一个以分隔符sep连接各个元素后生成的字符串
seq要连接的元素序列、字符串、元组、字典
dequePython标准库collections中的一项. 它提供了两端都可以操作的序列, 这意味着, 你可以在序列前后都执行添加或删除。deque()


reverse用于反向列表中元素。list.reverse()

该方法没有返回值,但是会对列表的元素进行反向排序。
extend该方法没有返回值,但是会对列表的元素进行反向排序。list.extend(seq)seq元素列表。该方法没有返回值,但会在已存在的列表中添加新的列表内容。
append用于在列表末尾添加新的对象。list.append(obj)obj添加到列表末尾的对象。该方法无返回值,但是会修改原来的列表。


   3.2 掘金接口函数:

功能函数原型参数返回值
参数名类型说明
on_bar响应Bar事件,收到Bar数据后本函数被调用。on_bar(bar)barbarbar数据
get_last_n_dailybars提取单个代码的最新n条DailyBar数据, 策略类和行情服务类都提供该接口。get_last_n_dailybars(symbol, n, end_time='')symbolstring证券代码, 带交易所代码以确保唯一,如SHSE.600000bar列表
nint提取的数据条数
end_timestring指定截止时间, 如2015-10-30 15:00:00
get_positions查询当前策略指定symbol(由交易所代码和证券ID组成)和买卖方向的持仓信息。策略类和交易服务类都提供该接口。get_position(exchange, sec_id, side);exchangestring交易所代码Position对象,持仓信息
sec_idstring证券代码
sideint买卖方向
open_long异步开多仓,以参数指定的symbol、价和量下单。如果价格为0,为市价单,否则为限价单。策略类和交易服务类都提供该接口。open_long(exchange, sec_id, price, volume)exchangestring交易所代码, 如上交所SHSE委托下单生成的Order对象
sec_idstring证券代码,如浦发银行600000
pricefloat委托价,如果price=0,为市价单,否则为限价单
volumefloat委托量
close_long异步平多仓接口,以参数指定exchange, 证券代码sec_id, 价和量下单。如果价格为0,为市价单,否则为限价单。策略类和交易服务类都提供该接口。close_long(exchange, sec_id, price, volume)exchangestring交易所代码, 如上交所SHSE委托下单生成的Order对象
sec_idstring证券代码,如浦发银行600000
pricefloat委托价,如果price=0,为市价单,否则为限价单
volumefloat平仓量


4. 金融术语
二八轮动策略是基于A股市场中大盘股和小盘股走势作为信号的策略。“二”指的是权重股,大盘股;“八”指的是中小盘股,非权重股。“轮动”指的是大盘股和中小盘股之间的相互切换。一般情况下,沪深300走势表示大盘股的整体走势,中证500指数综合反映沪深证券市场内小市值公司的整体状况。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:从零开始 collections Transaction Collection Statistics

已有 1 人评分经验 收起 理由
残阳_等待 + 60 精彩帖子

总评分: 经验 + 60   查看全部评分

西门高 发表于 2017-8-3 09:31:59 |显示全部楼层 |坛友微信交流群
谢谢分享
已有 1 人评分经验 收起 理由
残阳_等待 + 20 精彩帖子

总评分: 经验 + 20   查看全部评分

使用道具

西门高 发表于 2017-8-3 09:31
谢谢分享
不客气、后续还有一系列干货分享多多关注哈

使用道具

顶顶顶~好贴莫沉

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-3-29 14:57