From cac2a586cc4cedb594015f2e95111ad5b30c286f Mon Sep 17 00:00:00 2001 From: YuYuKunKun Date: Tue, 2 Jul 2024 12:46:57 +0800 Subject: [PATCH] Update chan.py --- chan.py | 330 ++++++++++++++++++++++++++------------------------------ 1 file changed, 154 insertions(+), 176 deletions(-) diff --git a/chan.py b/chan.py index 98bdc04..d17924e 100644 --- a/chan.py +++ b/chan.py @@ -111,13 +111,15 @@ class Freq(Enum): S5: int = 5 S12: int = 12 m1: int = 60 * 1 - m3: int = 60 * 3 - m5: int = 60 * 5 - m15: int = 60 * 15 - m30: int = 60 * 30 - H1: int = 60 * 60 * 1 - H2: int = 60 * 60 * 2 - H4: int = 60 * 60 * 4 + m3: int = 60 * 3 # 180 + m5: int = 60 * 5 # 300 + m15: int = 60 * 15 # 900 + m30: int = 60 * 30 # 1800 + H1: int = 60 * 60 * 1 # 3600 + H2: int = 60 * 60 * 2 # 7200 + H4: int = 60 * 60 * 4 # 14400 + H6: int = 60 * 60 * 6 # 21600 + H12: int = 60 * 60 * 12 # 43200 D1: int = 60 * 60 * 24 # 86400 D3: int = 60 * 60 * 24 * 3 # 259200 @@ -176,7 +178,7 @@ def _print(*args, **kwords): def dp(*args, **kwords): if not 0: - _print(*args, **kwords) + _print(*args, **kwords) #! jing def bdp(*args, **kwargs): @@ -386,13 +388,13 @@ def update(self, observable: "Observable", **kwords: Any): assert self._appended is True, self @classmethod - def plot_bsp(cls, _type, bar: "NewBar", bsp: BSPoint): + def plot_bsp(cls, _type, bar: "NewBar", bsp: BSPoint, real: bool = True): if cls.CAN: offset = NewBar.OBJS[-1].index - bar.index points = [ {"time": int(bar.dt.timestamp()), "price": bar.speck}, ] - if (_type, bar, bsp) in Observer.sigals: + if (_type, bar, bsp) in Observer.sigals and real: Observer.sigal = None return # print("plot_bsp", bar, bsp, RawBar.OBJS[-1].dt) @@ -409,11 +411,13 @@ def plot_bsp(cls, _type, bar: "NewBar", bsp: BSPoint): "text": f"{_type}{bsp.value}{offset}", } properties = {"title": f"{_type}{bsp.name}"} + if not real: + properties["color"] = "#FFFA50" message = { "type": "shape", - "cmd": ZhongShu.CMD_APPEND, + "cmd": ZhongShu.CMD_APPEND if real else ZhongShu.CMD_MODIFY, "name": options["shape"], - "id": bar.shape_id, + "id": bar.shape_id + _type, "points": points, "options": options, "properties": properties, @@ -639,7 +643,7 @@ def __repr__(self): def update(self, observer: "Observer", **kwords: Any): cmd = kwords.get("cmd") - # return + return if cmd in (RawBar.CMD_APPEND,): message = { @@ -717,9 +721,6 @@ class NewBar(BaseChanObject, Observer): 缠论 K线 """ - KEY_BI_ZS_ID = "KEY_BI_ZS_ID" - KEY_DUAN_ID = "KEY_DUAN_ID" - CMD_APPEND = "append" OBJS: List["NewBar"] = [] @@ -776,7 +777,7 @@ def __init__( def update(self, observable: "Observable", **kwords: Any): cmd = kwords.get("cmd") - return + # return # https://www.tradingview.com/charting-library-docs/v26/api/interfaces/Charting_Library.CreateShapeOptions/ point = {"time": int(self.dt.timestamp())} options = { @@ -2251,13 +2252,14 @@ def __eq__(self, other: "ZhongShu") -> bool: def update(self, observable: "Observable", **kwords: Any): cmd = kwords.get("cmd") - obj = kwords.get("obj") + obj: Observable = kwords.get("obj") if cmd == f"{self.__class__.__name__}_{BaseChanObject.CMD_DONE}": self.notify_observer(cmd=ZhongShu.CMD_MODIFY, obj=self) return - if cmd == f"{Duan.__class__.__name__}_{BaseChanObject.CMD_DONE}": + if cmd == f"{Duan.__name__}_{BaseChanObject.CMD_DONE}": self.notify_observer(cmd=ZhongShu.CMD_MODIFY, obj=self) + obj.detach_observer(self) return if cmd == Duan.CDM_ZS_OBSERVER: @@ -2270,6 +2272,7 @@ def update(self, observable: "Observable", **kwords: Any): Direction.JumpUp, Direction.JumpDown, ): + self.third = obj return self.elements.append(self.third) self.third = None @@ -2398,6 +2401,7 @@ def third(self): @third.setter def third(self, third): + old = self.__third self.__third = third if third is not None: self.done = True @@ -2408,6 +2412,12 @@ def third(self, third): else: self.done = False + if old: + if old.end.shape is Shape.G: + Observer.plot_bsp(self._type, old.end.mid, BSPoint.TS, False) + else: + Observer.plot_bsp(self._type, old.end.mid, BSPoint.TB, False) + @property def left(self) -> Union[Bi, Duan, RawBar, NewBar]: return self.elements[0] if self.elements else None @@ -2482,6 +2492,10 @@ def pop_element(self, obj: Union[Bi, Duan], _from): if self.last_element is not obj: dp("警告:中枢元素不匹配!!!", self.last_element, obj) self.elements.pop() + if obj.end.mid.bsp: + print("消除", obj.end.mid) + Observer.plot_bsp(self._type, obj.end.mid, obj.end.mid.bsp[-1], False) + # if _from == "analyzer" and self._type == "Duan": # self.notify_observer(cmd=ZhongShu.CMD_MODIFY) else: @@ -2493,15 +2507,6 @@ def append_element(self, obj: Union[Bi, Duan], _from): size = len(self.elements) if size >= 3 and (size + 1) % 2 == 0: - """print( - "计算买卖点", - size, - self._type, - self.dd, - self.gg, - self.elements[1].direction, - obj.direction, - )""" enter = ( Bi.OBJS[self.elements[0].index - 1] if self._type == "Bi" @@ -3097,6 +3102,7 @@ def init(self, size): break if Observer.CAN and Observer.thread is None: break + Observer.thread = None @staticmethod def ohlc(pair: str, step: int, start: int, end: int, length: int = 1000) -> Dict: @@ -3217,11 +3223,13 @@ def main_load_file1(path: str = "btcusd-300-1713295800-1715695500.dat"): return obj -def main_bitstamp(): - bitstamp = Bitstamp("btcusd", freq=Freq.m5) - bitstamp.init(2000) - bitstamp.toCharts() - return bitstamp +def main_bitstamp(symbol="btcusd", limit=500, freq=Freq.m5): + def func(): + bitstamp = Bitstamp(symbol, freq=freq) + bitstamp.init(int(limit)) + bitstamp.toCharts() + + return func app = FastAPI() @@ -3261,6 +3269,11 @@ async def websocket_endpoint(websocket: WebSocket): data = await websocket.receive_text() message = json.loads(data) if message["type"] == "ready": + exchange = message["exchange"] + symbol = message["symbol"] + freq = message["freq"] + limit = message["limit"] + print(message) if Observer.thread is not None: tmp = Observer.thread Observer.thread = None @@ -3277,7 +3290,10 @@ async def websocket_endpoint(websocket: WebSocket): ZhongShu.DUAN_OBJS = [] tmp.join(1) time.sleep(1) - Observer.thread = Thread(target=main_bitstamp) # 使用线程来运行main函数 + + Observer.thread = Thread( + target=main_bitstamp(symbol=symbol, freq=freq, limit=limit) + ) # 使用线程来运行main函数 Observer.thread.start() except WebSocketDisconnect: manager.disconnect(websocket) @@ -3289,13 +3305,38 @@ def static_czsc(): return HTMLResponse(f.read()) -@app.get("/{nol}/{exchange}/{symbol}", response_class=HTMLResponse) -async def home(request: Request, nol: str, exchange: str, symbol: str): - print(dir(request)) +@app.get("/") +async def main_page( + request: Request, + nol: str = "network", + exchange: str = "bitstamp", + symbol: str = "btcusd", + step: int = 300, + limit: int = 500, +): + resolutions = { + 60: "1", + 180: "3", + 300: "5", + 900: "15", + 1800: "30", + 3600: "1H", + 7200: "2H", + 14400: "4H", + 21600: "6H", + 43200: "12H", + 86400: "1D", + 259200: "3D", + } + if resolutions.get(step) is None: + return resolutions + print(request.base_url) + Observer.CAN = True charting_library = str( request.url_for("charting_library", path="/charting_library.standalone.js") ) + print(charting_library) return HTMLResponse( """ @@ -3306,11 +3347,24 @@ async def home(request: Request, nol: str, exchange: str, symbol: str): @@ -3736,16 +3716,14 @@ async def home(request: Request, nol: str, exchange: str, symbol: str): """.replace("$charting_library$", charting_library) + .replace("$exchange$", exchange) + .replace("$symbol$", symbol) + .replace("$interval$", resolutions.get(step)) + .replace("$limit$", str(limit)) + .replace("$step$", str(step)) ) -@app.get("/") -async def main_page(request: Request): - Observer.CAN = True - # Observer.loop = asyncio.get_event_loop() - return await home(request, "local", "oke", "btcusd") - - async def handle_message(message: dict): if message["type"] == "realtime": await manager.send_message(json.dumps(message))