glorifiedjx commited on
Commit
eb0aa8a
ยท
verified ยท
1 Parent(s): 8875a0d

back to stage

Browse files
Files changed (1) hide show
  1. app.py +36 -34
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
- # ๋ฐฑํ…Œ์Šคํ„ฐ์˜ ENGINE ์„ค์ • ๊ทธ๋Œ€๋กœ (RS_A4 / STAGE)
190
- _engine = BT.find_rs_a4_sells if getattr(BT, "ENGINE", "STAGE") == "RS_A4" else BT.find_confirmed_sells
191
- sells, jumps, steps = _engine(
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
- "cur": cur,
211
  }
212
 
213
 
214
  def _status_line(res):
215
- """ํ˜„์žฌ ๋‹จ๊ณ„๋ฅผ ์งง๊ฒŒ: ๊ด€๋ง / flagON ๋Œ€๊ธฐ / 1์ฐจ / 2์ฐจflagON ๋Œ€๊ธฐ + ์ด๊ฒฉ."""
216
- cur = res["cur"]
217
- if cur is None:
218
  return "๊ด€๋ง (์‹ ํ˜ธ ๋Œ€๊ธฐ)"
219
- name = cur["name"].replace("[ํ˜„์žฌ] ", "")
220
- note = cur.get("note", "")
221
- return f"{name} ยท ์ด๊ฒฉ {cur['div']*100:.1f}%" + (f" ยท {note}" if note else "")
 
 
222
 
223
 
224
  def run_monitor(text):
@@ -227,18 +237,10 @@ def run_monitor(text):
227
  if not raw:
228
  return "์ข…๋ชฉ์ฝ”๋“œ ๋˜๋Š” ์ข…๋ชฉ๋ช…์„ ์ž…๋ ฅํ•ด์ค˜ (์˜ˆ: 277810 ๋ ˆ์ธ๋ณด์šฐ๋กœ๋ณดํ‹ฑ์Šค)"
229
 
230
- if getattr(BT, "ENGINE", "STAGE") == "RS_A4":
231
- rc = {"A4": "A-4ํ‰ํ‰", "MA60": "์ข…๊ฐ€<60์„ ", "MA120": "์ข…๊ฐ€<120์„ ",
232
- "NONE": "RS๋‹จ๋…"}.get(BT.RS_CONFIRM, BT.RS_CONFIRM)
233
- head = (f"**์ „๋Ÿ‰๋งค๋„ ์ตœํ›„๋ณด๋ฃจ** (RS_A4) ยท ์ตœ๊ทผ {ALERT_DAYS}๊ฑฐ๋ž˜์ผ ๊ธฐ์ค€\n\n"
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