小隐的博客

人生在世,笑饮一生
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

python: 与通达信联动

Posted on 2025-05-31 14:09  隐客  阅读(149)  评论(0)    收藏  举报
import win32gui
import win32con
import win32api

import re
import win32clipboard
import time

MY_SYMBOLS = [
    "SHFE.rb", "SHFE.ru", "SHFE.fu", "SHFE.ag", "SHFE.cu", "SHFE.ss",
    "SHFE.ao", "SHFE.zn", "SHFE.ni", "SHFE.sn", "SHFE.al", "SHFE.pb",
    "SHFE.hc", "SHFE.sp", "INE.nr", "INE.sc", "DCE.y", "DCE.m", "DCE.p",
    "DCE.lh", "DCE.v", "DCE.pp", "DCE.eg", "DCE.eb", "DCE.pg", "DCE.jd",
    "DCE.jm", "DCE.c", "DCE.l", "CZCE.SA", "CZCE.OI", "CZCE.UR", "CZCE.CF",
    "CZCE.MA", "CZCE.TA", "CZCE.RM", "CZCE.FG", "CZCE.SR", "CZCE.CJ",
    "CZCE.PK", "CZCE.SM", "CZCE.SH", "GFEX.lc", "GFEX.si", "GFEX.ps"
]
def ensure_window_foreground(hwnd, max_retries=5, interval=0.2):
    """确保窗口成功前置的循环检测函数"""
    for attempt in range(max_retries):
        try:
            # 先最小化再恢复窗口(提高前置成功率)
            win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE)
            win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
            
            # 尝试设置前置窗口
            win32gui.SetForegroundWindow(hwnd)
            
            # 验证是否成功前置
            if win32gui.GetForegroundWindow() == hwnd:
                return True
                
        except Exception as e:
            print(f"窗口前置尝试 {attempt+1} 失败: {e}")
        
        time.sleep(interval)
    
    return False
def send_keys_to_window(class_name, keys):
    # 查找窗口句柄
    hwnd = win32gui.FindWindow(class_name, None)
    if not hwnd:
        print(f"未找到类名为 {class_name} 的窗口")
        return False
    if not ensure_window_foreground(hwnd):
        print("窗口前置失败")
        return False
    
    print("send " ,keys)
    time.sleep(0.3)
 
    
    # 发送键盘消息
    for char in keys:
        if char == '\n':  # 回车键
            win32api.keybd_event(win32con.VK_RETURN, 0, 0, 0)
            win32api.keybd_event(win32con.VK_RETURN, 0, win32con.KEYEVENTF_KEYUP, 0)
        else:
            # 发送普通字符
            win32api.keybd_event(ord(char.upper()), 0, 0, 0)
            win32api.keybd_event(ord(char.upper()), 0, win32con.KEYEVENTF_KEYUP, 0)
        time.sleep(0.05)  # 按键间隔
    
    return True

def format_contract_code(contract):
    """处理CZCE合约的特殊格式"""
    exchange, code = contract.split('.')
    if exchange == 'CZCE':
        # 匹配商品代码和数字部分
        match = re.match(r'([A-Za-z]+)(\d+)', code)
        if match:
            product = match.group(1)
            numbers = match.group(2)
            # 如果是3位数字,前面补2
            if len(numbers) == 3:
                numbers = '2' + numbers
            return f"{product}{numbers}"
    return code

def extract_first_bracket(text):
    match = re.search(r'\[([^]]+)\]', text)
    return match.group(1) if match else None

def is_valid_contract(code):
    # 提取基础合约代码(去除年月数字部分)
    base_code = re.sub(r'(\d{4}|\d{3})$', '', code)
    return base_code in MY_SYMBOLS

def monitor_clipboard(interval=1):
    last_content = ""
    try:
        while True:
            try:
                win32clipboard.OpenClipboard()
                if win32clipboard.IsClipboardFormatAvailable(win32clipboard.CF_TEXT):
                    data = win32clipboard.GetClipboardData()
                    if isinstance(data, str) and data != last_content:
                        symbol = extract_first_bracket(data)
                        if symbol and is_valid_contract(symbol):
                            print(f"有效合约代码: {symbol}")      
                            formatted_code = format_contract_code(symbol)
                            send_keys_to_window("TdxW_MainFrame_Class", formatted_code + "\n")
                        last_content = data
            finally:
                win32clipboard.CloseClipboard()
            time.sleep(interval)
    except KeyboardInterrupt:
        print("监控已停止")

if __name__ == "__main__":
    print("合约代码监控启动 (Ctrl+C退出)")
    monitor_clipboard()

复制文本后,可以将通达信界面打开显示相应的合约、

类似这这样的:

time:2025-05-30 13:36:00
[DCE.eb2507][short],price:7142.0 

QQ交流