| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- # 股指ETF期权T型报价
- # 参考资料:
- # - 原始策略来源: https://www.joinquant.com/view/community/detail/a5a968ed72f2b827c051d337b0d74d04
- # - 研究网址: https://www.joinquant.com/research?target=research&url=/user/75474983526/notebooks/Options/%E8%82%A1%E6%8C%87ETF%E6%9C%9F%E6%9D%83T%E5%9E%8B%E6%8A%A5%E4%BB%B7.ipynb
- # TODO: 添加股指ETF期权T型报价相关代码
- import pandas as pd
- import numpy as np
- import talib as tb
- from pandas.plotting import table
- from jqdata import *
- #期权合约信息
- class OptionContract:
-
- preClose: 0 #前一天的收盘价
- marginUnit: 0 #单位保证金
- prePosition: 0 #前一天收盘的持仓量
- close: 0 #现价
- volume: 0 #成交量
- position: 0 #当前持仓量
- priceChangePct: 0 #收盘价涨跌幅
- positionChange: 0 #日增仓
- positionChangePct: 0 #日增仓比例
- rewardPct: 0 #报酬率(权利金/保证金)
-
- def __init__(self, preClose, marginUnit,
- prePosition, close, volume,
- position, priceChangePct,
- positionChange,
- positionChangePct,
- rewardPct):
-
- self.preClose = preClose
- self.marginUnit = marginUnit
- self.prePosition = prePosition
- self.close = close
- self.volume = volume
- self.position = position
- self.priceChangePct = priceChangePct
- self.positionChange = positionChange
- self.positionChangePct = positionChangePct
- self.rewardPct = rewardPct
-
- # 同一行权价的一组期权
- class OptionGroup:
-
- exercisePrice: 0 ##行权价
- call: None ##认购的类型
- put: None ##认沽的类型
-
- def __init__(self, exercisePrice, call, put):
- self.exercisePrice = exercisePrice
- self.call = call
- self.put = put
-
- def __init__(self, exercisePrice):
- self.exercisePrice = exercisePrice
- #数据实体
- CONTENT = [
- 'close',
- 'volume',
- 'position',
- 'priceChangePct',
- 'positionChange',
- 'positionChangePct',
- 'preClose',
- 'marginUnit',
- 'rewardPct'
- ]
- ##目前支持的域及对应的抬头
- CONTENT_HEADER_MAP = {
-
- 'rewardPct': '报酬率', #计算方式:权利金/卖出一手所需的保证金*100
- 'marginUnit': '保证金', #开盘前一手该期权的保证金额,没有随盘中价格变化更新
- 'preClose': '昨收',
- 'prePosition': '昨日持仓',
- 'close': '现价',
- 'volume': '成交量',
- 'position': '持仓量',
- 'priceChangePct': '涨跌幅',
- 'positionChange': '日增仓',
- 'positionChangePct': '日增仓率',
-
- }
- ##期权合约,以50ETF为例
- SUBJECT_MATTER = '510050.XSHG'
- ##期权合约,以300ETF为例
- #SUBJECT_MATTER = '510300.XSHG'
- ##查询数据日期,以2024-03-22为例
- DATA_DATE = '2024-03-22'
- #合约到期日,以50ETF2403为例
- EXPIRE_MONTH = '2024-03-27'
- #查询相关的合约
- qy = query(opt.OPT_CONTRACT_INFO).filter(
- opt.OPT_CONTRACT_INFO.underlying_symbol == SUBJECT_MATTER, ##期权标的物
- opt.OPT_CONTRACT_INFO.exercise_date == EXPIRE_MONTH,##期权到期日
- ).order_by(opt.OPT_CONTRACT_INFO.exercise_price, opt.OPT_CONTRACT_INFO.contract_type)
- optList = opt.run_query(qy)
- print(optList)
- optionGroups = {}
- for index, row in optList.iterrows():
-
- code = row['code'] #key - 期权代码
-
- #查询具体合约的信息,商品需要去掉开盘前的静态信息
- optionDailyQuery = query(opt.OPT_DAILY_PREOPEN).filter(
- opt.OPT_DAILY_PREOPEN.code==code).order_by(
- opt.OPT_DAILY_PREOPEN.date.desc()).limit(1)
-
- dailyData = opt.run_query(optionDailyQuery)
- realTimeQuery = query(opt.OPT_DAILY_PRICE).filter(
- opt.OPT_DAILY_PRICE.code==code,
- opt.OPT_DAILY_PRICE.date==DATA_DATE).order_by(
- opt.OPT_DAILY_PRICE.date.desc()).limit(1)
-
- realTimeData = opt.run_query(realTimeQuery)
-
- #期权基本信息
- exercisePrice = row['exercise_price'] #行权价
- contractType = row['contract_type'] #合约类型。CO-认购期权,PO-认沽期权
-
- #盘前静态表查询
- preClose = dailyData.loc[0].at['pre_close'] #前一天的收盘价
- marginUnit = int(dailyData.loc[0].at['margin_unit']) #单位保证金
- prePosition = dailyData.loc[0].at['position'] #前一天收盘的持仓量
-
- #实时表查询
- close = realTimeData.loc[0].at['close'] #现价
- volume = int(realTimeData.loc[0].at['volume']) #成交量
- position = realTimeData.loc[0].at['position'] #当前持仓量
- priceChangePct = str(round(realTimeData.loc[0].at['change_pct_close'], 2)) + '%' #收盘价涨跌幅
-
- #计算
- positionChange = position - prePosition #日增仓
- positionChangePct = str(round(abs(positionChange / prePosition * 100), 2)) + '%' #日增仓比例
- rewardPct = round(close * 10000 / marginUnit * 100, 2) #报酬率(权利金/保证金)
-
- #去除非标准的带A合约
- if(exercisePrice * 10000 % 500 != 0):
- continue
- optionContract = OptionContract(preClose, marginUnit,
- prePosition, close,
- volume, position,
- priceChangePct, positionChange,
- positionChangePct, rewardPct)
-
- if(exercisePrice in optionGroups):
-
- if(contractType == 'CO'):
- optionGroups[exercisePrice].call = optionContract
- else:
- optionGroups[exercisePrice].put = optionContract
-
- else:
-
- optionGroup = OptionGroup(exercisePrice)
-
- if(contractType == 'CO'):
- optionGroup.call = optionContract
- else:
- optionGroup.put = optionContract
-
- optionGroups[exercisePrice] = optionGroup
- list = optionGroups.values()
- rtitle = CONTENT.copy()
- rtitle.reverse()
- data = {}
- for key in rtitle:
- data['C-'+CONTENT_HEADER_MAP[key]] = []
- data['行权价'] = []
- for key in CONTENT:
- data['P-'+CONTENT_HEADER_MAP[key]] = []
-
- for option in list:
-
- for key in CONTENT:
- data['C-'+CONTENT_HEADER_MAP[key]].append(getattr(option.call, key))
- data['行权价'].append(option.exercisePrice)
-
- for key in rtitle:
- data['P-'+CONTENT_HEADER_MAP[key]].append(getattr(option.put, key))
- df = pd.DataFrame(data)
- df
|