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

[原创博文] 【干货分享】从零开始学量化:07R_Breaker策略 [推广有奖]

  • 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. 策略原理:
      R-Breaker是个经典的具有长生命周期的日内模型。
类型:日内趋势追踪+反转策略
周期:1分钟、5分钟
根据前一个交易日的收盘价、最高价和最低价数据通过一定方式计算出六个价位,
从大到小依次为:
突破买入价(buy_break)、观察卖出价(sell_setup)、
反转卖出价(sell_enter)、反转买入价(buy_enter)、
观察买入价(buy_setup)、突破卖出价(sell_break)
以此来形成当前交易日盘中交易的触发条件。

交易规则:
反转:
持多单,当日内最高价超过观察卖出价后,盘中价格出现回落,且进一步跌破反转卖出价构成的支撑线时,采取反转策略,即在该点位反手做空;
持空单,当日内最低价低于观察买入价后,盘中价格出现反弹,且进一步超过反转买入价构成的阻力线时,采取反转策略,即在该点位反手做多;
突破:
在空仓的情况下,如果盘中价格超过突破买入价,则采取趋势策略,即在该点位开仓做多;
在空仓的情况下,如果盘中价格跌破突破卖出价,则采取趋势策略,即在该点位开仓做空;
2. 代码解读:
2.1 R_Breaker.ini
  1. [strategy]
  2. ;td_addr=localhost:8001

  3. username=

  4. password=

  5. strategy_id=
  6. ;模拟状态
  7. mode=4
  8. ;订阅代码注意及时更新
  9. subscribe_symbols=CFFEX.IF1703.tick,CFFEX.IF1703.bar.60

  10. [backtest]
  11. start_time=2017-06-15 09:00:00

  12. end_time=2017-07-07 15:00:00

  13. initial_cash=10000000

  14. transaction_ratio=1

  15. commission_ratio=0

  16. slippage_ratio=0


  17. [para]
  18. trade_symbol=CFFEX.IF1703

  19. begin_time = 09:30:00

  20. end_time = 14:55:00

  21. observe_size =0.35

  22. reversal_size = 0.07

  23. break_size = 0.25
复制代码
2.2 R_Breaker.py
  1. # encoding: utf-8

  2. from gmsdk.api import StrategyBase
  3. from gmsdk import md
  4. from gmsdk.enums import *
  5. import arrow
  6. import time

  7. # 每次开仓量
  8. OPEN_VOL = 5

  9. class R_Breaker(StrategyBase):
  10.     def __init__(self, *args, **kwargs):
  11.         super(R_Breaker, self).__init__(*args, **kwargs)
  12.         self.__get_param()
  13.         self.__init_data()

  14.     def __get_param(self):
  15.         '''
  16.         获取配置参数
  17.         '''

  18.         self.trade_symbol = self.config.get('para', 'trade_symbol')
  19.         pos = self.trade_symbol.find('.')
  20.         # 策略的一些阀值
  21.         self.exchange = self.trade_symbol[:pos]
  22.         self.sec_id = self.trade_symbol[pos + 1:]
  23.         self.observe_size = self.config.getfloat('para', 'observe_size')
  24.         self.reversal_size = self.config.getfloat('para', 'reversal_size')
  25.         self.break_size = self.config.getfloat('para', 'break_size')

  26.         # 交易开始和结束时间
  27.         FMT = '%sT%s'
  28.         today = arrow.now().date()
  29.         begin_time = self.config.get('para', 'begin_time')
  30.         et = FMT % (today.isoformat(), begin_time)
  31.         self.begin_trading = arrow.get(et).replace(tzinfo='local').timestamp
  32.         end_time = self.config.get('para', 'end_time')
  33.         et = FMT % (today.isoformat(), end_time)
  34.         self.end_trading = arrow.get(et).replace(tzinfo='local').timestamp
  35.         print((begin_time,end_time))
  36.         print("start time %s, end time %s" % (self.begin_trading, self.end_trading))

  37.     def __init_data(self):
  38.         '''
  39.         提取数据,计算价位
  40.         '''

  41.         prev_dailybar = self.get_last_dailybars(self.trade_symbol)

  42.         if len(prev_dailybar) < 1:
  43.             return

  44.         self.prev_high = prev_dailybar[0].high
  45.         self.prev_low = prev_dailybar[0].low
  46.         self.prev_close = prev_dailybar[0].close

  47.         self.high = self.prev_close
  48.         self.low = self.prev_close
  49.         self.close = self.prev_close

  50.         # 观察卖出价
  51.         self.sell_setup = self.prev_high + self.observe_size * (self.prev_close - self.prev_low)
  52.         print('sell_setup price: %s' % self.sell_setup)

  53.         # 反转卖出价
  54.         self.sell_enter = (1 + self.reversal_size) / 2 * (
  55.         self.prev_high + self.prev_low) - self.reversal_size * self.prev_low
  56.         print('sell_enter price:%s' % self.sell_enter)

  57.         # 反转买入价
  58.         self.buy_enter = (1 + self.reversal_size) / 2 * (
  59.         self.prev_high + self.prev_low) - self.reversal_size * self.prev_high
  60.         print('buy_enter price:%s' % self.buy_enter)

  61.         # 观察买入价
  62.         self.buy_setup = self.prev_low - self.observe_size * (self.prev_high - self.prev_close)
  63.         print('buy_setup:%s' % self.buy_setup)

  64.         # 突破买入价
  65.         self.buy_break = self.sell_setup + self.break_size * (self.sell_setup - self.buy_setup)
  66.         print('buy_break:%s' % self.buy_break)

  67.         # 突破卖出价
  68.         self.sell_break = self.buy_setup + self.break_size * (self.sell_setup - self.buy_setup)
  69.         print('sell_break:%s' % self.sell_break)

  70.         self.bid_holding = 0.0
  71.         position = self.get_position(self.exchange, self.sec_id, OrderSide_Bid);
  72.         if position is not None:
  73.             self.bid_holding = position.volume
  74.             print((self.bid_holding))

  75.         self.ask_holding = 0.0
  76.         position = self.get_position(self.exchange, self.sec_id, OrderSide_Ask)
  77.         if position is not None:
  78.             self.ask_holding = position.volume

  79.     def on_tick(self, tick):
  80.         '''
  81.         tick行情事件
  82.         '''

  83.         # 即时获取当天高、低、现价
  84.         self.high = tick.high
  85.         self.low = tick.low
  86.         self.close = tick.last_price

  87.     def on_bar(self, bar):
  88.         '''
  89.         bar周期数据事件
  90.         '''

  91.         x = time.localtime(bar.utc_time)
  92.         bartime =  (time.strftime('%H:%M:%S',x))
  93.         y = time.localtime(self.begin_trading)
  94.         begin_trading = (time.strftime('%H:%M:%S',y))
  95.         z = time.localtime(self.end_trading)
  96.         end_trading = (time.strftime('%H:%M:%S',z))


  97.         if bartime > begin_trading and bartime < end_trading:


  98.             if self.close > self.buy_break and self.bid_holding < 1:
  99.                 # 空仓做多
  100.                 self.open_long(self.exchange, self.sec_id, self.close, OPEN_VOL)
  101.                 print('open long: price %s, vol %s' % (self.close, OPEN_VOL))
  102.             elif self.close < self.sell_break and self.ask_holding < 1:
  103.                 # 空仓做空
  104.                 self.open_short(self.exchange, self.sec_id, self.close, OPEN_VOL)
  105.                 print('open short: price %s, vol %s' % (self.close, OPEN_VOL))
  106.             elif self.bid_holding > 0 and self.high > self.sell_setup and self.close < self.sell_enter:
  107.                 # 多单反转
  108.                 self.close_long(self.exchange, self.sec_id, self.close, self.bid_holding)
  109.                 print('close long: price %s, vol %s' % (self.close, self.bid_holding))

  110.                 self.open_short(self.exchange, self.sec_id, self.close, OPEN_VOL)
  111.                 print('Reverse open short: price %s, vol %s' % (self.close, OPEN_VOL))

  112.             elif self.ask_holding > 0 and self.low < self.buy_setup and self.close > self.buy_enter:
  113.                 # 空单反转
  114.                 self.close_short(self.exchange, self.sec_id, self.close, self.ask_holding)
  115.                 print('close short: price %s, vol %s' % (self.close, self.ask_holding))

  116.                 self.open_long(self.exchange, self.sec_id, self.close, OPEN_VOL)
  117.                 print('Reverse open long: price %s, vol %s' % (self.close, OPEN_VOL))

  118.         if bartime > end_trading:
  119.             # 日内平仓
  120.             if self.bid_holding > 0:
  121.                 self.close_long(self.exchange, self.sec_id, 0, self.bid_holding)
  122.             elif self.ask_holding > 0:
  123.                 self.close_short(self.exchange, self.sec_id, 0, self.ask_holding)


  124.     def on_execrpt(self, rpt):
  125.         '''
  126.          委托回报事件回调
  127.         '''

  128.         if rpt.exec_type != ExecType_Trade:
  129.             return

  130.     # 从成交回报累计持仓量
  131.         if PositionEffect_Open == rpt.position_effect and OrderSide_Bid == rpt.side:
  132.             self.bid_holding += rpt.volume

  133.         elif PositionEffect_Open == rpt.position_effect and OrderSide_Ask == rpt.side:
  134.             self.ask_holding += rpt.volume
  135.             print ('self.ask_holding')
  136.         elif PositionEffect_Close == rpt.position_effect and OrderSide_Bid == rpt.side:
  137.             self.bid_holding -= rpt.volume
  138.         elif PositionEffect_Close == rpt.position_effect and OrderSide_Ask == rpt.side:
  139.             self.ask_holding -= rpt.volume


  140. if __name__ == '__main__':
  141.     r_breaker = R_Breaker(config_file='R_Breaker.ini')
  142.     ret = r_breaker.run()
  143. print(r_breaker.get_strerror(ret))
复制代码
3. Python相关函数
3.1 Python标准函数:
功能函数原型参数返回值
参数名含义
find检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,如果包含子字符串返回开始的索引值,否则返回-1。str.find(str, beg=0, end=len(string))str指定检索的字符串。如果包含子字符串返回开始的索引值,否则返回-1。
beg开始索引,默认为0。
end结束索引,默认为字符串的长度。
arrowArrow是一个专门处理时间和日期的轻量级Python库,它提供了一种合理、智能的方式来创建、操作、格式化、转换时间和日期。转换为Arrow对象后,我们可以很方便的获取我们想要的各种时间数据,通过year、month、day、hour、minute、second、week等属性。
time.localtime()将一个时间戳转换为当前时区的struct_time。time.localtime([secs])secs若未提供,则以当前时间为准。
time.gmtime()是将一个时间戳转换为UTC时区(0时区)的struct_time。time.gmtime([secs])secs若未提供,则以当前时间为准。
time.time返回当前时间的时间戳。time.time()
time.mktime将一个struct_time转化为时间戳。time.mktime()
time.sleep线程推迟指定的时间运行。单位为秒。time.sleep()
time.asctime把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。time.asctime([t])t如果没有参数,将会将time.localtime()作为参数传入。
time.ctime把一个时间戳(按秒计算的浮点数)转化time.asctime()的形式。time.ctime如果参数未给或者为None的时候,将会默认time.time()
为参数。它的作用相当于time.asctime(time.localtime(secs))。
time.clock这个需要注意,在不同的系统上含义不同。在UNIX系统上,它返回的是“进程时间”,它是用秒表示的浮点数(时间戳)。而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行时间。(实际上是以WIN32上QueryPerformanceCounter()为基础,它比毫秒表示更为精确)time.clock()
len返回对象(字符、列表、元组等)长度或项目个数。len(s)s对象返回对象长度。


3.2 掘金接口函数:
功能函数原型参数返回值
参数名类型说明
on_bar响应Bar事件,收到Bar数据后本函数被调用。on_bar(bar)barbarbar数据
on_tick响应Tick事件,收到Tick数据后本函数被调用。on_tick(tick)tickticktick数据
on_execrpt响应委托执行回报事件,收到Execution数据后本函数被调用。on_execrpt(rpt)rptExecRpt
get_last_dailybars提取最新1条DailyBar数据,支持单个代码提取或多个代码组合提取。策略类和行情服务类都提供该接口。get_last_dailybars(symbol_list)symbolstring证券代码, 带交易所代码以确保唯一,如SHSE.600000,同时支持多只代码DailyBar列表
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_short异步平空仓接口,以参数指定exchange, 证券代码sec_id, 价和量下单。如果价格为0,为市价单,否则为限价单。策略类和交易服务类都提供该接口。close_short(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平仓量
open_short异步开空仓接口,以参数指定的exchange, 证券代码sec_id, 价和量下单。如果价格为0,为市价单,否则为限价单。策略类和交易服务类都提供该接口。open_short(exchange, sec_id, price, volume)exchangestring交易所代码, 如上交所SHSE委托下单生成的Order对象
sec_idstring证券代码,如浦发银行600000
pricefloat委托价,如果price=0,为市价单,否则为限价单
volumefloat平仓量


4. 金融术语
R-Breaker是个经典的具有长生命周期的日内模型。曾14年排名Future Trust杂志年度前10最赚钱的策略。R-Breaker交易规则示意图如下图:


二维码

扫码加我 拉你入群

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

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

关键词:从零开始 performance Transaction Commission exchanges

屏幕快照 2017-07-27 上午10.34.29.png
后续还会继续上干货策略,好东西希望和大家一起分享,如果想了解更多精彩的量化方面的内容进入证经社——http://***/q/forum.php?gid=36了解更多吧~

使用道具

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

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

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

GMT+8, 2024-4-18 20:54