早上执行好好的,下午执行就出现废单了,想知道原因,谢谢,执行结果贴在后面
#coding:gbk
import time
from datetime import datetime
from datetime import timedelta
# 单独维护交易日期
trade_date = "2024-12-30"
# 固定的交易时间
sell_time = "14:26:01"
buy_time = "14:26:05"
print_time = "14:26:22"
# 预先配置的股票名称和股票代码的对应关系
stock_code_dict = {
'30年国债': '511090.sh',
'十年国债': '511260.sh',
'国债': '511010.sh',
'国开债': '159649.sz',
'国开': '159650.sz',
'国开债券': '159651.sz',
'中证红利': '515080.sh',
'红利低波': '512890.sh',
'天弘添利': '164206.sz',
'纳斯达克100': '161130.sz',
'标普科技': '161128.sz',
'标普医疗': '161126.sz',
'美国消费': '162415.sz',
'美国精选': '160140.sz',
'全球芯片': '501225.sh',
'人工智能': '161631.sz',
'黄金': '160719.sz',
'原油': '160723.sz',
'银华日利': '511880.sh',
'日鑫利': 'RXL001.sz'
}
# 创建一个反向字典用于股票代码查找名称
code_to_name_dict = {v.split('.')[0]: k for k, v in stock_code_dict.items()}
# 交易状态字典
trade_status = {
'sell': False,
'buy': False
}
# 假设这些是您要卖出和买入的股票名称和手数/金额
sell_stocks_info = [
#{'name': '美国精选', 'lots': '100'}
# {'name': '十年国债', 'lots': 1000},
{'name': '天弘添利', 'lots': 100}
]
buy_stocks_info = [
#{'name': '标普科技', 'amount': 550},
]
# 中文星期映射
weekdays_cn = {
0: '星期一',
1: '星期二',
2: '星期三',
3: '星期四',
4: '星期五',
5: '星期六',
6: '星期日'
}
def get_weekday(date_str):
date_obj = datetime.strptime(date_str, "%Y-%m-%d")
return weekdays_cn.get(date_obj.weekday(), '未知')
def print_trade_plan(trade_date, sell_time, buy_time, sell_stocks_info, buy_stocks_info, stock_code_dict):
print("交易计划:")
date_obj = datetime.strptime(trade_date, "%Y-%m-%d")
print(f"交易日期:{trade_date} {get_weekday(trade_date)}")
print(f"卖出时间:{sell_time}, 买入时间:{buy_time}")
print("卖出计划:")
for stock in sell_stocks_info:
stock_code = stock_code_dict.get(stock['name'])
if stock_code:
print(f" - 股票名称:{stock['name']}, 股票代码:{stock_code}, 数量:{stock['lots']}手")
else:
print(f" - 股票名称:{stock['name']} 的代码未找到")
print("买入计划:")
for stock in buy_stocks_info:
stock_code = stock_code_dict.get(stock['name'])
if stock_code:
print(f" - 股票名称:{stock['name']}, 股票代码:{stock_code}, 金额:{stock['amount']}元")
else:
print(f" - 股票名称:{stock['name']} 的代码未找到")
print("-" * 50) # 添加分割线
def print_positions(accountID, accountType):
position_info = get_trade_detail_data(accountID, accountType, 'position')
if not position_info:
print("没有持仓数据返回")
else:
print("当前持仓情况:")
print(f"{'股票名称':<12}{'股票代码':<10}{'持仓量':<8}{'最新价':<8}{'持仓金额':<10}")
print("-" * 50)
stock_code_order = {v.split('.')[0]: idx for idx, v in enumerate(stock_code_dict.values())}
sorted_positions = sorted(
position_info,
key=lambda x: stock_code_order.get(x.m_strInstrumentID, float('inf')) # 未匹配到的代码排在末尾
)
total_market_value = 0 # 计算总市值
for i in sorted_positions:
stock_name = code_to_name_dict.get(i.m_strInstrumentID, '未知股票')
stock_code = i.m_strInstrumentID
volume = i.m_nVolume
last_price = i.m_dLastPrice
market_value = volume * last_price # 持仓金额
total_market_value += market_value
print(f"{stock_name:<12}{stock_code:<10}{volume:<8}{last_price:<8.2f}{market_value:<10.2f}")
print("-" * 50) # 添加分割线
# 打印账户总资产
account_info_list = get_trade_detail_data(accountID, accountType, 'account')
if account_info_list: # 确保列表不为空
account_info = account_info_list[0] # 取列表中的第一个Account对象
total_assets = account_info.m_dBalance
print(f"账户总资产:{total_assets:.2f}元")
else:
print("账户信息获取失败")
print("-" * 50) # 添加分割线
def print_orders(accountID, accountType):
order_info = get_trade_detail_data(accountID, accountType, 'order')
if not order_info:
print("没有委托数据返回")
else:
print("当前委托情况:")
print(f"{'股票名称':<12}{'方向':<8}{'委托量':<8}{'价格':<8}{'委托状态':<10}{'废单原因':<20}")
for obj in order_info:
stock_code = obj.m_strInstrumentID
stock_name = code_to_name_dict.get(stock_code.split('.')[0], '未知股票') # 通过代码查找名称
# 确定买卖方向
if obj.m_nOffsetFlag == 48: # 买入,开仓
direction = "买入"
elif obj.m_nOffsetFlag == 49: # 卖出,平仓
direction = "卖出"
else:
direction = "其他" # 其他情况,如强平、平今、平昨等
# 确定委托状态并打印废单原因
if obj.m_nOrderStatus == 49: # 待报
status = "待报"
reason = "无"
elif obj.m_nOrderStatus == 50: # 已报
status = "已报"
reason = "无"
elif obj.m_nOrderStatus == 51: # 已报待撤
status = "已报待撤"
reason = "无"
elif obj.m_nOrderStatus == 52: # 部成待撤
status = "部成待撤"
reason = "无"
elif obj.m_nOrderStatus == 53: # 部撤
status = "部撤"
reason = "无"
elif obj.m_nOrderStatus == 54: # 已撤
status = "已撤"
reason = "无"
elif obj.m_nOrderStatus == 55: # 部成
status = "部成"
reason = "无"
elif obj.m_nOrderStatus == 56: # 已成
status = "已成"
reason = "无"
elif obj.m_nOrderStatus == 57: # 废单
status = "废单"
# 假设有一个字段 m_strOrderStatusMsg 记录废单原因(需要根据实际情况调整)
reason = obj.m_strOrderStatusMsg if hasattr(obj, 'm_strOrderStatusMsg') else "未知原因"
else:
status = "未知状态"
reason = "无"
# 委托对象没有m_nVolume属性,我们使用委托数量属性m_nVolumeTotalOriginal
print(f"{stock_name:<12}{direction:<8}{obj.m_nVolumeTotalOriginal:<8}{obj.m_dLimitPrice:<8.2f}{status:<10}{reason:<20}")
def print_trades(accountID, accountType):
trade_info = get_trade_detail_data(accountID, accountType, 'trade')
if not trade_info:
print("没有成交数据返回")
else:
print("当前成交情况:")
print(f"{'股票代码':<12}{'方向':<8}{'成交量':<8}{'价格':<8}")
for obj in trade_info:
direction = "买入" if obj.m_nDirection == 1 else "卖出"
# 成交对象使用成交量属性m_nVolume
print(f"{obj.m_strInstrumentID:<12}{direction:<8}{obj.m_nVolume:<8}{obj.m_dPrice:<8.2f}")
def init(ContextInfo):
print("程序开始运行...")
print("-" * 50) # 添加分割线
print_positions('8886006288', 'stock') # 打印当前持仓情况
print_trade_plan(trade_date, sell_time, buy_time, sell_stocks_info, buy_stocks_info, stock_code_dict)
ContextInfo.run_time("sell_stocks", "1nSecond", trade_date + " " + sell_time)
ContextInfo.run_time("buy_stocks", "1nSecond", trade_date + " " + buy_time)
ContextInfo.run_time("print_trade_status", "1nSecond", trade_date + " " + print_time)
def get_position_info(accountID, stock_code, ContextInfo):
try:
position_info = get_trade_detail_data(accountID, 'stock', 'position')
# 首先尝试不带后缀的查询
for position in position_info:
if position.m_strInstrumentID == stock_code:
return position
# 如果不带后缀的查询失败,尝试带后缀的查询
for position in position_info:
if position.m_strInstrumentID == f"{stock_code}.sz":
return position
print(f"未找到股票 {stock_code} 或 {stock_code}.sz 的持仓信息")
return None
except Exception as e:
print(f"获取持仓信息时发生错误:{e}")
return None
def sell_stocks(ContextInfo):
if not trade_status['sell']:
trade_status['sell'] = True
for stock in sell_stocks_info:
stock_code = stock_code_dict.get(stock['name'])
if stock_code:
# 提交卖单
stock_code_without_sz = stock_code.split('.')[0]
position = get_position_info('8886006288', stock_code_without_sz, ContextInfo)
if position:
if stock['lots'] == 'ALL':
lots_to_sell = position.m_nVolume
else:
lots_to_sell = stock['lots']
# 卖出操作
passorder(24, 1101, '8886006288', stock_code, 5, -1, lots_to_sell, '', 1, '', ContextInfo)
print(f"已提交卖单:股票 {stock['name']},数量 {lots_to_sell} 手")
else:
print(f"股票 {stock['name']} 的持仓信息未找到")
else:
print(f"股票 {stock['name']} 的代码未找到")
status_printed = False
def print_trade_status(ContextInfo):
global status_printed
if status_printed: # 如果已经打印过,就跳过
return
print("正在打印交易状态...") # 添加调试输出
print_orders('8886006288', 'stock') # 打印委托情况
print_trades('8886006288', 'stock') # 打印成交情况
print_positions('8886006288', 'stock') # 打印最终持仓
# 打印完成后标记为已打印
status_printed = True
def buy_stocks(ContextInfo):
if not trade_status['buy']:
trade_status['buy'] = True
for stock in buy_stocks_info:
stock_code = stock_code_dict.get(stock['name'], '')
if stock_code:
# 确保price和volume是正确的类型
passorder(23, 1101, '8886006288', stock_code, 5, -1.0, float(stock['amount']), '', 1, '', ContextInfo)
else:
print(f"股票 {stock['name']} 的代码未找到")
def handlebar(ContextInfo):
return
结果
【2024-12-30 14:48:19.918】 [quote]start simulation mode
【2024-12-30 14:48:19.918】 程序开始运行...
--------------------------------------------------
当前持仓情况:
股票名称 股票代码 持仓量 最新价 持仓金额
--------------------------------------------------
30年国债 511090 0 123.12 0.00
十年国债 511260 0 135.34 0.00
国债 511010 0 141.00 0.00
国开 159650 1000 106.41 106409.00
天弘添利 164206 20000 1.49 29700.00
标普科技 161128 1100 5.12 5633.10
标普医疗 161126 6800 1.86 12620.80
美国精选 160140 9400 1.28 12013.20
全球芯片 501225 7800 1.48 11551.80
人工智能 161631 18800 1.51 28369.20
黄金 160719 9500 1.31 12416.50
原油 160723 8200 1.43 11726.00
日鑫利 RXL001 0 100.00 0.00
--------------------------------------------------
账户总资产:504312.38元
--------------------------------------------------
交易计划:
交易日期:2024-12-30 星期一
卖出时间:14:26:01, 买入时间:14:26:05
卖出计划:
- 股票名称:天弘添利, 股票代码:164206.sz, 数量:100手
买入计划:
--------------------------------------------------
【2024-12-30 14:48:20.093】 正在打印交易状态...
当前委托情况:
股票名称 方向 委托量 价格 委托状态 废单原因
30年国债 卖出 1300 123.57 已成 无
美国精选 卖出 9500 1.28 已成 无
银华日利 买入 11000 101.60 废单 未知原因
银华日利 买入 11000 101.60 废单 未知原因
标普科技 买入 550 5.12 废单 未知原因
天弘添利 卖出 100 1.49 废单 未知原因
标普科技 卖出 100 5.12 已成 无
十年国债 卖出 1000 135.52 已成 无
国债 卖出 700 141.27 已成 无
美国精选 买入 100 1.28 已成 无
美国精选 买入 9400 1.28 已成 无
天弘添利 买入 20000 1.49 已成 无
国开 买入 1000 106.40 已成 无
没有成交数据返回
当前持仓情况:
股票名称 股票代码 持仓量 最新价 持仓金额
--------------------------------------------------
30年国债 511090 0 123.12 0.00
十年国债 511260 0 135.34 0.00
国债 511010 0 141.00 0.00
国开 159650 1000 106.41 106409.00
天弘添利 164206 20000 1.49 29700.00
标普科技 161128 1100 5.12 5633.10
标普医疗 161126 6800 1.86 12620.80
美国精选 160140 9400 1.28 12013.20
全球芯片 501225 7800 1.48 11551.80
人工智能 161631 18800 1.51 28369.20
黄金 160719 9500 1.31 12416.50
原油 160723 8200 1.43 11726.00
日鑫利 RXL001 0 100.00 0.00
--------------------------------------------------
账户总资产:504312.38元
--------------------------------------------------
已提交卖单:股票 天弘添利,数量 100 手