-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
93 lines (73 loc) · 2.92 KB
/
Copy pathmain.py
File metadata and controls
93 lines (73 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python3
# Copyright (c) 2026 shing1211
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
46 — CurKline Handler
CurKlineHandlerBase streams real-time candlestick updates as they build up.
Unlike request_history_kline which gives you closed candles,
this handler gives you the LIVE candle as it forms -- every tick
that moves the open/high/low/close/vol.
Useful for:
- Real-time MACD/strategy signals without polling
- Intraday candlestick pattern recognition
- Live chart rendering
SDK: OpenQuoteContext.set_handler() + CurKlineHandlerBase
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
import time
import futu as ft
from connect import create_quote_context
class MyCurKlineHandler(ft.CurKlineHandlerBase):
def on_recv_rsp(self, rsp_pb):
ret_code, content = super().on_recv_rsp(rsp_pb)
if ret_code != ft.RET_OK:
return ft.RET_ERROR, content
# content is a DataFrame with K-line fields:
# code, kline_type, open, high, low, close, volume, turnover, ...
for _, row in content.iterrows():
code = row.get("code", "?")
ktype = row.get("kline_type", "?")
open_ = row.get("open", 0)
high = row.get("high", 0)
low = row.get("low", 0)
close = row.get("close", 0)
vol = row.get("volume", 0)
turn = row.get("turnover", 0)
ts = row.get("time", "?") if "time" in row else "?"
print(f" [{code}] {ktype} | {ts} | "
f"O={float(open_):.2f} H={float(high):.2f} "
f"L={float(low):.2f} C={float(close):.2f} "
f"| vol={int(vol):,} turn={float(turn):,.0f}")
return ft.RET_OK, content
def main():
ctx = create_quote_context()
try:
ctx.set_handler(MyCurKlineHandler())
stock = "HK.00700"
# Subscribe to daily K-line push (K_DAY = current day's candle)
ret, _ = ctx.subscribe(stock, ft.SubType.K_DAY)
if ret != 0:
print(f"Subscribe failed: {ret}")
return
print(f"Subscribed to {stock} K_DAY push (today's live candle).")
print("Each push = one updated candle as it forms.\n")
print("Waiting 20s for candle updates (press Ctrl+C to exit)...\n")
time.sleep(20)
finally:
ctx.close()
print("\nDone.")
if __name__ == "__main__":
main()