HS300_SimplifiedSpiderGridTrading.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # 克隆自聚宽文章:https://www.joinquant.com/post/36687
  2. # 标题:股指期货-简化版蜘蛛网策略
  3. # 作者:宋兵乙
  4. # 导入函数库
  5. from six import BytesIO
  6. import numpy as np
  7. import pandas as pd
  8. import talib as ta
  9. from jqdata import finance
  10. from datetime import datetime, timedelta
  11. ## 初始化函数,设定基准等等
  12. def initialize(context):
  13. # 设定沪深300作为基准
  14. set_benchmark('000300.XSHG')
  15. # 开启动态复权模式(真实价格)
  16. set_option('use_real_price', True)
  17. # 过滤掉order系列API产生的比error级别低的log
  18. log.set_level('order', 'error')
  19. # 输出内容到日志 log.info()
  20. log.info('初始函数开始运行且全局只运行一次')
  21. set_subportfolios([SubPortfolioConfig(cash=context.portfolio.starting_cash, type='index_futures')])
  22. set_order_cost(OrderCost(open_commission=0.000023, close_commission=0.000023,close_today_commission=0.0004), type='index_futures')
  23. set_option('futures_margin_rate', 0.17)
  24. set_slippage(StepRelatedSlippage(4))
  25. g.close_long = []
  26. g.close_short = []
  27. g.open_long = []
  28. g.open_short = []
  29. g.times = 3
  30. run_daily(cal_signal, time='20:30')
  31. run_daily(trade, time='09:32')
  32. ## 开盘前运行函数
  33. def set_parameter():
  34. ## 设置交易品种
  35. g.symbol_list = [
  36. 'IH',
  37. ]
  38. ## 设置品种乘数
  39. g.muliti_dict = {
  40. ## 中金所
  41. 'IF':300, 'TF':10000, 'IC':200, 'IH':300,
  42. }
  43. ## 开盘前20:30:00运行函数
  44. def cal_signal(context):
  45. # 参数设置
  46. set_parameter()
  47. # 创建保持计算结果的DataFrame
  48. g.signal_df = pd.DataFrame(columns=['期货代码','交易信号','手数'])
  49. ## 获取当前持仓
  50. g.short_holds = context.portfolio.short_positions.keys()
  51. g.long_holds = context.portfolio.long_positions.keys()
  52. for symbol in g.symbol_list:
  53. ## 获取主力合约
  54. symbol_dominant = get_dominant_future(symbol)
  55. if len(symbol_dominant) == 0:
  56. continue
  57. # # 获取品种持仓状况
  58. if symbol_dominant in g.short_holds:
  59. hold_signal = -1
  60. # 查看多单仓位情况
  61. elif symbol_dominant in g.long_holds:
  62. hold_signal = 1
  63. else:
  64. hold_signal = 0
  65. ## 现在的自然日日期
  66. date = context.current_dt.strftime('%Y%m%d')
  67. ## 获取主力合约价格
  68. current_time = context.current_dt
  69. price_data = get_price(symbol_dominant, end_date=current_time, frequency='1d',
  70. fields=['close'], count = 10)
  71. dominant_price = price_data['close'][-1]
  72. # 获取所有合约
  73. contract_all = get_future_contracts(symbol, current_time)
  74. # print('contract_all: ', contract_all)
  75. long_hold_delta = 0
  76. short_hold_delta = 0
  77. for contract in contract_all:
  78. q=query(finance.FUT_MEMBER_POSITION_RANK.day,
  79. finance.FUT_MEMBER_POSITION_RANK.code,
  80. finance.FUT_MEMBER_POSITION_RANK.rank_type,
  81. finance.FUT_MEMBER_POSITION_RANK.rank,
  82. finance.FUT_MEMBER_POSITION_RANK.member_name,
  83. finance.FUT_MEMBER_POSITION_RANK.indicator,
  84. finance.FUT_MEMBER_POSITION_RANK.indicator_increase).\
  85. filter(finance.FUT_MEMBER_POSITION_RANK.code==contract,
  86. finance.FUT_MEMBER_POSITION_RANK.day==date)
  87. df=finance.run_query(q)
  88. #数据分离,分别按多单持有量与空单持有量排序
  89. df1 = df[df['rank_type']=='持买单量排名']
  90. df2 = df[df['rank_type']=='持卖单量排名']
  91. #分别计算多、空持仓前二十会员的多仓增量与空仓增量
  92. long_hold_delta = long_hold_delta + df1[:20]['indicator_increase'].sum()
  93. short_hold_delta = short_hold_delta + df2[:20]['indicator_increase'].sum()
  94. # print(contract)
  95. # print('long_hold_delta: ', long_hold_delta)
  96. # print('short_hold_delta: ', short_hold_delta)
  97. try:
  98. if hold_signal == 0:
  99. if long_hold_delta>0 and short_hold_delta<0:
  100. signal = 1
  101. elif long_hold_delta<0 and short_hold_delta>0:
  102. signal = -1
  103. else: signal = 0
  104. if hold_signal > 0:
  105. if long_hold_delta <= 0 or short_hold_delta >= 0:
  106. signal = 0
  107. else:
  108. signal = 1
  109. if hold_signal < 0:
  110. if long_hold_delta >= 0 or short_hold_delta <= 0:
  111. signal = 0
  112. else:
  113. signal = -1
  114. except:
  115. log.info('信号计算报错'+str(symbol_dominant))
  116. # 按照两倍杠杆计算持仓手数
  117. total_value = context.portfolio.total_value
  118. multi = g.muliti_dict[symbol]
  119. amount = int(total_value / dominant_price / multi /len(g.symbol_list) * g.times)
  120. print('total_value: ', total_value)
  121. print('dominant_price: ', dominant_price)
  122. print('multi: ', multi)
  123. print('g.symbol_list: ', len(g.symbol_list))
  124. print('amount: ', amount)
  125. # 开仓数量过滤
  126. if amount < 1:
  127. amount = 1
  128. g.signal_df = g.signal_df.append({'期货代码': symbol_dominant,
  129. '交易信号': signal,
  130. '手数': amount,
  131. },
  132. ignore_index=True)
  133. log.info('\n' + str(g.signal_df))
  134. signal_df_analysis(context)
  135. ## 夜盘交易函数
  136. def trade(context):
  137. # 平仓
  138. for future in g.close_long:
  139. order_target(future, 0, side='long')
  140. for future in g.close_short:
  141. order_target(future, 0, side='short')
  142. # 开仓
  143. for future in g.open_long:
  144. amount = g.signal_df[g.signal_df['期货代码'] == future]['手数'].values[0]
  145. order_target(future, amount, side='long')
  146. for future in g.open_short:
  147. amount = g.signal_df[g.signal_df['期货代码'] == future]['手数'].values[0]
  148. order_target(future, amount, side='short')
  149. def signal_df_analysis(context):
  150. #交易信号
  151. target_long = g.signal_df[g.signal_df['交易信号'] > 0]
  152. target_short = g.signal_df[g.signal_df['交易信号'] < 0]
  153. target_long_list = list(target_long['期货代码']) # 想持多仓的目标
  154. target_short_list = list(target_short['期货代码']) # 想持空仓的目标
  155. # 下一个交易日需要处理多类的品种
  156. g.open_long = [i for i in target_long_list if i not in g.long_holds]
  157. g.close_long = [i for i in g.long_holds if i not in target_long_list]
  158. # 下一个交易日需要处理空类的品种
  159. g.open_short = [i for i in target_short_list if i not in g.short_holds]
  160. g.close_short = [i for i in g.short_holds if i not in target_short_list]