Spaces:
Running
Running
back to stage
Browse files
app.py
CHANGED
|
@@ -179,46 +179,56 @@ def _band(lo, hi):
|
|
| 179 |
return f"โค{hi*100:.0f}%" if lo <= -1 else f"({lo*100:.0f},{hi*100:.0f}]%"
|
| 180 |
|
| 181 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
def check_one(code):
|
| 183 |
code = code.zfill(6)
|
| 184 |
market = market_of(code)
|
| 185 |
r = BT.load_one(code, market)
|
| 186 |
if r is None:
|
| 187 |
return {"code": code, "market": market, "ok": False, "msg": "๋ฐ์ดํฐ ์์"}
|
| 188 |
-
stock = r["stock"]; index = r["index"]
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
sells,
|
| 192 |
-
stock, index, r["dates"], r["start_pos"],
|
| 193 |
-
ma60=r.get("ma60"), ma240=r.get("ma240"),
|
| 194 |
-
low=r.get("low"), bbl=r.get("bbl"),
|
| 195 |
-
ma240_est=r.get("ma240_est"), ma120=r.get("ma120"))
|
| 196 |
last_i = len(stock) - 1
|
| 197 |
recent = [s for s in sells if s["i"] >= last_i - ALERT_DAYS]
|
| 198 |
-
|
| 199 |
-
# ํ์ฌ ๋จ๊ณ status: steps ๋ง์ง๋ง์ '[ํ์ฌ] ...' (์์ผ๋ฉด ๊ด๋ง)
|
| 200 |
-
cur = None
|
| 201 |
-
for stp in steps:
|
| 202 |
-
if stp["name"].startswith("[ํ์ฌ]"):
|
| 203 |
-
cur = stp
|
| 204 |
return {
|
| 205 |
"code": code, "market": market, "ok": True,
|
| 206 |
"price_now": float(stock[last_i]),
|
| 207 |
-
"last_date": r["dates"][last_i],
|
| 208 |
"recent": recent,
|
| 209 |
"last_sell": sells[-1] if sells else None,
|
| 210 |
-
"
|
| 211 |
}
|
| 212 |
|
| 213 |
|
| 214 |
def _status_line(res):
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
if cur is None:
|
| 218 |
return "๊ด๋ง (์ ํธ ๋๊ธฐ)"
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
|
|
|
|
|
|
| 222 |
|
| 223 |
|
| 224 |
def run_monitor(text):
|
|
@@ -227,18 +237,10 @@ def run_monitor(text):
|
|
| 227 |
if not raw:
|
| 228 |
return "์ข
๋ชฉ์ฝ๋ ๋๋ ์ข
๋ชฉ๋ช
์ ์
๋ ฅํด์ค (์: 277810 ๋ ์ธ๋ณด์ฐ๋ก๋ณดํฑ์ค)"
|
| 229 |
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
f"๊ธฐ์ค: RS์ ์ฝํ(๋ฌด์ฅ) โ {rc} ํ์ธ ์ฆ์๋งค๋"
|
| 235 |
-
f"{' + ' + BT.CONFIRM_NEEDS_FLAT if BT.RS_CONFIRM in ('MA60','MA120') else ''}\n\n---\n")
|
| 236 |
-
else:
|
| 237 |
-
head = (f"**์ ๋๋งค๋ ์ตํ๋ณด๋ฃจ** (STAGE) ยท ์ต๊ทผ {ALERT_DAYS}๊ฑฐ๋์ผ ๊ธฐ์ค\n\n"
|
| 238 |
-
f"๊ธฐ์ค: ๋ํํ{BT.RUN_MIN_DAYS}์ผ AND A-4ํํ "
|
| 239 |
-
f"60{_band(BT.FLAT_MIN_60, BT.FLAT_MAX_60)} {BT.FLAT_COMBINE} "
|
| 240 |
-
f"120{_band(BT.FLAT_MIN_120, BT.FLAT_MAX_120)} {BT.FLAT_COMBINE} "
|
| 241 |
-
f"240{_band(BT.FLAT_MIN_240, BT.FLAT_MAX_240)}\n\n---\n")
|
| 242 |
out = [head]
|
| 243 |
alerts = []
|
| 244 |
asof = None
|
|
|
|
| 179 |
return f"โค{hi*100:.0f}%" if lo <= -1 else f"({lo*100:.0f},{hi*100:.0f}]%"
|
| 180 |
|
| 181 |
|
| 182 |
+
def _real_sells(stock, low, ma240, sells):
|
| 183 |
+
"""๋ฐฑํ
์คํฐ main()๊ณผ ๋์ผํ 4์ข
ํํฐ๋ก '์ง์ง ๋งค๋'๋ง (240ํฐ์น/240์์/๋๋ฌด์ผ์ฐ/์ถ์ธ์ ์ง SKIP)."""
|
| 184 |
+
out = []
|
| 185 |
+
for s in sells:
|
| 186 |
+
i = s["i"]; price = s["price"]
|
| 187 |
+
cat, days = BT.classify_240(stock, low, ma240, i, price)
|
| 188 |
+
if getattr(BT, "SKIP_IF_NO_240", False) and cat == "UNKNOWN":
|
| 189 |
+
continue
|
| 190 |
+
if getattr(BT, "SKIP_IF_BELOW_240", False) and cat == "ALREADY_DOWN":
|
| 191 |
+
continue
|
| 192 |
+
med = getattr(BT, "MAX_EARLY_DAYS", None)
|
| 193 |
+
if med is not None and cat == "EARLY" and days is not None and days > med:
|
| 194 |
+
continue
|
| 195 |
+
if getattr(BT, "SKIP_IF_STILL_UP", False) and cat == "STILL_UP":
|
| 196 |
+
continue
|
| 197 |
+
out.append(s)
|
| 198 |
+
return out
|
| 199 |
+
|
| 200 |
+
|
| 201 |
def check_one(code):
|
| 202 |
code = code.zfill(6)
|
| 203 |
market = market_of(code)
|
| 204 |
r = BT.load_one(code, market)
|
| 205 |
if r is None:
|
| 206 |
return {"code": code, "market": market, "ok": False, "msg": "๋ฐ์ดํฐ ์์"}
|
| 207 |
+
stock = r["stock"]; index = r["index"]; low = r["low"]; ma240 = r["ma240"]
|
| 208 |
+
sells, jumps, state = BT.find_confirmed_sells(
|
| 209 |
+
stock, index, r["dates"], r["start_pos"], return_state=True)
|
| 210 |
+
sells = _real_sells(stock, low, ma240, sells) # 4์ข
ํํฐ
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
last_i = len(stock) - 1
|
| 212 |
recent = [s for s in sells if s["i"] >= last_i - ALERT_DAYS]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
return {
|
| 214 |
"code": code, "market": market, "ok": True,
|
| 215 |
"price_now": float(stock[last_i]),
|
| 216 |
+
"last_date": r["dates"][last_i],
|
| 217 |
"recent": recent,
|
| 218 |
"last_sell": sells[-1] if sells else None,
|
| 219 |
+
"state": state,
|
| 220 |
}
|
| 221 |
|
| 222 |
|
| 223 |
def _status_line(res):
|
| 224 |
+
st = res.get("state")
|
| 225 |
+
if not st:
|
|
|
|
| 226 |
return "๊ด๋ง (์ ํธ ๋๊ธฐ)"
|
| 227 |
+
nm = {"์์": "๊ด๋ง", "flagON": "flag ON (๋๊ธฐ)", "1์ฐจ": "1์ฐจ (์งํ์ค)",
|
| 228 |
+
"2์ฐจflagON": "2์ฐจ flag ON (์ ๋๋งค๋ ์๋ฐ!)", "2์ฐจ๋งค๋": "์ ๋๋งค๋ ๋ฐ๋"}.get(
|
| 229 |
+
st["stage_name"], st["stage_name"])
|
| 230 |
+
tail = " ยท ๋งค๋ํ ๋๊ธฐ" if st.get("sold") else ""
|
| 231 |
+
return f"{nm} ยท ์ด๊ฒฉ {st['div']*100:.1f}%{tail}"
|
| 232 |
|
| 233 |
|
| 234 |
def run_monitor(text):
|
|
|
|
| 237 |
if not raw:
|
| 238 |
return "์ข
๋ชฉ์ฝ๋ ๋๋ ์ข
๋ชฉ๋ช
์ ์
๋ ฅํด์ค (์: 277810 ๋ ์ธ๋ณด์ฐ๋ก๋ณดํฑ์ค)"
|
| 239 |
|
| 240 |
+
head = (f"**์ ๋๋งค๋ ์ตํ๋ณด๋ฃจ** ยท ์ต๊ทผ {ALERT_DAYS}๊ฑฐ๋์ผ ๊ธฐ์ค\n\n"
|
| 241 |
+
f"๊ธฐ์ค: ์ด๊ฒฉ {BT.DIV_THRESHOLD*100:.0f}% ๋จ๊ณ๋์ ({BT.MIN_DEEPEN*100:.1f}%p+) "
|
| 242 |
+
f"+ ํ๋ฃจ๊ธ๋ณ {BT.DAILY_JUMP*100:.0f}%p ์ ํ. "
|
| 243 |
+
f"ํํฐ: 240ํฐ์นยท240์์ยทํ๋งค๋ ์ ์ธ\n\n---\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
out = [head]
|
| 245 |
alerts = []
|
| 246 |
asof = None
|