73 浏览
0

请问一下有没有大佬遇到过这样的问题,一直重连断开,网络检查了没有任何问题

chaos 已回答的问题 2天 前
0

看起来还是网络问题,天勤这边一直尝试重连,还有其他信息吗或者可以给一个最小复现代码我看看

chaos 发表新评论 2天 前

提前谢谢您的耐心解答,上面就是单纯的筛选出来想要交易的合约代码,不知道是不是因为合约比较多的原因,所以把代码也贴上了,往下面翻下面是错误复现:

from datetime import datetime, time
from tqsdk import TqApi, TqAuth, TqSim, TqBacktest
from tqsdk.tafunc import time_to_datetime
import time as sys_time
from datetime import date
import pandas as pd
# 初始化API和账户
# api = TqApi(backtest=TqBacktest(start_dt=date(2025, 5, 1), end_dt=date(2025, 5, 10)),web_gui=True, auth=TqAuth(“18560100409”, “hyjn88”))
api = TqApi(TqSim(init_balance=10000000), web_gui=True, auth=TqAuth(“18560100409”, “hyjn8888″))

# 列出你关注的交易所代码
exchanges = [‘DCE’, ‘CZCE’, ‘SHFE’] # 可以根据需要增删, ‘SHFE’, ‘DCE’, ‘CZCE’, ‘SSE’, ‘SZSE’

all_options = [] # 用于存储所有期权合约的列表

for exchange in exchanges:
try:
# 查询该交易所下所有未过期的期权合约
options_list = api.query_quotes(ins_class=’OPTION’, exchange_id=exchange, expired=False)
all_options.extend(options_list)
print(f”交易所 {exchange} 有 {len(options_list)} 个未到期期权合约”)
except Exception as e:
print(f”获取交易所 {exchange} 的期权列表时出错: {e}”)

print(f”n总共获取到 {len(all_options)} 个未到期期权合约”)

from datetime import datetime
from collections import defaultdict

# 定义一个函数来提取合约的到期月份
def get_expiry_month(symbol):
# 假设合约代码格式为 ‘交易所代码.品种代码到期月份-C/P-行权价’
# 例如 ‘DCE.m2505-C-1000’
parts = symbol.split(‘.’)
if len(parts) = 2:
expiry = sorted_expiries[0]
next_expiry = sorted_expiries[1] # 次主力
next_next_expiry = sorted_expiries[2] if len(sorted_expiries) >= 3 else None # 次次主力
next_next_next_expiry = sorted_expiries[3] if len(sorted_expiries) >= 3 else None
else:
expiry = None
next_expiry = None
next_next_expiry = None
next_next_next_expiry = None

# 构建目标合约列表
target_symbols = []
if expiry:
target_symbols.extend(expiry_groups[expiry])
if next_expiry:
target_symbols.extend(expiry_groups[next_expiry])
if next_next_expiry:
target_symbols.extend(expiry_groups[next_next_expiry])
if next_next_next_expiry:
target_symbols.extend(expiry_groups[next_next_next_expiry])
print(f”主力合约月份: {expiry}, 合约数量: {len(expiry_groups.get(expiry, []))}”)
print(f”次主力合约月份: {next_expiry}, 合约数量: {len(expiry_groups.get(next_expiry, []))}”)
print(f”次次主力合约月份: {next_next_expiry}, 合约数量: {len(expiry_groups.get(next_next_expiry, []))}”)
print(f”次次主力合约月份: {next_next_next_expiry}, 合约数量: {len(expiry_groups.get(next_next_next_expiry, []))}”)
print(f”目标交易池总合约数: {len(target_symbols)}”)

# 获取行情列表
quote_list = api.get_quote_list(target_symbols)

# 新增代码:筛选虚值4档和实值3档合约
from collections import defaultdict
import numpy as np

# 首先,将 target_symbols 按标的物和到期月份分组
grouped_options = defaultdict(list)
for option_symbol in target_symbols:
quote = api.get_quote(option_symbol)
underlying_sym = quote.underlying_symbol
expiry = get_expiry_month(option_symbol)
if underlying_sym and expiry:
group_key = (underlying_sym, expiry)
grouped_options[group_key].append(option_symbol)

# 用于存储最终筛选出的合约
target_symbols_xu4shi3 = []

# 遍历每一个分组
for group_key, option_list in grouped_options.items():
underlying_sym, expiry_month = group_key
print(f”处理标的物: {underlying_sym}, 到期月: {expiry_month}”)

# 获取该标的物的当前价格
underlying_quote = api.get_quote(underlying_sym)
underlying_price = underlying_quote.last_price
if underlying_price <= 0:
print(f" 警告: 无法获取 {underlying_sym} 的有效价格,跳过该组。")
continue

# 提取并排序行权价
strike_prices = []
for sym in option_list:
quote = api.get_quote(sym)
strike_prices.append(quote.strike_price)

# 去重并排序
unique_strikes = sorted(set(strike_prices))
if len(unique_strikes) < 2:
print(f" 警告: 分组 {group_key} 中行权价数量不足,无法计算间距。")
continue

# 计算行权价间距 (取相邻行权差价的最小众数)
differences = [round(unique_strikes[i] – unique_strikes[i-1], 6) for i in range(1, len(unique_strikes))]
from collections import Counter
if differences:
strike_step = Counter(differences).most_common(1)[0][0]
print(f" 计算出的行权价间距为: {strike_step}")
else:
print(f" 警告: 无法计算分组 {group_key} 的行权价间距。")
continue

# 确定平值行权价 (最接近标的物价格的那个)
atm_strike = min(unique_strikes, key=lambda x: abs(x – underlying_price))
print(f" 标的物价格: {underlying_price}, 平值行权价: {atm_strike}")

# 计算每个合约的档位并筛选
for option_symbol in option_list:
quote = api.get_quote(option_symbol)
strike = quote.strike_price
# 计算档位: (当前行权价 – 平值行权价) / 行权价间距
tier = round((strike – atm_strike) / strike_step)

# 根据期权类型调整档位的正负号意义以确保统一:
if quote.option_class == 'PUT':
# 对于认沽期权,行权价越高越实值,计算出的tier正负号与实值方向相同,无需调整。
pass
else: # 'CALL'
# 对于认购期权,行权价越低越实值,计算出的tier需要取反,才能使正数代表实值。
tier = -tier

# 筛选:保留虚值4档(tier=-4)和实值3档(tier=3)
if -4<= tier <=3:
target_symbols_xu4shi3.append(option_symbol)
print(f" 保留合约: {option_symbol}, 行权价: {strike}, 计算档位: {tier}")

print(f"n筛选出的虚值4档和实值3档合约数: {len(target_symbols_xu4shi3)}")
print("筛选出的合约列表:", target_symbols_xu4shi3)

# 预先获取所有合约的最小变动单位 (price_tick)
contract_ticks = {}
for symbol in target_symbols_xu4shi3:
try:
contract_info = api.query_symbol_info(symbol)
price_tick = contract_info["price_tick"].iloc[0]
contract_ticks[symbol] = price_tick
print(f"合约 {symbol} 的最小变动单位: {price_tick}")
except Exception as e:
print(f"获取合约 {symbol} 的price_tick时出错: {e}")
contract_ticks[symbol] = 0.5 # 默认值

api.close()

上面就是单纯的筛选出来想要交易的合约代码,不知道是不是因为合约比较多的原因,所以把代码也贴上了,下面是错误复现:

api = TqApi(TqSim(init_balance=10000000), web_gui=True, auth=TqAuth("18560100409", "hyjn88"))
quote_list = api.get_quote_list(target_symbols_xu4shi3)
orders_dict = {} # 用于存储所有订单

while True:

api.wait_update()
# 获取当前账户信息
account = api.get_account()
# 打印当前账户资金情况
print(f"当前账户权益: {account.static_balance}, 可用资金: {account.available}, 持仓盈亏: {account.float_profit}")
current_dt = datetime.now().time()
print("current_dt: ",current_dt)

for i, quote in enumerate(quote_list):
symbol = quote.instrument_id

# 跳过无效报价
if quote.ask_price1 <= 0 or quote.bid_price1 5 and symbol not in orders_dict:
buy_price = round(quote.bid_price1 + price_tick, 6)
expected_sell_price = round(quote.ask_price1 – price_tick, 6)
buy_order = api.insert_order(
symbol=symbol,
direction=”BUY”,
offset=”OPEN”,
volume=1,
limit_price=buy_price,
)
orders_dict[symbol] = {
‘buy_order’: buy_order,
‘sell_order’: None,
‘buy_price’: buy_price,
‘expected_sell_price’:expected_sell_price,
‘price_tick’: price_tick
}
print(f”为合约 {symbol} 挂买单,价格: {buy_price}”)

sys_time.sleep(60)

然后运行一会就报错了,不知道什么原因,网络是没问题的,也不会自动重连,就算现实自动重连之后也只会运行到print(“current_dt: “,current_dt)这一行,谢谢您耐心解答

有可能是因为订阅合约数量过多导致的,你先减小一下订阅数量再运行看看
然后代码中不要使用time.sleep这种方法
代码给一个最小复现的就行,可以运行的,不用贴全部的代码

您正在查看1个答案中的1个,单击此处查看所有答案。