1#coding:gbk
2import datetime
3
4# ====================== 自定义参数区(直接改这里) ======================
5STOCK_CODE = "513770.SH" # ETF/股票代码
6GRID_STEP = 0.001 # 网格价差1厘
7BASE_VOL = 200 # 基础委托股
8MULTIPLE = 2 # 下跌加仓倍数
9ACCOUNT_ID = "" # 填你的资金账号,空自动取默认
10# ======================================================================
11
12# 全局状态变量
13g_base_price = None # 当前基准价
14g_buy_oid = None # 买单委托号
15g_sell_oid = None # 卖单委托号
16g_cur_vol = BASE_VOL # 当前买单股(带倍数)
17g_inited = False # 是否初始化完成
18g_last_check = 0 # 上一次检测成交时间戳
19
20def init(ContextInfo):
21 global g_base_price,g_buy_oid,g_sell_oid,g_cur_vol,g_inited,g_last_check
22 print("【双向倍数触价网格】初始化完成")
23 g_base_price = None
24 g_buy_oid = None
25 g_sell_oid = None
26 g_cur_vol = BASE_VOL
27 g_inited = False
28 g_last_check = 0
29 # 订阅标的行情
30 ContextInfo.set_universe([STOCK_CODE])
31 if ACCOUNT_ID != "":
32 ContextInfo.set_account(ACCOUNT_ID)
33
34# Tick行情驱动,初始化 + 顺带轮询检测成交(无定时器,兼容所有版本)
35def handle_tick(ContextInfo, tick):
36 global g_base_price,g_inited,g_last_check,g_cur_vol,g_buy_oid,g_sell_oid
37 now = datetime.datetime.now()
38 now_ts = now.timestamp()
39
40 # 非交易时段跳过
41 if now.hour < 9 or (now.hour ==9 and now.minute <30):
42 return
43 if now.hour >=15:
44 return
45
46 # --------首次初始化,挂第一组双向单--------
47 if not g_inited:
48 g_base_price = round(tick.lastPrice, 3)
49 g_inited = True
50 print(f"自动获取初始基准价:{g_base_price}")
51 rebuild_pair(ContextInfo)
52 g_last_check = now_ts
53 return
54
55 # --------每1秒检测一次委托成交状态,不重复高频查询--------
56 if now_ts - g_last_check < 1.0:
57 return
58 g_last_check = now_ts
59
60 acc = ACCOUNT_ID if ACCOUNT_ID else ContextInfo.accid
61 target_oid = None
62 op_type = 0
63 deal_price = 0
64
65 # 查询全部委托
66 df_order = get_trade_detail_data(acc, "STOCK", "ORDER", ContextInfo)
67
68 # 检查买单是否完全成交 status=3全部成交
69 if g_buy_oid is not None:
70 df_buy = df_order[df_order.m_strOrderSysID == g_buy_oid]
71 if len(df_buy) > 0:
72 status = df_buy.iloc[0]["m_nOrderStatus"]
73 if status == 3:
74 target_oid = g_buy_oid
75 op_type = 23
76 deal_price = round(df_buy.iloc[0]["m_dOrderPrice"],3)
77
78 # 检查卖单是否完全成交
79 if g_sell_oid is not None:
80 df_sell = df_order[df_order.m_strOrderSysID == g_sell_oid]
81 if len(df_sell) > 0:
82 status = df_sell.iloc[0]["m_nOrderStatus"]
83 if status == 3:
84 target_oid = g_sell_oid
85 op_type = 24
86 deal_price = round(df_sell.iloc[0]["m_dOrderPrice"],3)
87
88 # 检测到单子完全成交,执行网格逻辑
89 if target_oid is not None:
90 print(f"委托{target_oid}全部成交,成交价{deal_price}")
91 cancel_all(ContextInfo)
92 g_base_price = deal_price
93 if op_type ==23:
94 g_cur_vol = int(g_cur_vol * MULTIPLE)
95 print(f"买单成交,加仓倍数,下档股数:{g_cur_vol}")
96 elif op_type ==24:
97 g_cur_vol = BASE_VOL
98 print(f"卖单成交,恢复基础股数:{BASE_VOL}")
99 rebuild_pair(ContextInfo)
100
101# 撤销当前全部双向委托
102def cancel_all(ContextInfo):
103 global g_buy_oid,g_sell_oid
104 acc = ACCOUNT_ID if ACCOUNT_ID else ContextInfo.accid
105 if g_buy_oid is not None:
106 try:
107 cancel(g_buy_oid, acc, "STOCK", ContextInfo)
108 print(f"撤销买单 {g_buy_oid}")
109 except Exception as e:
110 print(f"撤买单异常:{e}")
111 g_buy_oid = None
112 if g_sell_oid is not None:
113 try:
114 cancel(g_sell_oid, acc, "STOCK", ContextInfo)
115 print(f"撤销卖单 {g_sell_oid}")
116 except Exception as e:
117 print(f"撤卖单异常:{e}")
118 g_sell_oid = None
119
120# 重新生成一买一卖双向委托
121def rebuild_pair(ContextInfo):
122 global g_base_price,g_buy_oid,g_sell_oid,g_cur_vol
123 cancel_all(ContextInfo)
124 buy_p = round(g_base_price - GRID_STEP, 3)
125 sell_p = round(g_base_price + GRID_STEP, 3)
126 acc = ACCOUNT_ID if ACCOUNT_ID else ContextInfo.accid
127
128 # 挂买单,股数对齐100整数
129 fix_buy_vol = ((g_cur_vol + 99) // 100) * 100
130 oid_b = passorder(
131 opType=23, orderType=1101, accountid=acc,
132 orderCode=STOCK_CODE, prType=11, price=buy_p, volume=fix_buy_vol,
133 quickTrade=2, ContextInfo=ContextInfo
134 )
135 if oid_b > 0:
136 g_buy_oid = oid_b
137 print(f"挂买单 价:{buy_p} 股:{fix_buy_vol} 委托号:{oid_b}")
138 else:
139 g_buy_oid = None
140
141 # 挂卖单,固定基础股数
142 oid_s = passorder(
143 opType=24, orderType=1101, accountid=acc,
144 orderCode=STOCK_CODE, prType=11, price=sell_p, volume=BASE_VOL,
145 quickTrade=2, ContextInfo=ContextInfo
146 )
147 if oid_s > 0:
148 g_sell_oid = oid_s
149 print(f"挂卖单 价:{sell_p} 股:{BASE_VOL} 委托号:{oid_s}")
150 else:
151 g_sell_oid = None
152
153# 策略停止时自动清委托
154def on_strategy_stop(ContextInfo):
155 print("策略停止,撤销全部委托")
156 cancel_all(ContextInfo)