增加交易策略、交易指标、量化库代码等文件夹

This commit is contained in:
Win_home
2025-04-27 15:54:09 +08:00
parent ca3b209096
commit f57150dae8
589 changed files with 854346 additions and 1757 deletions

View File

@@ -0,0 +1,86 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from update_etf_data import *"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"合约信息更新成功 642\n"
]
}
],
"source": [
"contracts = update_contract_data(\"上证期权\")"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ContractData(gateway_name='XT', extra=None, symbol='10005765', exchange=<Exchange.SSE: 'SSE'>, name='50ETF购3月2411A', product=<Product.OPTION: '期权'>, size=10161, pricetick=0.0001, min_volume=1, stop_supported=False, net_position=False, history_data=False, option_strike=2.411, option_underlying='510050-2403', option_type=<OptionType.CALL: '看涨期权'>, option_listed=datetime.datetime(2023, 7, 27, 0, 0), option_expiry=datetime.datetime(2024, 3, 27, 0, 0), option_portfolio='510050', option_index='2.411')\n",
"ContractData(gateway_name='XT', extra=None, symbol='10006712', exchange=<Exchange.SSE: 'SSE'>, name='300ETF沽6月3700', product=<Product.OPTION: '期权'>, size=10000, pricetick=0.0001, min_volume=1, stop_supported=False, net_position=False, history_data=False, option_strike=3.7, option_underlying='510300-2406', option_type=<OptionType.PUT: '看跌期权'>, option_listed=datetime.datetime(2024, 1, 19, 0, 0), option_expiry=datetime.datetime(2024, 6, 26, 0, 0), option_portfolio='510300', option_index='3.7')\n"
]
}
],
"source": [
"print(contracts[0])\n",
"print(contracts[-1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"update_bar_data()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.9"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -0,0 +1,86 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from update_rqdata_data import *"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"合约信息更新成功 4808\n"
]
}
],
"source": [
"contracts = update_contract_data(Exchange.CFFEX)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ContractData(gateway_name='RQ', extra=None, symbol='HO2301-C-2325', exchange=<Exchange.CFFEX: 'CFFEX'>, name='HO2301-C-2325', product=<Product.OPTION: '期权'>, size=100.0, pricetick=0.2, min_volume=1.0, stop_supported=False, net_position=False, history_data=False, option_strike=2325.0, option_underlying='HO2301', option_type=<OptionType.CALL: '看涨期权'>, option_listed=datetime.datetime(2022, 12, 21, 0, 0), option_expiry=datetime.datetime(2023, 1, 20, 0, 0), option_portfolio='HO', option_index='2325.0')\n",
"ContractData(gateway_name='RQ', extra=None, symbol='MO2412-P-6600', exchange=<Exchange.CFFEX: 'CFFEX'>, name='MO2412-P-6600', product=<Product.OPTION: '期权'>, size=100.0, pricetick=0.2, min_volume=1.0, stop_supported=False, net_position=False, history_data=False, option_strike=6600.0, option_underlying='MO2412', option_type=<OptionType.PUT: '看跌期权'>, option_listed=datetime.datetime(2023, 12, 18, 0, 0), option_expiry=datetime.datetime(2024, 12, 20, 0, 0), option_portfolio='MO', option_index='6600.0')\n"
]
}
],
"source": [
"print(contracts[0])\n",
"print(contracts[-1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"update_bar_data()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.9"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -0,0 +1,198 @@
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"] = ""
# 交易所映射关系
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:
# 拆分XT代码
symbol, xt_exchange = xt_symbol.split(".")
# 筛选期权合约合约ETF期权代码为8位
if len(symbol) == 8:
data: dict = get_instrument_detail(xt_symbol, True)
#print(data)
#raise Exception("fuck")
name: str = data["InstrumentName"]
if "" in name:
option_type = OptionType.CALL
elif "" in name:
option_type = OptionType.PUT
else:
continue
# 获取期权组合
option_portfolio = data["ExtendInfo"]["OptUndlCode"]
# 获取期权链(标的)
option_expiry = datetime.strptime(data["ExpireDate"], "%Y%m%d")
option_underlying = option_portfolio + "-" + option_expiry.strftime("%y%m")
# 生成合约对象
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=option_portfolio,
option_underlying=option_underlying,
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(2018, 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_contract_data("深证期权")
update_contract_data("过期深证期权")
# 更新历史数据
update_bar_data()

View File

@@ -0,0 +1,163 @@
from datetime import datetime
import rqdatac
import pandas as pd
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 elite_database import EliteDatabase
# 初始化数据服务
datafeed = get_datafeed()
datafeed.init()
# 交易所映射关系
EXCHANGE_RQ2VT = {
"XSHG": Exchange.SSE,
"XSHE": Exchange.SZSE,
"SHFE": Exchange.SHFE,
"CFFEX": Exchange.CFFEX,
"INE": Exchange.INE,
"DCE": Exchange.DCE,
"CZCE": Exchange.CZCE,
"GFEX": Exchange.GFEX
}
def update_contract_data(exchange: Exchange) -> None:
"""更新合约数据"""
# 查询期权信息
df: pd.DataFrame = rqdatac.all_instruments(type="Option")
# 转换合约对象
contracts: list[ContractData] = []
for tp in df.itertuples():
# 交易所过滤
if exchange != EXCHANGE_RQ2VT[tp.exchange]:
continue
# 确认期权类型
if tp.option_type == "C":
option_type = OptionType.CALL
else:
option_type = OptionType.PUT
# 获取最小价格变动
pricetick: float = rqdatac.instruments(tp.order_book_id).tick_size()
# 获取期权链(标的)
if "-" in tp.trading_code:
option_underlying = tp.trading_code.split("-")[0]
else:
suffix = tp.trading_code.replace(tp.underlying_symbol, "")
ix = suffix.index(tp.option_type)
time_str = suffix[:ix]
option_underlying = tp.underlying_symbol + time_str
# 创建期权对象
contract = ContractData(
symbol=tp.trading_code,
exchange=exchange,
name=tp.trading_code,
product=Product.OPTION,
size=tp.contract_multiplier,
pricetick=pricetick,
min_volume=tp.round_lot,
option_strike=tp.strike_price,
option_listed=datetime.strptime(tp.listed_date, "%Y-%m-%d"),
option_expiry=datetime.strptime(tp.maturity_date, "%Y-%m-%d"),
option_portfolio=tp.underlying_symbol,
option_index=str(tp.strike_price),
option_underlying=option_underlying,
option_type=option_type,
gateway_name="RQ"
)
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(2018, 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__":
# 更新合约信息
update_contract_data(Exchange.CFFEX)
# 更新历史数据
update_bar_data()