Spaces:
Running
Running
realtime data plz
Browse files- confirm_sell_backtest.py +111 -12
confirm_sell_backtest.py
CHANGED
|
@@ -18,7 +18,9 @@ import sys, ssl
|
|
| 18 |
import pandas as pd
|
| 19 |
import numpy as np
|
| 20 |
import FinanceDataReader as fdr
|
| 21 |
-
from datetime import datetime, timedelta
|
|
|
|
|
|
|
| 22 |
|
| 23 |
ssl._create_default_https_context = ssl._create_unverified_context
|
| 24 |
if sys.platform == 'win32':
|
|
@@ -53,6 +55,17 @@ DAILY_JUMP = 0.10 # ํ๋ฃจ๋ง์ ์ด๊ฒฉ์ด ์ ์ผๆฏ ์ด๋งํผ(%p)+ ๊ธ
|
|
| 53 |
# 3 = ๊ธฐ์กด(flagโ1์ฐจโ2์ฐจflagโ2์ฐจ๋งค๋, ๊น์ด์ง 3๋ฒ). ์ค์ด๋ฉด ๋ ์ผ์ฐ ์ธ๋ฆฌ์ง๋ง ๋ ์์ฃผ ์ธ๋ฆผ.
|
| 54 |
# 2 = flagโ1์ฐจโ๋งค๋ (๊น์ด์ง 2๋ฒ) / 1 = flagโ๋งค๋ (๊น์ด์ง 1๋ฒ, ๊ฐ์ฅ ์ผ์ฐ/๊ฐ์ฅ ์์ฃผ)
|
| 55 |
CONFIRM_STAGES = 3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
PEAK_WINDOW = 252 # ๊ณ ์ ๊ธฐ์ค = ์ต๊ทผ N๊ฑฐ๋์ผ(252=1๋
) ๋ด ์ต๊ณ ์ (์ค๋๋ ๊ณ ์ ์ ์ ๋ฌถ์)
|
| 57 |
# CONFIRM_WINDOW ์ ๊ฑฐ๋จ: 1์ฐจ->2์ฐจ ์ฌ์ด ์ผ์ ์ ํ ์์ (๋ฉฐ์น ์ด ๊ฑธ๋ฆฌ๋ ์ฐ์ ํ์ฉ)
|
| 58 |
|
|
@@ -93,15 +106,20 @@ TREND_MIN_DAYS = 60 # '240์ฌ': ์ต๊ทผ N๊ฑฐ๋์ผ ์ฐ์ 240์ ์
|
|
| 93 |
TREND_MIN_GAP = 0.05 # '240์ฌ': ๋งค๋์ผ ์ข
๊ฐ๊ฐ 240์ +5% ์ด์
|
| 94 |
|
| 95 |
ANALYZE_FROM = '2020-01-01' # ์ฑ์ (๋งค๋์ง๊ณ) ์์์ผ โ ์ด๊ฑด '์ธ์ ๋ถํฐ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ์ง'์ผ ๋ฟ
|
| 96 |
-
ANALYZE_TO = None # None=์ค๋
|
| 97 |
|
| 98 |
# โ
๋ฐ์ดํฐ ๋ก๋ฉ์ ANALYZE_FROM ๊ณผ ๋ฌด๊ดํ๊ฒ 'ํญ์ ์ถฉ๋ถํ ๊ณผ๊ฑฐ๋ถํฐ' ๋ถ๋ฌ์จ๋ค.
|
| 99 |
# (๊ณ ์ /์ด๊ฒฉ์ ์ ์ฒด ๊ฐ๊ฒฉ์ด๋ ฅ์ผ๋ก ๊ณ์ฐ๋ผ์ผ ํ๋ฏ๋ก. ANALYZE_FROM ๋ง ๋ฆ์ถ๋ฉด ๊ณ ์ ์
|
| 100 |
# ์๋ชป ์ก์ ๋งค๋์์ ์ด ๋ฌ๋ผ์ง๋ ๋ฒ๊ทธ๊ฐ ์๊น -> ๊ทธ๋์ DATA_START ๋ ๊ณ ์ .)
|
| 101 |
DATA_START = '2018-01-01' # ๊ณ ์ . ๋ ๊ณผ๊ฑฐ๋ฅผ ๋ณด๋ ค๋ฉด ์ด ๋ ์ง๋ง ์๋น๊ธฐ๋ฉด ๋จ.
|
| 102 |
|
| 103 |
-
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
|
| 107 |
# =============================================
|
|
@@ -348,6 +366,82 @@ def find_confirmed_sells(stock, index, dates, start_pos, ma60=None, ma240=None,
|
|
| 348 |
return sells, jumps, steps
|
| 349 |
|
| 350 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 351 |
def in_240_run(stock, ma240, i):
|
| 352 |
if i - TREND_MIN_DAYS + 1 < 0:
|
| 353 |
return False
|
|
@@ -384,7 +478,7 @@ def protected(stock, i, price):
|
|
| 384 |
|
| 385 |
def load_one(ticker, market):
|
| 386 |
try:
|
| 387 |
-
sdf = fdr.DataReader(ticker, DATA_START,
|
| 388 |
except Exception:
|
| 389 |
return None
|
| 390 |
if not isinstance(sdf, pd.DataFrame) or 'Close' not in sdf.columns or len(sdf) == 0:
|
|
@@ -393,7 +487,7 @@ def load_one(ticker, market):
|
|
| 393 |
idf = None
|
| 394 |
for c in (idx_code, '^' + idx_code):
|
| 395 |
try:
|
| 396 |
-
t = fdr.DataReader(c, DATA_START,
|
| 397 |
if isinstance(t, pd.DataFrame) and 'Close' in t.columns and len(t) > 0:
|
| 398 |
idf = t; break
|
| 399 |
except Exception:
|
|
@@ -442,7 +536,7 @@ def pct(a, b):
|
|
| 442 |
|
| 443 |
def main():
|
| 444 |
print("=" * 88)
|
| 445 |
-
print(f"์ด๊ฒฉ ์ฌํ์ธ ๋ฐฑํ
์คํธ [lower-low] | {ANALYZE_FROM} ~ {
|
| 446 |
f"{sum(len(v) for v in TICKERS.values())}๊ฐ")
|
| 447 |
if USE_TREND and USE_TREND_FLAT:
|
| 448 |
cb = FLAT_COMBINE
|
|
@@ -454,10 +548,14 @@ def main():
|
|
| 454 |
f"240{_b(FLAT_MIN_240,FLAT_MAX_240)}]")
|
| 455 |
else:
|
| 456 |
tf_s = "์ถ์ธํํฐ=OFF"
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 461 |
print(f"์ฑ์ : ๊ด์ฐฐ {LOOK_AHEAD}์ผ | E์จ=240์ดํ(์กฐ๊ธฐ๊ฒฝ๋ณด) | P์จ=๋งค๋๊ฐ๋๋น {PROTECT_DROP*100:.0f}% ์ถ๊ฐํ๋ฝ ํํผ")
|
| 462 |
print("=" * 88)
|
| 463 |
|
|
@@ -483,7 +581,8 @@ def main():
|
|
| 483 |
sl60 = _smoothed_slope(ma60, _sd, _sm) if ma60 is not None else None
|
| 484 |
sl120 = _smoothed_slope(ma120, _sd, _sm) if ma120 is not None else None
|
| 485 |
sl240 = _smoothed_slope(ma240, _sd, _sm) if ma240 is not None else None
|
| 486 |
-
|
|
|
|
| 487 |
ma60=ma60, ma240=ma240,
|
| 488 |
low=r.get('low'), bbl=r.get('bbl'),
|
| 489 |
ma240_est=r.get('ma240_est'), ma120=ma120)
|
|
|
|
| 18 |
import pandas as pd
|
| 19 |
import numpy as np
|
| 20 |
import FinanceDataReader as fdr
|
| 21 |
+
from datetime import datetime, timedelta, timezone
|
| 22 |
+
|
| 23 |
+
_KST = timezone(timedelta(hours=9))
|
| 24 |
|
| 25 |
ssl._create_default_https_context = ssl._create_unverified_context
|
| 26 |
if sys.platform == 'win32':
|
|
|
|
| 55 |
# 3 = ๊ธฐ์กด(flagโ1์ฐจโ2์ฐจflagโ2์ฐจ๋งค๋, ๊น์ด์ง 3๋ฒ). ์ค์ด๋ฉด ๋ ์ผ์ฐ ์ธ๋ฆฌ์ง๋ง ๋ ์์ฃผ ์ธ๋ฆผ.
|
| 56 |
# 2 = flagโ1์ฐจโ๋งค๋ (๊น์ด์ง 2๋ฒ) / 1 = flagโ๋งค๋ (๊น์ด์ง 1๋ฒ, ๊ฐ์ฅ ์ผ์ฐ/๊ฐ์ฅ ์์ฃผ)
|
| 57 |
CONFIRM_STAGES = 3
|
| 58 |
+
|
| 59 |
+
# =============================================
|
| 60 |
+
# ๋งค๋ ์์ง ์ ํ
|
| 61 |
+
# 'STAGE' = ๊ธฐ์กด: ์ด๊ฒฉ flagโ1์ฐจโ2์ฐจflagโ2์ฐจ (๋จ๊ณ๋์ ). ํ์๋ ์ ์ง๋ง ํํ(๋๋ฆผ).
|
| 62 |
+
# 'RS_A4' = ์๊ฑฐ: RS์ ์ด ์์ฅ๋ณด๋ค ์ฝํด์ง๋ฉด(๋ฐ๋ํฌ๋ก์ค) '๋ฌด์ฅ' -> A-4(์ถ์ธ์ฃฝ์) ํ์ธ๋๋
|
| 63 |
+
# ์ฆ์ ๋งค๋. ๋จ๊ณ ์ ๊ฑฐ์นจ -> ๋ ์ผ์ฐ. RS๋ ์ ํ์งํ๋ผ 240 ๊นจ์ง๊ธฐ ์ ์ ๊ฒฝ๊ณ .
|
| 64 |
+
# =============================================
|
| 65 |
+
ENGINE = 'STAGE' # 'STAGE' / 'RS_A4'
|
| 66 |
+
RS_MA_PERIOD = 20 # RS์ (์ข
๋ชฉ/์ง์)์ ์ด๋ํ๊ท ๊ธฐ๊ฐ. RS < ์ด ํ๊ท ์ด๋ฉด ๋ฐ๋ํฌ๋ก์ค(์ฝํ)
|
| 67 |
+
RS_PERSIST = 3 # RS๊ฐ ์ด๋งํผ(๊ฑฐ๋์ผ) ์ฐ์ ์ฝํด์ผ '๋ฌด์ฅ' (ํ๋ฃจ ๋
ธ์ด์ฆ ๋ฐฉ์ง)
|
| 68 |
+
RS_CONFIRM = 'A4' # 'A4'=A-4 ์ถ์ธํํฐ ํ์ธ๋ผ์ผ ๋งค๋ / 'NONE'=RS ๋ฐ๋ํฌ๋ก์ค๋ง์ผ๋ก ๋งค๋
|
| 69 |
PEAK_WINDOW = 252 # ๊ณ ์ ๊ธฐ์ค = ์ต๊ทผ N๊ฑฐ๋์ผ(252=1๋
) ๋ด ์ต๊ณ ์ (์ค๋๋ ๊ณ ์ ์ ์ ๋ฌถ์)
|
| 70 |
# CONFIRM_WINDOW ์ ๊ฑฐ๋จ: 1์ฐจ->2์ฐจ ์ฌ์ด ์ผ์ ์ ํ ์์ (๋ฉฐ์น ์ด ๊ฑธ๋ฆฌ๋ ์ฐ์ ํ์ฉ)
|
| 71 |
|
|
|
|
| 106 |
TREND_MIN_GAP = 0.05 # '240์ฌ': ๋งค๋์ผ ์ข
๊ฐ๊ฐ 240์ +5% ์ด์
|
| 107 |
|
| 108 |
ANALYZE_FROM = '2020-01-01' # ์ฑ์ (๋งค๋์ง๊ณ) ์์์ผ โ ์ด๊ฑด '์ธ์ ๋ถํฐ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ์ง'์ผ ๋ฟ
|
| 109 |
+
ANALYZE_TO = None # None=์ค๋(๋งค๋ฒ ํธ์ถ์์ KST ๊ธฐ์ค). ํน์ ์ผ ๊ณ ์ ํ๋ ค๋ฉด 'YYYY-MM-DD'.
|
| 110 |
|
| 111 |
# โ
๋ฐ์ดํฐ ๋ก๋ฉ์ ANALYZE_FROM ๊ณผ ๋ฌด๊ดํ๊ฒ 'ํญ์ ์ถฉ๋ถํ ๊ณผ๊ฑฐ๋ถํฐ' ๋ถ๋ฌ์จ๋ค.
|
| 112 |
# (๊ณ ์ /์ด๊ฒฉ์ ์ ์ฒด ๊ฐ๊ฒฉ์ด๋ ฅ์ผ๋ก ๊ณ์ฐ๋ผ์ผ ํ๋ฏ๋ก. ANALYZE_FROM ๋ง ๋ฆ์ถ๋ฉด ๊ณ ์ ์
|
| 113 |
# ์๋ชป ์ก์ ๋งค๋์์ ์ด ๋ฌ๋ผ์ง๋ ๋ฒ๊ทธ๊ฐ ์๊น -> ๊ทธ๋์ DATA_START ๋ ๊ณ ์ .)
|
| 114 |
DATA_START = '2018-01-01' # ๊ณ ์ . ๋ ๊ณผ๊ฑฐ๋ฅผ ๋ณด๋ ค๋ฉด ์ด ๋ ์ง๋ง ์๋น๊ธฐ๋ฉด ๋จ.
|
| 115 |
|
| 116 |
+
|
| 117 |
+
def _end_date():
|
| 118 |
+
"""๋ฐ์ดํฐ ๋๋ ์ง. ANALYZE_TO ๊ฐ None ์ด๋ฉด '์ง๊ธ KST ์ค๋'์ ๋งค๋ฒ ์๋ก ๊ณ์ฐ
|
| 119 |
+
(์ฑ์ด ๋ฉฐ์น ์งธ ์ผ์ ธ ์์ด๋ ํญ์ ์ต์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋๋ก)."""
|
| 120 |
+
if ANALYZE_TO:
|
| 121 |
+
return ANALYZE_TO
|
| 122 |
+
return datetime.now(_KST).strftime('%Y-%m-%d')
|
| 123 |
|
| 124 |
|
| 125 |
# =============================================
|
|
|
|
| 366 |
return sells, jumps, steps
|
| 367 |
|
| 368 |
|
| 369 |
+
def find_rs_a4_sells(stock, index, dates, start_pos, ma60=None, ma240=None,
|
| 370 |
+
low=None, bbl=None, ma240_est=None, ma120=None):
|
| 371 |
+
"""RS_A4 ์์ง: RS์ (์ข
๋ชฉ/์ง์)์ด ์์ฅ๋ณด๋ค ์ฝํด์ง๋ฉด(RS<RS_MA, RS_PERSIST์ผ ์ง์) '๋ฌด์ฅ',
|
| 372 |
+
๊ทธ ์ํ์์ A-4 ์ถ์ธํํฐ๊ฐ ํ์ธ๋๋ ์ฆ์ ์ ๋๋งค๋. ๋จ๊ณ ์ ๊ฑฐ์นจ -> ์ผ์ฐ ์ด๋ค.
|
| 373 |
+
๋ฐํ์ STAGE ์์ง๊ณผ ๋์ผ ํ์ (sells, jumps, steps)."""
|
| 374 |
+
n = len(stock)
|
| 375 |
+
twpk, twip = _trailing_peaks(stock, index, PEAK_WINDOW)
|
| 376 |
+
|
| 377 |
+
flat_slopes = None
|
| 378 |
+
if USE_TREND_FLAT:
|
| 379 |
+
flat_slopes = {}
|
| 380 |
+
for ln, arr in ((60, ma60), (120, ma120), (240, ma240)):
|
| 381 |
+
if arr is not None:
|
| 382 |
+
flat_slopes[ln] = _smoothed_slope(arr, FLAT_SLOPE_DAYS, FLAT_SMOOTH)
|
| 383 |
+
|
| 384 |
+
# RS์ ๊ณผ ๊ทธ ์ด๋ํ๊ท
|
| 385 |
+
rs = np.array([stock[t] / index[t] if index[t] else np.nan for t in range(n)])
|
| 386 |
+
rs_ma = pd.Series(rs).rolling(RS_MA_PERIOD).mean().values
|
| 387 |
+
rs_weak = np.array([(not np.isnan(rs_ma[t])) and rs[t] < rs_ma[t] for t in range(n)])
|
| 388 |
+
|
| 389 |
+
sells = []; jumps = []; steps = []
|
| 390 |
+
def _step(t, name, div, note=''):
|
| 391 |
+
if t >= start_pos:
|
| 392 |
+
steps.append({'date': dates[t], 'name': name, 'div': div, 'note': note})
|
| 393 |
+
|
| 394 |
+
def _gate(t):
|
| 395 |
+
if ma240 is None:
|
| 396 |
+
return True, ''
|
| 397 |
+
return trend_ok(t, stock, ma240, ma60, ma120, flat_slopes)
|
| 398 |
+
|
| 399 |
+
armed = False; armed_date = None; sold = False; weak_run = 0
|
| 400 |
+
for t in range(n):
|
| 401 |
+
div = (stock[t] / twpk[t] - 1) - ((index[t] / twip[t] - 1) if twip[t] else 0.0)
|
| 402 |
+
|
| 403 |
+
if rs_weak[t]:
|
| 404 |
+
weak_run += 1
|
| 405 |
+
else:
|
| 406 |
+
# RS๊ฐ ๋ค์ ์์ฅ๋ณด๋ค ๊ฐํด์ง -> ๋ฌด์ฅ ํด์ / ๋งค๋์ํ ๋ฆฌ์
|
| 407 |
+
if armed and t >= start_pos:
|
| 408 |
+
_step(t, '๋ฌด์ฅ ํด์ (RS ํ๋ณต)', div)
|
| 409 |
+
armed = False; weak_run = 0; sold = False
|
| 410 |
+
continue
|
| 411 |
+
|
| 412 |
+
# RS_PERSIST์ผ ์ฐ์ ์ฝํ๋ฉด ๋ฌด์ฅ
|
| 413 |
+
if not armed and weak_run >= RS_PERSIST:
|
| 414 |
+
armed = True; armed_date = dates[t]
|
| 415 |
+
rsd = (rs[t] / rs_ma[t] - 1) * 100
|
| 416 |
+
_step(t, '๋ฌด์ฅ(RS ๋ฐ๋ํฌ๋ก์ค)', div, f'RS {rsd:.1f}% < MA{RS_MA_PERIOD}')
|
| 417 |
+
|
| 418 |
+
if armed and not sold:
|
| 419 |
+
ok, why = (_gate(t) if RS_CONFIRM == 'A4' else (True, 'RS๋จ๋
'))
|
| 420 |
+
if ok:
|
| 421 |
+
if t >= start_pos:
|
| 422 |
+
est = bool(ma240_est[t]) if ma240_est is not None else False
|
| 423 |
+
sells.append({'i': t, 'price': float(stock[t]), 'div': div,
|
| 424 |
+
'date': dates[t], 'trend': why,
|
| 425 |
+
'via': f'RS๋ฌด์ฅ({armed_date})', 'est': est})
|
| 426 |
+
_step(t, '์ ๋๋งค๋ โ
๋ฐ๋', div,
|
| 427 |
+
f'RS๋ฌด์ฅ ํ A-4ํ์ธ' if RS_CONFIRM == 'A4' else 'RS ๋ฐ๋ํฌ๋ก์ค')
|
| 428 |
+
sold = True
|
| 429 |
+
else:
|
| 430 |
+
pass # ๋ฌด์ฅ๋์ง๋ง A-4 ์์ง -> ๋๊ธฐ (๋ค์๋ ๋ ํ์ธ)
|
| 431 |
+
|
| 432 |
+
# ํ์ฌ ์ํ
|
| 433 |
+
last = n - 1
|
| 434 |
+
if not sold:
|
| 435 |
+
div = (stock[last] / twpk[last] - 1) - ((index[last] / twip[last] - 1) if twip[last] else 0.0)
|
| 436 |
+
if armed:
|
| 437 |
+
ok, why = (_gate(last) if RS_CONFIRM == 'A4' else (True, ''))
|
| 438 |
+
note = ('A-4 ํ์ธ ๋๊ธฐ์ค (' + why + ')') if RS_CONFIRM == 'A4' else 'RS๋จ๋
'
|
| 439 |
+
_step(last, '[ํ์ฌ] ๋ฌด์ฅ๋จ(๋งค๋ ๋๊ธฐ)', div, note)
|
| 440 |
+
else:
|
| 441 |
+
_step(last, '[ํ์ฌ] ๊ด๋ง (RS ์์ง ์์ฅ๋ณด๋ค ์ ์ฝํจ)', div, '')
|
| 442 |
+
return sells, jumps, steps
|
| 443 |
+
|
| 444 |
+
|
| 445 |
def in_240_run(stock, ma240, i):
|
| 446 |
if i - TREND_MIN_DAYS + 1 < 0:
|
| 447 |
return False
|
|
|
|
| 478 |
|
| 479 |
def load_one(ticker, market):
|
| 480 |
try:
|
| 481 |
+
sdf = fdr.DataReader(ticker, DATA_START, _end_date())
|
| 482 |
except Exception:
|
| 483 |
return None
|
| 484 |
if not isinstance(sdf, pd.DataFrame) or 'Close' not in sdf.columns or len(sdf) == 0:
|
|
|
|
| 487 |
idf = None
|
| 488 |
for c in (idx_code, '^' + idx_code):
|
| 489 |
try:
|
| 490 |
+
t = fdr.DataReader(c, DATA_START, _end_date())
|
| 491 |
if isinstance(t, pd.DataFrame) and 'Close' in t.columns and len(t) > 0:
|
| 492 |
idf = t; break
|
| 493 |
except Exception:
|
|
|
|
| 536 |
|
| 537 |
def main():
|
| 538 |
print("=" * 88)
|
| 539 |
+
print(f"์ด๊ฒฉ ์ฌํ์ธ ๋ฐฑํ
์คํธ [lower-low] | {ANALYZE_FROM} ~ {_end_date()} | ์ข
๋ชฉ "
|
| 540 |
f"{sum(len(v) for v in TICKERS.values())}๊ฐ")
|
| 541 |
if USE_TREND and USE_TREND_FLAT:
|
| 542 |
cb = FLAT_COMBINE
|
|
|
|
| 548 |
f"240{_b(FLAT_MIN_240,FLAT_MAX_240)}]")
|
| 549 |
else:
|
| 550 |
tf_s = "์ถ์ธํํฐ=OFF"
|
| 551 |
+
if ENGINE == 'RS_A4':
|
| 552 |
+
rs_confirm = 'A-4ํ์ธ' if RS_CONFIRM == 'A4' else 'RS๋จ๋
'
|
| 553 |
+
print(f"์์ง=RS_A4 | RS์ <MA{RS_MA_PERIOD} {RS_PERSIST}์ผ์ฐ์ ๋ฌด์ฅ -> {rs_confirm} ์ฆ์๋งค๋ | {tf_s}")
|
| 554 |
+
else:
|
| 555 |
+
div_s = f"์ด๊ฒฉ๊ธฐ์ค={DIV_THRESHOLD*100:.0f}%(๊ณ ์ )"
|
| 556 |
+
jmp_s = f"ํ๋ฃจ๊ธ๋ณ({DAILY_JUMP*100:.0f}%p)์ ํ"
|
| 557 |
+
print(f"์์ง=STAGE | ๊ณ ์ =์ต๊ทผ{PEAK_WINDOW}์ผ๋ด์ต๊ณ | {div_s} | ๋จ๊ณ๋์ ({MIN_DEEPEN*100:.1f}%p+, "
|
| 558 |
+
f"๋งค๋๊น์ง {CONFIRM_STAGES+1}๋จ๊ณ) | {jmp_s} | {tf_s}")
|
| 559 |
print(f"์ฑ์ : ๊ด์ฐฐ {LOOK_AHEAD}์ผ | E์จ=240์ดํ(์กฐ๊ธฐ๊ฒฝ๋ณด) | P์จ=๋งค๋๊ฐ๋๋น {PROTECT_DROP*100:.0f}% ์ถ๊ฐํ๋ฝ ํํผ")
|
| 560 |
print("=" * 88)
|
| 561 |
|
|
|
|
| 581 |
sl60 = _smoothed_slope(ma60, _sd, _sm) if ma60 is not None else None
|
| 582 |
sl120 = _smoothed_slope(ma120, _sd, _sm) if ma120 is not None else None
|
| 583 |
sl240 = _smoothed_slope(ma240, _sd, _sm) if ma240 is not None else None
|
| 584 |
+
_engine = find_rs_a4_sells if ENGINE == 'RS_A4' else find_confirmed_sells
|
| 585 |
+
sells, jumps, steps = _engine(stock, index, r['dates'], r['start_pos'],
|
| 586 |
ma60=ma60, ma240=ma240,
|
| 587 |
low=r.get('low'), bbl=r.get('bbl'),
|
| 588 |
ma240_est=r.get('ma240_est'), ma120=ma120)
|