增加交易策略、交易指标、量化库代码等文件夹
This commit is contained in:
BIN
5.课程代码/2.Option_spread_strategy/使用文档/26/2024031574052027.dmp
Normal file
BIN
5.课程代码/2.Option_spread_strategy/使用文档/26/2024031574052027.dmp
Normal file
Binary file not shown.
102
5.课程代码/2.Option_spread_strategy/使用文档/26/get_history_sector.py
Normal file
102
5.课程代码/2.Option_spread_strategy/使用文档/26/get_history_sector.py
Normal file
@@ -0,0 +1,102 @@
|
||||
#encoding:gbk
|
||||
|
||||
import re
|
||||
|
||||
def init(C):
|
||||
|
||||
option_code_list1 = get_option_code(C,"IF",data_type = 0) # 获取中金所当前可交易期权合约
|
||||
|
||||
option_code_list2 = get_option_code(C,"SHO",data_type = 1) # 获取上交所已退市可交易期权合约
|
||||
option_code_list3 = get_option_code(C,"IF",data_type = 2) # 获取 中金所 所有期权(包含历史)合约
|
||||
|
||||
print(option_code_list1[:5])
|
||||
print("="*20)
|
||||
print(option_code_list2[:5])
|
||||
print("="*20)
|
||||
print(option_code_list3[:5])
|
||||
|
||||
# 可通过C.get_option_detail_data()查看合约具体信息
|
||||
|
||||
def hanldbar(C):
|
||||
return
|
||||
|
||||
def get_option_code(C,market,data_type = 0):
|
||||
|
||||
'''
|
||||
|
||||
ToDo:取出指定market的期权合约
|
||||
|
||||
Args:
|
||||
market: 目标市场,比如中金所填 IF
|
||||
|
||||
data_type: 返回数据范围,可返回已退市合约,默认仅返回当前
|
||||
|
||||
0: 仅当前
|
||||
1: 仅历史
|
||||
2: 历史 + 当前
|
||||
|
||||
'''
|
||||
_history_sector_dict = {
|
||||
"IF":"过期中金所",
|
||||
"SF":"过期上期所",
|
||||
"DF":"过期大商所",
|
||||
"ZF":"过期郑商所",
|
||||
"INE":"过期能源中心",
|
||||
"SHO":"过期上证期权",
|
||||
"SZO":"过期深证期权",
|
||||
}
|
||||
|
||||
# _now_secotr_dict = {
|
||||
# "IF":"中金所",
|
||||
# "SF":"上期所",
|
||||
# "DF":"大商所",
|
||||
# "ZF":"郑商所",
|
||||
# "INE":"能源中心",
|
||||
# "SHO":"上证期权",
|
||||
# "SZO":"深证期权",
|
||||
# }
|
||||
|
||||
_sector = _history_sector_dict.get(market)
|
||||
# _now_sector = _now_secotr_dict.get(market)
|
||||
if _sector == None:
|
||||
raise KeyError(f"不存在该市场:{market}")
|
||||
_now_sector = _sector[2:]
|
||||
|
||||
|
||||
# 过期上证和过期深证有专门的板块,不需要处理
|
||||
if market == "SHO" or market == "SZO":
|
||||
if data_type == 0:
|
||||
_list = C.get_stock_list_in_sector(_now_sector)
|
||||
elif data_type == 1:
|
||||
_list = C.get_stock_list_in_sector(_sector)
|
||||
elif data_type == 2:
|
||||
_list = C.get_stock_list_in_sector(_sector) + C.get_stock_list_in_sector(_now_sector)
|
||||
else:
|
||||
raise KeyError(f"data_type参数错误:{data_type}")
|
||||
return _list
|
||||
|
||||
# 期货期权需要额外处理
|
||||
if data_type == 0:
|
||||
all_list = C.get_stock_list_in_sector(_now_sector)
|
||||
elif data_type == 1:
|
||||
all_list = C.get_stock_list_in_sector(_sector)
|
||||
elif data_type == 2:
|
||||
all_list = C.get_stock_list_in_sector(_sector) + C.get_stock_list_in_sector(_now_sector)
|
||||
else:
|
||||
raise KeyError(f"data_type参数错误:{data_type}")
|
||||
|
||||
_list = []
|
||||
pattern1 = r'^[A-Z]{2}\d{4}-[A-Z]-\d{4}\.[A-Z]+$'
|
||||
pattern2 = r'^[a-zA-Z]+\d+[a-zA-Z]\d+\.[A-Z]+$'
|
||||
pattern3 = r'^[a-zA-Z]+\d+-[a-zA-Z]-\d+\.[A-Z]+$'
|
||||
for i in all_list:
|
||||
if re.match(pattern1,i):
|
||||
_list.append(i)
|
||||
elif re.match(pattern2,i):
|
||||
_list.append(i)
|
||||
elif re.match(pattern3,i):
|
||||
_list.append(i)
|
||||
# _list =[i for i in all_list if re.match(pattern, i)]
|
||||
return _list
|
||||
|
||||
|
||||
1159
5.课程代码/2.Option_spread_strategy/使用文档/26/test.ipynb
Normal file
1159
5.课程代码/2.Option_spread_strategy/使用文档/26/test.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
194
5.课程代码/2.Option_spread_strategy/使用文档/26/update_commodity_data.py
Normal file
194
5.课程代码/2.Option_spread_strategy/使用文档/26/update_commodity_data.py
Normal file
@@ -0,0 +1,194 @@
|
||||
from multiprocessing import Process
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.trader.database import BarOverview
|
||||
from vnpy.trader.datafeed import get_datafeed
|
||||
from vnpy.trader.object import ContractData, BarData, HistoryRequest
|
||||
from vnpy.trader.constant import Exchange, Product, OptionType, Interval
|
||||
from vnpy.trader.setting import SETTINGS
|
||||
|
||||
from elite_database import EliteDatabase
|
||||
|
||||
|
||||
# 配置迅投研数据服务
|
||||
SETTINGS["datafeed.name"] = "xt"
|
||||
SETTINGS["datafeed.username"] = "token"
|
||||
SETTINGS["datafeed.password"] = "4aff6f3b0dcfc990ec9476213ba784e17c34e757"
|
||||
|
||||
|
||||
# 交易所映射关系
|
||||
EXCHANGE_XT2VT = {
|
||||
"SH": Exchange.SSE,
|
||||
"SZ": Exchange.SZSE,
|
||||
"BJ": Exchange.BSE,
|
||||
"SF": Exchange.SHFE,
|
||||
"IF": Exchange.CFFEX,
|
||||
"INE": Exchange.INE,
|
||||
"DF": Exchange.DCE,
|
||||
"ZF": Exchange.CZCE,
|
||||
"GF": Exchange.GFEX
|
||||
}
|
||||
|
||||
|
||||
def update_history_data() -> None:
|
||||
"""更新历史合约信息"""
|
||||
# 在子进程中加载xtquant
|
||||
from xtquant.xtdata import download_history_data
|
||||
|
||||
# 初始化数据服务
|
||||
datafeed = get_datafeed()
|
||||
datafeed.init()
|
||||
|
||||
# 下载历史合约信息
|
||||
download_history_data("", "historycontract")
|
||||
|
||||
print("xtquant历史合约信息下载完成")
|
||||
|
||||
|
||||
def update_contract_data(sector_name: str) -> None:
|
||||
"""更新合约数据"""
|
||||
# 在子进程中加载xtquant
|
||||
from xtquant.xtdata import (
|
||||
get_stock_list_in_sector,
|
||||
get_instrument_detail
|
||||
)
|
||||
|
||||
# 初始化数据服务
|
||||
datafeed = get_datafeed()
|
||||
datafeed.init()
|
||||
|
||||
# 查询交易所历史合约代码
|
||||
vt_symbols: list[str] = get_stock_list_in_sector(sector_name)
|
||||
|
||||
# 遍历列表查询合约信息
|
||||
contracts: list[ContractData] = []
|
||||
|
||||
for xt_symbol in vt_symbols:
|
||||
# 筛选期权合约合约
|
||||
data: dict = get_instrument_detail(xt_symbol, True)
|
||||
option_strike: float = data["ExtendInfo"]["OptExercisePrice"]
|
||||
if not option_strike:
|
||||
continue
|
||||
|
||||
# 拆分XT代码
|
||||
symbol, xt_exchange = xt_symbol.split(".")
|
||||
|
||||
# 移除产品前缀
|
||||
for ix, w in enumerate(symbol):
|
||||
if w.isdigit():
|
||||
break
|
||||
|
||||
suffix: str = symbol[ix:]
|
||||
|
||||
# 判断期权类型
|
||||
if "C" in suffix:
|
||||
option_type = OptionType.CALL
|
||||
elif "P" in suffix:
|
||||
option_type = OptionType.PUT
|
||||
else:
|
||||
continue
|
||||
|
||||
contract: ContractData = ContractData(
|
||||
symbol=data["InstrumentID"],
|
||||
exchange=EXCHANGE_XT2VT[xt_exchange.replace("O", "")],
|
||||
name=data["InstrumentName"],
|
||||
product=Product.OPTION,
|
||||
size=data["VolumeMultiple"],
|
||||
pricetick=data["PriceTick"],
|
||||
min_volume=data["MinLimitOrderVolume"],
|
||||
option_strike=data["ExtendInfo"]["OptExercisePrice"],
|
||||
option_listed=datetime.strptime(data["OpenDate"], "%Y%m%d"),
|
||||
option_expiry=datetime.strptime(data["ExpireDate"], "%Y%m%d"),
|
||||
option_portfolio=data["ProductID"],
|
||||
option_index=str(data["ExtendInfo"]["OptExercisePrice"]),
|
||||
option_type=option_type,
|
||||
gateway_name="XT"
|
||||
)
|
||||
contracts.append(contract)
|
||||
|
||||
# 保存合约信息到数据库
|
||||
database: EliteDatabase = EliteDatabase()
|
||||
database.save_contract_data(contracts)
|
||||
|
||||
print("合约信息更新成功", len(contracts))
|
||||
|
||||
return contracts
|
||||
|
||||
|
||||
def update_bar_data() -> None:
|
||||
"""更新K线数据"""
|
||||
# 初始化数据服务
|
||||
datafeed = get_datafeed()
|
||||
datafeed.init()
|
||||
|
||||
# 获取当前时间戳
|
||||
now: datetime = datetime.now()
|
||||
|
||||
# 获取合约信息
|
||||
database: EliteDatabase = EliteDatabase()
|
||||
contracts: list[ContractData] = database.load_contract_data()
|
||||
|
||||
# 获取数据汇总
|
||||
data: list[BarOverview] = database.get_bar_overview()
|
||||
|
||||
overviews: dict[str, BarOverview] = {}
|
||||
for o in data:
|
||||
# 只保留分钟线数据
|
||||
if o.interval != Interval.MINUTE:
|
||||
continue
|
||||
|
||||
vt_symbol: str = f"{o.symbol}.{o.exchange.value}"
|
||||
overviews[vt_symbol] = o
|
||||
|
||||
# 遍历所有合约信息
|
||||
for contract in contracts:
|
||||
# 如果没有到期时间,则跳过
|
||||
if not contract.option_expiry:
|
||||
continue
|
||||
|
||||
# 查询数据汇总
|
||||
overview: BarOverview = overviews.get(contract.vt_symbol, None)
|
||||
|
||||
# 如果已经到期,则跳过
|
||||
if overview and contract.option_expiry < now:
|
||||
continue
|
||||
|
||||
# 初始化查询开始的时间
|
||||
start: datetime = datetime(2017, 1, 1)
|
||||
|
||||
# 实现增量查询
|
||||
if overview:
|
||||
start = overview.end
|
||||
|
||||
# 执行数据查询和更新入库
|
||||
req: HistoryRequest = HistoryRequest(
|
||||
symbol=contract.symbol,
|
||||
exchange=contract.exchange,
|
||||
start=start,
|
||||
end=datetime.now(),
|
||||
interval=Interval.MINUTE
|
||||
)
|
||||
|
||||
bars: list[BarData] = datafeed.query_bar_history(req)
|
||||
|
||||
if bars:
|
||||
database.save_bar_data(bars)
|
||||
|
||||
start_dt: datetime = bars[0].datetime
|
||||
end_dt: datetime = bars[-1].datetime
|
||||
msg: str = f"{contract.vt_symbol}数据更新成功,{start_dt} - {end_dt}"
|
||||
print(msg)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 使用子进程更新历史合约信息
|
||||
process: Process = Process(target=update_history_data)
|
||||
process.start()
|
||||
process.join() # 等待子进程执行完成
|
||||
|
||||
# 更新合约信息
|
||||
update_contract_data("郑商所")
|
||||
update_contract_data("过期郑商所")
|
||||
|
||||
# 更新历史数据
|
||||
update_bar_data()
|
||||
Reference in New Issue
Block a user