返回列表 发布新帖

这段代码有时出现废单,请问是什么原因

2478 1
发表于 2024-12-30 14:43:19 | 显示全部楼层 阅读模式

早上执行好好的,下午执行就出现废单了,想知道原因,谢谢,执行结果贴在后面

#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 手

评论1

Clarence.罗
发表于 2025-1-2 12:16:13 | 显示全部楼层
代码很优美啊!

代码看不出废单原因,

你点qmt主界面下面的消息链接,点开会弹出一个页面,滚动到右边看废单原因,我遇到过资金不足

回复

您需要登录后才可以回帖 登录 | 立即注册

客服专线

400-080-8112

用思考的速度交易,用真诚的态度合作,我们是认真的!
  • 关注公众号
  • 添加微信客服
Copyright © 2001-2025 迅投QMT社区 版权所有 All Rights Reserved. 京ICP备2025122616号-3
关灯 快速发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表