返回列表 发布新帖

总结~首次下载软件如何使用xtquant模块链接miniQMT客户端的几种方式

93 0
发表于 2025-8-11 10:04:47 | 显示全部楼层 阅读模式

企业微信截图_17548751802903.png

miniQMT是迅**司提供的正经软件,不是什么外挂,大家可以放心使用,已经有多家券商向交易所报备过这套软件相关功能,个人用户也可以跟机构投资者一样合规使用miniQMT实现程序化交易,展现了公平原则。

首次下载软件如何使用xtquant模块链接miniQMT客户端

1、(券商版)传统方式 复制粘贴

①请先联系开通指定证券账户后, 再开通QMT交易权限(需包含miniqmt功能),会在电子邮箱收到下载地址。

②然后在设置》系统设置》模型设置》点击下载“python库下载”

③下载完成后找到 QMT文件安装目录下//bin.x64//lib//site-packags//xtquant

④复制到本地python环境下的//site-packags文件夹

⑤同时必须登录极简版QMT(XtMiniQmt.exe) 就可以本地调用python的miniQMT接口了。

⑥运行导入行情模块xtdata和交易模块xttrader, 实现本地程序化交易,开户咨询微信miniqmt

2、(投研版)迅投官网下载压缩包

迅**司提供了多个版本,包括历史版本的xtquant压缩包下载链接: xtquant版本下载 | 迅投知识库

下载解压后,安装到自己本地的python路径//lib//site-packags//下

同时启动miniqmt客户端就可以实现数据调用和连接交易。

3、(通用版)通过pip下载安装xtquant包

这种方法比较简单 通过cmd环境python的pip功能安装xtquant

pip install xtquant

目前这种方式已经成为主流方式。

4、(进阶版)通过python代码自动安装

代码安装集成了环境检测和xtquant安装,保存path环境等功能 以下代码仅供参考:

# -*- coding: utf-8 -*-
"""
申请开通QMT请添加微信咨询miniqmt,获取更多资料访问https://miniqmt.com/
此代码脚本仅用于软件测试,不能用于实盘交易,以此代码进行交易本人不承担任何损失
"""
import sys
import os
import subprocess
import importlib

# ================================
# 第一步:检查并安装必需的第三方包
# ================================

REQUIRED_PACKAGES = ['psutil', 'xtquant']

def ensure_packages_installed():
    """检查并安装所需的第三方包"""
    for package in REQUIRED_PACKAGES:
        try:
            importlib.import_module(package)
            print(f"✅ {package} 已安装")
        except ImportError:
            print(f"⚠️ 未找到 {package},正在安装...")
            try:
                subprocess.check_call([
                    sys.executable, "-m", "pip", "install", package
                ])
                print(f"✅ {package} 安装成功")
            except subprocess.CalledProcessError as e:
                print(f"❌ 安装 {package} 失败,请手动执行: pip install {package}")
                sys.exit(1)

# --- 在导入其他模块前先确保依赖存在 ---
print(" 🔍 正在检查依赖环境...\n","📘 更多资料访问miniqmt.com")
ensure_packages_installed()

# === 现在可以安全导入第三方库 ===
import psutil
import ctypes
from ctypes import wintypes

# -----------------------------
# 1. 检查 xtquant 模块
# -----------------------------
def check_xtquant():
    """检查 xtquant 模块是否安装并获取版本"""
    try:
        xtquant = importlib.import_module('xtquant')
        print("xtquant: ✅ 已安装")

        # 尝试获取版本信息
        version = "未知版本"
        try:
            # 尝试通过importlib.metadata获取
            from importlib.metadata import version as md_version
            version = md_version('xtquant')
        except ImportError:
            # 回退到模块属性
            if hasattr(xtquant, '__version__'):
                version = xtquant.__version__
            else:
                # 尝试获取文件版本信息
                try:
                    version = get_module_file_version(xtquant)
                except Exception:
                    pass

        print(f"xtquant 版本: {version}")
        return True
    except ImportError as e:
        print(f"xtquant: ❌ 未安装 ({e})")
        return False

def get_module_file_version(module):
    """尝试从模块文件属性获取版本信息"""
    file_path = module.__file__
    if file_path.endswith('.pyc'):
        file_path = file_path[:-1]  # 转换为.py文件

    if os.path.exists(file_path):
        # 读取文件内容查找版本信息
        with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
            for line in f:
                if '__version__' in line:
                    parts = line.split('=')
                    if len(parts) > 1:
                        return parts[1].strip().strip("'\"")

    # 尝试获取文件修改时间作为替代
    mtime = os.path.getmtime(file_path)
    from datetime import datetime
    return f"文件修改时间: {datetime.fromtimestamp(mtime).strftime('%Y-%m-%d')}"

# -----------------------------
# 2. Windows API:获取指定 PID 的窗口标题
# -----------------------------
user32 = ctypes.WinDLL('user32', use_last_error=True)

user32.GetWindowThreadProcessId.argtypes = (wintypes.HWND, ctypes.POINTER(wintypes.DWORD))
user32.GetWindowTextLengthW.argtypes = (wintypes.HWND,)
user32.GetWindowTextW.argtypes = (wintypes.HWND, wintypes.LPWSTR, ctypes.c_int)
user32.EnumWindows.argtypes = (ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM), wintypes.LPARAM)

def get_window_title_by_pid(pid):
    """枚举所有窗口,找到属于指定 PID 的主窗口标题"""
    titles = []

    def callback(hwnd, lParam):
        pid_ptr = wintypes.DWORD()
        user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid_ptr))
        if pid_ptr.value == pid:
            length = user32.GetWindowTextLengthW(hwnd)
            if length > 0:
                buffer = ctypes.create_unicode_buffer(length + 1)
                user32.GetWindowTextW(hwnd, buffer, length + 1)
                title = buffer.value.strip()
                if title:
                    titles.append(title)
        return True

    WNDENUMPROC = ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM)
    user32.EnumWindows(WNDENUMPROC(callback), 0)
    return titles[0] if titles else None

# -----------------------------
# 3. 获取 miniQMT 安装/运行状态
# -----------------------------
def get_miniqmt_info():
    """检查 miniQMT 是否运行,返回安装目录和窗口标题"""
    for proc in psutil.process_iter(['name', 'exe', 'pid']):
        if proc.info['name'] == 'XtMiniQmt.exe':
            try:
                exe_path = proc.info['exe']
                pid = proc.info['pid']
                install_dir = os.path.dirname(exe_path)
                window_title = get_window_title_by_pid(pid)
                return {
                    'install_dir': install_dir,
                    'process_name': window_title or f"XtMiniQmt.exe (PID: {pid})",
                    'status': 'running'
                }
            except (psutil.NoSuchProcess, psutil.AccessDenied, OSError):
                continue

    # 快捷方式 fallback(可选)
    shortcut_name = "国金证券QMT交易端.lnk"
    desktop = os.path.expanduser("~/Desktop")
    shortcut_path = os.path.join(desktop, shortcut_name)

    if os.path.exists(shortcut_path):
        target = get_target_from_shortcut(shortcut_path)
        if target and os.path.exists(target):
            install_dir = os.path.dirname(target)
            return {
                'install_dir': install_dir,
                'process_name': '未运行',
                'status': 'installed'
            }

    return {
        'install_dir': '未找到',
        'process_name': '未运行',
        'status': 'not_found'
    }

# -----------------------------
# 4. 解析快捷方式目标
# -----------------------------
def get_target_from_shortcut(lnk_path):
    cmd = f'powershell -command "$s=(New-Object -ComObject WScript.Shell).CreateShortcut(\'{lnk_path}\'); $s.TargetPath"'
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=5)
        return result.stdout.strip() if result.returncode == 0 else None
    except Exception:
        return None

# -----------------------------
# 5. 提取账户名(从窗口标题)
# -----------------------------
def extract_account_from_title(title):
    """从窗口标题提取账号,例如 '55011888 - 国金QMT交易端模拟 1.0.0.36251'"""
    if title and ' - ' in title:
        account = title.split(' - ')[0].strip()
        if account.isdigit():
            return account
    return None

# -----------------------------
# 6. 保存 path.txt
# -----------------------------
def save_path_file(install_dir, account):
    """生成 path.txt,路径替换 bin.x64 -> userdata_mini"""
    try:
        base_dir = os.path.dirname(install_dir.rstrip('\\/'))
        userdata_path = os.path.join(base_dir, "userdata_mini")

        # 写入文件
        with open('path.txt', 'w', encoding='utf-8') as f:
            f.write(f"{userdata_path}\n")
            f.write(f"{account}\n")

        print(f"✅ 已生成环境配置所需文件 path.txt:\n   {userdata_path}\n   {account}")
    except Exception as e:
        print(f"❌ 保存 path.txt 失败: {e}")

# -----------------------------
# 7. 主函数
# -----------------------------
def main():
    print("=" * 50)
    print("🔍 开始检查运行环境")
    print("=" * 50)

    # 输出Python环境信息
    print(f"Python版本: {sys.version.split()[0]}")
    print(f"Python路径: {sys.executable}")
    print(f"运行路径: {os.getcwd()}")

    # 检查模块
    print("\n" + "=" * 50)
    print("📦 xtquant 模块检查")
    print("=" * 50)
    xtquant_ok = check_xtquant()

    # 获取 miniQMT 状态
    print("\n" + "=" * 50)
    print("📊 miniQMT 终端状态")
    print("=" * 50)

    miniqmt = get_miniqmt_info()
    status_map = {
        'running': '🟢 运行中',
        'installed': '🟡 已安装(未运行)',
        'not_found': '🔴 未找到'
    }

    print(f"miniQMT路径: {miniqmt['install_dir']}")
    print(f"miniQMT窗口: {miniqmt['process_name']}")
    print(f"状态: {status_map.get(miniqmt['status'], '未知')}")

    # 建议与保存逻辑
    print("\n" + "=" * 50)
    print("💡 环境检测配置")
    print("=" * 50)

    if miniqmt['status'] == 'not_found':
        print("⚠️ 未找到 miniQMT,请在登录QMT终端时勾选'独立交易'。")
    elif not xtquant_ok:
        print("⚠️ xtquant 模块未安装 ")
    elif miniqmt['status'] == 'running':
        account = extract_account_from_title(miniqmt['process_name'])
        if account:
            print("✅ 环境准备就绪,可以开始使用 miniQMT 量化开发!")
            print("📘 更多资料请访问:https://miniqmt.com")
            # 保存 path.txt
            save_path_file(miniqmt['install_dir'], account)
        else:
            print("⚠️ 运行 未登录,请检查miniQMT终端状态是否已经登录账户。")
            print("✅ 环境正常,但未检测到登录账户,未生成环境文档 path.txt")
    else:
        print("🟡 miniQMT 已安装但未运行。")
        print("⚠️ 请先启动 miniQMT 登录交易。")

if __name__ == "__main__":
    main()
客服专线

400-080-8112

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