QQ登录

只需一步,快速开始

广告载入中...
楼主: ablya

怎么看待黑马王子的《量柱擒涨停》?

[复制链接]
 楼主| 发表于 2026-7-15 12:32 | 显示全部楼层
调用与选股公式(以“一字横盘”为例)
数据存好后,你就可以在任何时候通过调用EXTDATA_USER函数来使用这些历史竞价数据了。

副图公式:查看竞价形态缩略图
你可以用下面的公式,在副图上把每天11个时间点的竞价价格连成线,直观地看到竞价形态。

plaintext
{竞价形态缩略图}
K915:=CONST(EXTDATA_USER(1,0));
K916:=CONST(EXTDATA_USER(2,0));
K917:=CONST(EXTDATA_USER(3,0));
K918:=CONST(EXTDATA_USER(4,0));
K919:=CONST(EXTDATA_USER(5,0));
K920:=CONST(EXTDATA_USER(6,0));
K921:=CONST(EXTDATA_USER(7,0));
K922:=CONST(EXTDATA_USER(8,0));
K923:=CONST(EXTDATA_USER(9,0));
K924:=CONST(EXTDATA_USER(10,0));
K925:=CONST(EXTDATA_USER(11,0));

竞价线: IF(CURRBARSCOUNT=11,K915,
        IF(CURRBARSCOUNT=10,K916,
        IF(CURRBARSCOUNT=9,K917,
        IF(CURRBARSCOUNT=8,K918,
        IF(CURRBARSCOUNT=7,K919,
        IF(CURRBARSCOUNT=6,K920,
        IF(CURRBARSCOUNT=5,K921,
        IF(CURRBARSCOUNT=4,K922,
        IF(CURRBARSCOUNT=3,K923,
        IF(CURRBARSCOUNT=2,K924,
        IF(CURRBARSCOUNT=1,K925,DRAWNULL)))))))))));
回复

使用道具 举报

 楼主| 发表于 2026-7-15 13:17 | 显示全部楼层
{一字形横盘选股(利用扩展数据)}
{1. 获取存储的11个竞价价格}
K915:=EXTDATA_USER(1,0);
K916:=EXTDATA_USER(2,0);
K917:=EXTDATA_USER(3,0);
K918:=EXTDATA_USER(4,0);
K919:=EXTDATA_USER(5,0);
K920:=EXTDATA_USER(6,0);
K921:=EXTDATA_USER(7,0);
K922:=EXTDATA_USER(8,0);
K923:=EXTDATA_USER(9,0);
K924:=EXTDATA_USER(10,0);
K925:=EXTDATA_USER(11,0);
{2. 计算竞价期间的最高价和最低价}
竞价最高价:= MAX6(MAX6(K915,K916,K917,K918,K919,K920),K921,K922,K923,K924,K925);
竞价最低价:= MIN6(MIN6(K915,K916,K917,K918,K919,K920),K921,K922,K923,K924,K925);

{3. 一字横盘判断:最高与最低价波动小于0.5%}
一字横盘条件 := (竞价最高价 - 竞价最低价) / 竞价最低价 * 100 < 0.5;

{4. 非一字涨停板判断:开盘价低于涨停价}
{计算涨停价,区分板块}
ZTJ := IF(CODELIKE('30') OR CODELIKE('68'), REF(C,1)*1.2, REF(C,1)*1.1);
{用DYNAINFO(4)获取当日开盘价}
非一字板 := DYNAINFO(4) < ZTJ;

{5. 基础筛选(剔除ST、次新等)}
基础条件 := NOT(NAMELIKE('ST') OR NAMELIKE('*ST')) AND FINANCE(42) > 60 AND FINANCE(3)=1;

{6. 输出选股信号}
XG: C<10 AND 一字横盘条件 AND 非一字板 AND 基础条件;
回复

使用道具 举报

 楼主| 发表于 2026-7-15 13:38 | 显示全部楼层
{计算涨停价,区分板块}
ZTJ := IF(FINANCE(3)=1, ZTPRICE(REF(C,1),0.1), ZTPRICE(REF(C,1),0.2));
{用DYNAINFO(4)获取当日开盘价}
非一字板 := DYNAINFO(4) < ZTJ;
回复

使用道具 举报

 楼主| 发表于 2026-7-15 14:13 | 显示全部楼层
{一字形横盘选股(利用扩展数据)}
{1. 获取存储的11个竞价价格}
K915:=EXTDATA_USER(1,0);
K916:=EXTDATA_USER(2,0);
K917:=EXTDATA_USER(3,0);
K918:=EXTDATA_USER(4,0);
K919:=EXTDATA_USER(5,0);
K920:=EXTDATA_USER(6,0);
K921:=EXTDATA_USER(7,0);
K922:=EXTDATA_USER(8,0);
K923:=EXTDATA_USER(9,0);
K924:=EXTDATA_USER(10,0);
K925:=EXTDATA_USER(11,0);
{2. 计算竞价期间的最高价和最低价}
竞价最高价:= MAX6(MAX6(K915,K916,K917,K918,K919,K920),K921,K922,K923,K924,K925);
竞价最低价:= MIN6(MIN6(K915,K916,K917,K918,K919,K920),K921,K922,K923,K924,K925);

{3. 一字横盘判断:最高与最低价波动小于0.5%}
一字横盘条件 := (竞价最高价 - 竞价最低价) / 竞价最低价 * 100 < 0.5;

{5. 基础筛选(剔除ST、次新等)}
基础条件:= NOT(NAMELIKE('ST') OR NAMELIKE('*ST')) AND FINANCE(42) > 60 AND FINANCE(3)=1;
开盘涨幅:=(DYNAINFO(4)/REF(C,1)-1)*100;
HS:=(VOL/CAPITAL*100);
ZRZF:=(REF(C,1)/REF(C,2)-1)*100;
{6. 输出选股信号}
XG: C<10 AND REF(HS,1)>2.36 AND 一字横盘条件 AND 基础条件 AND BETWEEN(开盘涨幅,0,2.36) AND BETWEEN(ZRZF,0,5);
回复

使用道具 举报

 楼主| 发表于 2026-7-15 19:07 | 显示全部楼层
{一字形横盘选股(利用扩展数据)}
{1. 获取存储的11个竞价价格}
K915:=EXTDATA_USER(1,0);
K916:=EXTDATA_USER(2,0);
K917:=EXTDATA_USER(3,0);
K918:=EXTDATA_USER(4,0);
K919:=EXTDATA_USER(5,0);
K920:=EXTDATA_USER(6,0);
K921:=EXTDATA_USER(7,0);
K922:=EXTDATA_USER(8,0);
K923:=EXTDATA_USER(9,0);
K924:=EXTDATA_USER(10,0);
K925:=EXTDATA_USER(11,0);
K1:=BETWEEN(K915/REF(C,1),0.995,1.005);
K2:=BETWEEN(K916/K915,0.995,1.005);
K3:=BETWEEN(K917/K916,0.995,1.005);
K4:=BETWEEN(K918/K917,0.995,1.005);
K5:=BETWEEN(K919/K918,0.995,1.005);
K6:=BETWEEN(K920/K919,0.995,1.005);
K7:=BETWEEN(K921/K920,0.995,1.005);
K8:=BETWEEN(K922/K921,0.995,1.005);
K9:=BETWEEN(K923/K922,0.995,1.005);
K10:=BETWEEN(K924/K923,0.995,1.005);
K11:=BETWEEN(K925/K924,0.995,1.005);
一字:=K1 AND K2 AND K3 AND K4 AND K5 AND K6 AND K7 AND K8 AND K9 AND K10 AND K11;
{2. 计算竞价期间的最高价和最低价}
最高价:= MAX6(MAX6(K915,K916,K917,K918,K919,K920),K921,K922,K923,K924,K925);
最低价:= MIN6(MIN6(K915,K916,K917,K918,K919,K920),K921,K922,K923,K924,K925);
{3. 一字横盘判断:最高与最低价波动小于0.5%}
一字横盘:= (最高价 - 最低价) / 最低价 * 100;

{5. 基础筛选(剔除ST、次新等)}
基础条件:= NOT(NAMELIKE('ST') OR NAMELIKE('*ST')) AND FINANCE(42) > 60 AND FINANCE(3)=1;
开盘涨幅:=(DYNAINFO(4)/REF(C,1)-1)*100;
涨幅:=(C/REF(C,1)-1)*100;
HS:=VOL/CAPITAL*100;
换手:=(DYNAINFO(15)/O)/FINANCE(46)*100;
昨日涨幅:=BETWEEN((REF(C,1)/REF(C,2)-1)*100,0,5);
竞昨比:=DYNAINFO(15)/REF(AMOUNT,1)*100;
DIF:=EMA(CLOSE,12)-EMA(CLOSE,26);DEA:=EMA(DIF,9);
MACDS:=IF(DIF>DEA,BARSLAST(CROSS(DIF,DEA))+1,IF(DEA>DIF,-(BARSLAST(CROSS(DEA,DIF))+1),DRAWNULL));

{6. 输出选股信号}
一字竞价: IF(C<10 AND REF(HS,1)>2.36 AND BETWEEN(开盘涨幅,0,3.82) AND 昨日涨幅 AND 竞昨比 >0.28 AND 一字,一字横盘,DRAWNULL);
开盘%:IF(ISVALID(一字竞价),开盘涨幅,DRAWNULL);
涨幅%:IF(ISVALID(一字竞价),涨幅,DRAWNULL);
量比:IF(ISVALID(一字竞价),DYNAINFO(48),DRAWNULL);
换手率:IF(ISVALID(一字竞价),换手,DRAWNULL);
竞昨比率:IF(ISVALID(一字竞价),竞昨比,DRAWNULL);
MACD数:IF(ISVALID(一字竞价),MACDS,DRAWNULL);
回复

使用道具 举报

 楼主| 发表于 2026-7-17 03:11 | 显示全部楼层
tdx_client.py 通达信行情客户端完整实现
tdx_client.py 是 ** 对接通达信官方行情接口(TDX Server)** 的 Python 客户端核心文件,用于获取 A 股实时行情、历史 K 线、分时数据、财务数据等,是量化交易、行情分析最常用的通达信对接工具。

完整版 tdx_client.py,基于官方通达信接口协议封装,支持:

连接通达信行情服务器
获取实时五档行情
获取日 K / 分钟 K 历史数据
获取股票列表、财务数据
心跳保活、自动重连


完整代码:tdx_client.py
{本文为理想论坛博主「白交易」的帖子,转载请注明出处。原文链接: https://www.55188.com/thread-40367778-1-1.html}

# -*- coding: utf-8 -*-
"""通达信行情客户端 TDX Client功能:连接通达信行情服务器,获取股票实时行情、K线、财务数据等稳定可用,兼容A股全市场"""
import socketimport structimport timefrom typing
import List, Dict, Optional
# 通达信官方公共行情服务器(国内可用,延迟低)
TDX_SERVERS = [    ("119.147.212.81", 7709),    ("119.147.212.82", 7709),    ("119.147.212.83", 7709),    ("121.14.104.69", 7709),    ("121.14.104.70", 7709),]
class TdxClient:   
def __init__(self):        
self.socket = None        
self.connected = False        
self.server_ip = None        
self.server_port = None        
self.last_heartbeat = 0   
def connect(self, ip: Optional[str] = None, port: Optional[int] = None) -> bool:        
"""连接通达信服务器,自动选择最优节点"""        
if self.connected:            
return True        
# 自动选择服务器        
if not ip or not port:            
for server_ip, server_port in TDX_SERVERS:               
try: self._connect_single(server_ip, server_port)                    
print(f"&#9989; 连接成功:{server_ip}:{server_port}")                    
return True               
except Exception as e:                    
continue            
raise Exception("所有通达信服务器连接失败")        
else:            
self._connect_single(ip, port)            
return True   
def _connect_single(self, ip: str, port: int):        """单节点连接"""        
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        
self.socket.settimeout(10)        
self.socket.connect((ip, port))        
self.server_ip = ip        
self.server_port = port        
self.connected = True        
self.heartbeat()   
def disconnect(self):        
"""断开连接"""        
if self.socket:            
self.socket.close()        
self.connected = False        
print("&#9989; 已断开通达信服务器")   
def heartbeat(self):        
"""心跳包(保活)"""        
if not self.connected:            
return        
try:   hb = b'\x00\x00\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'            
self.socket.send(hb)            
self.socket.recv(1024)            
self.last_heartbeat = time.time()        
except: self.connected = False   
def auto_heartbeat(self):        
"""自动心跳(建议循环调用)"""        
if time.time() - self.last_heartbeat > 30:            
self.heartbeat()   
# ==================== 核心行情接口 ====================   
def get_security_quotes(self, codes: List[str]) -> List[Dict]:        
"""        获取实时五档行情        
:param codes: 股票代码列表,如 ["600000", "000001", "300750"]        
:return: 行情字典列表        """        
if not self.connected:            
self.connect()        
# 构造请求包        
req = self._build_quote_request(codes)        
self.socket.send(req)        
data = self.socket.recv(8192)        
# 解析行情数据        
return self._parse_quote_data(data, codes)   
def get_kline(self, code: str, category: int = 0, start: int = 0, count: int = 60) -> List[Dict]:        
"""        获取K线历史数据        
:param code: 股票代码        
:param category: K线类型 0=5min 1=15min 2=30min 3=1h 4=1d 5=1w 6=1M        
:param start: 起始位置        
:param count: 获取数量        
:return: K线列表        """        
if not self.connected:            
self.connect()        
req = self._build_kline_request(code, category, start, count)        
self.socket.send(req)        
data = self.socket.recv(8192 * 4)        
return self._parse_kline_data(data)   
# ==================== 内部打包/解包函数 ====================   
def _build_quote_request(self, codes: List[str]) -> bytes:        
"""构造行情请求包"""        
market = 0  
# 0沪市 1深市        
buf = bytearray(12 + len(codes) * 7)        
struct.pack_into('<IHB', buf, 0, 0x101, len(codes), market)        
for i, code in enumerate(codes):            
struct.pack_into('<6s', buf, 12 + i * 7, code.encode())        
return bytes(buf)   
def _parse_quote_data(self, data: bytes, codes: List[str]) -> List[Dict]:        
"""解析实时行情"""        
result = []        
pos = 0        
for code in codes:            
if pos + 192 > len(data):  break            
d = data[pos:pos+192]            
pos += 192            
# 字段解包            
price = struct.unpack('<I', d[20:24])[0] / 100            
open_p = struct.unpack('<I', d[24:28])[0] / 100          
 high = struct.unpack('<I', d[28:32])[0] / 100            
low = struct.unpack('<I', d[32:36])[0] / 100            
close = struct.unpack('<I', d[36:40])[0] / 100            
vol = struct.unpack('<I', d[40:44])[0]            
amount = struct.unpack('<I', d[44:48])[0] / 100            
# 五档买卖            
bid1 = struct.unpack('<I', d[48:52])[0] / 100            
ask1 = struct.unpack('<I', d[68:72])[0] / 100            
bid_vol1 = struct.unpack('<I', d[52:56])[0]            
ask_vol1 = struct.unpack('<I', d[72:76])[0]            
result.append({ "code": code, "price": price,"open": open_p,"high": high,"low": low,"close": close, "vol": vol, "amount": amount,  "bid1": bid1,"ask1": ask1,  "bid_vol1": bid_vol1,  "ask_vol1": ask_vol1  })        
return result   
def _build_kline_request(self, code: str, category: int, start: int, count: int) -> bytes:        
"""K线请求包"""        
market = 0 if code.startswith('6') else 1        
buf = bytearray(24)        
struct.pack_into('<IHB6sIII', buf, 0, 0x10c, 1, market, code.encode(), category, start, count)        
return bytes(buf)   
def _parse_kline_data(self, data: bytes) -> List[Dict]:        
"""解析K线"""        
result = []        
num = struct.unpack('<I', data[4:8])[0]        
pos = 8        
for _ in range(num):            
if pos + 44 > len(data): break            
d = data[pos:pos+44]            pos += 44            
time_int = struct.unpack('<I', d[0:4])[0]            
open_p = struct.unpack('<I', d[4:8])[0] / 100            
high = struct.unpack('<I', d[8:12])[0] / 100            
low = struct.unpack('<I', d[12:16])[0] / 100            
close = struct.unpack('<I', d[16:20])[0] / 100            
vol = struct.unpack('<I', d[20:24])[0]            
amount = struct.unpack('<I', d[24:28])[0] / 100            
result.append({ "time": time_int,  "open": open_p,  "high": high, "low": low,  "close": close, "vol": vol,  "amount": amount })        
return result
# ==================== 测试示例 ====================
if __name__ == '__main__':   
client = TdxClient()   
try:        
# 连接服务器        
client.connect()        
# 获取实时行情        
quotes = client.get_security_quotes(["600000", "000001", "300750"])        
print("\n&#128202; 实时行情:")        
for q in quotes:            
print(q)        
# 获取日K线        
kline = client.get_kline("600000", category=4, count=10)        
print("\n&#128200; 日K线(最近10天):")        
for k in kline:            
print(k)   
except Exception as e:        
print(f"&#10060; 错误:{e}")   
finally: client.disconnect()
回复

使用道具 举报

 楼主| 发表于 2026-7-17 07:07 | 显示全部楼层
from eltdx import TdxClient

with TdxClient(timeout=3) as client:
    series = client.auctions.series("sh600540")
    for point in series.points:
        print(point.time_label, round(point.price,2))
        

回复

使用道具 举报

 楼主| 发表于 2026-7-17 07:09 | 显示全部楼层
ablya 发表于 2026-7-17 07:07
from eltdx import TdxClient

with TdxClient(timeout=3) as client:

取得集合竞价时间和价格
回复

使用道具 举报

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

本版积分规则

快速回复 返回顶部 返回列表