基于同花顺和QMT开发股票量化策略

量化交易已成为个人和机构投资者的重要工具。本文将详细介绍如何利用同花顺和迅投QMT平台开发完整的股票量化策略,从数据获取到策略实现,再到实盘部署的全过程。

1.

一、环境准备

1.1 软件安装与配置

同花顺i问财

按照pywencai 

pip install pywencai 

迅投QMT

  • 通过合作券商获取QMT安装包(如华泰、国泰君安等)

  • 安装并完成基础配置

  • 申请模拟盘或者实盘交易权限(需满足券商要求)

安装vscode,创建以下项目:

QMT_WENCAI
├── stock_selector.py    # 选股逻辑
├── quant_trader.py      # 交易执行
└── config.py           # 配置文件(可选) 

二、数据获取与处理

2.1 同花顺数据接口

历史数据获取:使用vscode ,创建新项目,如QMT_WENCAI,然后创建选股模块,供qmt使用

比如以下:

# stock_selector.py
import pywencai

def select_stocks():
    """
    选股主函数,返回符合以下条件的股票:
    1. 最近5日有过涨停
    2. 最近5日没有跌停
    3. 今日成交量 > 5日平均成交量
    4. 今日集合竞价涨幅在2%-3%之间
    5. 排除北交所、科创板、创业板、ST股票
    
    返回:
        list: 符合条件的股票代码列表(如['000001.SZ']),如果没有符合条件的股票则返回空列表
    """
    try:
        # 构造查询语句
        query = (
            "最近5日有过涨停,"
            "最近5日没有跌停,"
            "今日成交量>5日平均成交量,"
            "2<今日集合竞价涨幅<3,"
            "非北交所非科创板非创业板非ST"
        )
        
        # 调用 pywencai 获取数据
        df = pywencai.get(query=query, sort_key='成交金额', sort_order='desc')
        
        if df is None or df.empty:
            print("[StockSelector] 未找到符合条件的股票。")
            return []
        
        # 返回股票代码列表
        if '股票代码' in df.columns:
            return df['股票代码'].tolist()
        elif '代码' in df.columns:
            return df['代码'].tolist()
        else:
            print("[StockSelector] 错误:数据框中找不到股票代码列。")
            return []
            
    except Exception as e:
        print(f"[StockSelector] 查询时发生错误: {e}")
        return []

# 示例调用
if __name__ == "__main__":
    selected_stocks = select_stocks()
    print("符合条件的股票:", selected_stocks)

返回结果如下:

接着,使用qmt进行下单,打开券商提供的qmt,输入账号密码,勾选下面独立交易,就可以使用miniqmt了。

三、策略开发和下单

基于同花顺的选股结果,我们就可以继续开发策略了,quant_trader.py代码如下,其中 ACCOUNT_ID替换成自己的账号即可:

# quant_trader.py
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
from xtquant import xtconstant
import time
from datetime import datetime
from xtquant import xtdata
from stock_selector import select_stocks  # 直接导入选股函数

class MyXtQuantTraderCallback(XtQuantTraderCallback):
    def __init__(self):
        super().__init__()
        self.last_order_id = None
    
    def on_disconnected(self):
        print(f"[{datetime.now()}] 连接断开")
    
    def on_stock_order(self, order):
        self.last_order_id = order.order_id
        print(f"[{datetime.now()}] 委托回报: {order.stock_code} 状态:{order.order_status}")
    
    def on_stock_trade(self, trade):
        print(f"[{datetime.now()}] 成交回报: {trade.stock_code} 价格:{trade.traded_price} 数量:{trade.traded_volume}")
    
    def on_order_error(self, order_error):
        print(f"[{datetime.now()}] 委托失败: {order_error.error_msg}")
    
    def on_cancel_error(self, cancel_error):
        print(f"[{datetime.now()}] 撤单失败: {cancel_error.error_msg}")

class QuantTrader:
    def __init__(self, qmt_path, session_id, account_id):
        self.xt_trader = XtQuantTrader(qmt_path, session_id)
        self.acc = StockAccount(account_id)
        self.callback = MyXtQuantTraderCallback()
        self.connected = False
    
    def connect(self):
        try:
            self.xt_trader.register_callback(self.callback)
            self.xt_trader.start()
            
            connect_result = self.xt_trader.connect()
            if connect_result != 0:
                raise ConnectionError(f"交易服务器连接失败,错误码: {connect_result}")
            
            subscribe_result = self.xt_trader.subscribe(self.acc)
            if subscribe_result != 0:
                raise ConnectionError(f"账号订阅失败,错误码: {subscribe_result}")
            
            self.connected = True
            print(f"[{datetime.now()}] 交易服务器连接成功")
            return True
        except Exception as e:
            print(f"[{datetime.now()}] 连接失败: {e}")
            return False
    
    def get_realtime_price(self, stock_code):
        """获取股票实时价格"""
        try:
            quote = xtdata.get_full_tick([stock_code])
            if quote and stock_code in quote:
                return quote[stock_code]['lastPrice']
        except Exception as e:
            print(f"[{datetime.now()}] 获取实时价格失败: {e}")
        return None
    
    def place_order(self, stock_code, price, amount, order_direction):
        """下单函数"""
        try:
            order_id = self.xt_trader.order_stock(
                self.acc, 
                stock_code, 
                order_direction, 
                amount, 
                xtconstant.FIX_PRICE, 
                price, 
                '涨停策略', 
                '系统自动下单'
            )
            print(f"[{datetime.now()}] 下单成功: {stock_code} 方向:{order_direction} 价格:{price} 数量:{amount}")
            return order_id
        except Exception as e:
            print(f"[{datetime.now()}] 下单失败: {e}")
            return None
    
    def execute_buy(self, stock_code, amount=100):
        """执行买入操作"""
        price = self.get_realtime_price(stock_code)
        if price is None:
            print(f"[{datetime.now()}] 无法获取实时价格,取消买入")
            return False
        
        return self.place_order(stock_code, price, amount, xtconstant.STOCK_BUY) is not None
    
    def run_strategy(self):
        """执行策略"""
        try:
            if not self.connect():
                return
            
            print(f"[{datetime.now()}] 开始执行选股策略...")
            selected_stocks = select_stocks()  # 直接调用选股函数
            
            if not selected_stocks:
                print(f"[{datetime.now()}] 今日未选出符合条件的股票")
                return
            
            print(f"[{datetime.now()}] 选出的股票: {selected_stocks}")
            
            # 对每只选出的股票执行买入
            for stock_code in selected_stocks:
                if self.execute_buy(stock_code):
                    print(f"[{datetime.now()}] 成功买入: {stock_code}")
                else:
                    print(f"[{datetime.now()}] 买入失败: {stock_code}")
            
        except KeyboardInterrupt:
            print(f"[{datetime.now()}] 用户中断程序")
        except Exception as e:
            print(f"[{datetime.now()}] 策略执行出错: {e}")
        finally:
            print(f"[{datetime.now()}] 程序结束")

if __name__ == "__main__":
    # 配置参数(根据实际情况修改)
    QMT_PATH = 'C:\\国金QMT交易端模拟\\userdata_mini'
    SESSION_ID = 123456
    ACCOUNT_ID = '*******'
    
    print(f"[{datetime.now()}] 启动量化交易程序")
    trader = QuantTrader(QMT_PATH, SESSION_ID, ACCOUNT_ID)
    trader.run_strategy()

执行结果如下:

切换到qmt,可以看到我们刚才选出并下单的股票已经成功在qmt下单:

通过同花顺和QMT的组合,我们可以构建从数据获取、策略研发到实盘交易的完整量化交易体系。本文介绍的框架和方法可以作为起点,实际应用中需要根据个人风险偏好和市场特点进行调整。量化交易的核心在于持续优化和严格的风险控制,希望本文能为您的量化交易之旅提供有价值的参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值