변경 사항 (Changes): 구문 오류(Syntax error) 및 토큰 낭비를 방지하기 위해 에이전트 쉘(Agent shell)과 파이썬 코드 스니펫에 다수의 신규 안전 규칙(Safety rules)을 추가함. 스키마 검증 및 적절한 SQL 포맷팅을 보장하기 위해 임시(Ad-hoc) 데이터베이스 쿼리 작성 가이드라인을 도입함. 코드 수정 후 UI 기능이 정상 작동하는지 확인하기 위해, 백테스트 웹 서비스 재시작 및 브라우저 검증에 대한 새로운 규칙을 구현함. 시스템 전반의 무결성(Integrity)을 유지하기 위해 실전 매매(Live trading), 웹 백테스팅, 파라미터 탐색(Parameter searches) 간의 일관성 검사(Consistency checks) 체계를 확립함. 기대 효과 (Impact): 이러한 개선 사항들은 트레이딩 시스템의 견고성(Robustness)과 신뢰성을 향상시키며, 에러 발생을 최소화하고 다양한 시스템 컴포넌트 간의 원활한 상호작용을 보장함.
2890 lines
190 KiB
HTML
2890 lines
190 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ko" data-bs-theme="dark">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>📈 KIS Quant 백테스트 대시보드</title>
|
||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.4/dist/chart.umd.min.js"></script>
|
||
<link rel="stylesheet" href="{{ url_for('static', filename='css/backtest.css') }}">
|
||
</head>
|
||
<body>
|
||
|
||
<!-- 로딩 오버레이 -->
|
||
<div class="spin-overlay" id="spinner">
|
||
<div class="spinner"></div>
|
||
</div>
|
||
|
||
<nav class="navbar px-4 py-3" style="background:var(--surface); border-bottom:1px solid var(--border)">
|
||
<span class="navbar-brand">📈 KIS Quant Dashboard</span>
|
||
<span class="text-muted" id="lastRefresh" style="font-size:12px"></span>
|
||
</nav>
|
||
|
||
<div class="container-fluid px-4 py-3">
|
||
|
||
<!-- 탭 -->
|
||
<ul class="nav nav-tabs mb-4" id="mainTab">
|
||
<li class="nav-item"><a class="nav-link active" data-tab="actual" href="#">📊 실거래 분석</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="dashboard" href="#">📈 오늘 운영</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="liveconfig" href="#">⚙️ 운영 설정</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="portfolio" href="#">💼 보유·매도</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="backtest" href="#">📉 스캘핑 백테스트</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="tail" href="#">🎣 꼬리잡기 백테스트</a></li>
|
||
<li class="nav-item" style="display:none"><a class="nav-link" data-tab="dbband" href="#">📊 DBBAND</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="breakout" href="#">🚀 돌파매매 백테스트</a></li>
|
||
<li class="nav-item" style="display:none"><a class="nav-link" data-tab="range_break" href="#">📦 박스권돌파</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="momentum" href="#">🌊 모멘텀 백테스트</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="holding" href="#">📈 홀딩 전략</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="updownbox" href="#">📦 박스엔진</a></li>
|
||
<li class="nav-item"><a class="nav-link" data-tab="updow" href="#">📡 영구구독 관리</a></li>
|
||
</ul>
|
||
|
||
<!-- ═══ 오늘 운영 (전략별·합계) ═══════════════════════════════════════════ -->
|
||
<div id="tab-dashboard" style="display:none">
|
||
<div class="card p-3 mb-3">
|
||
<div class="row g-3 align-items-end">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" style="color:var(--muted);font-size:12px">기준일 (KST)</label>
|
||
<input type="date" id="dash_date" class="form-control form-control-sm" style="width:160px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-sm btn-primary" onclick="loadDashboard()">새로고침</button>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-sm btn-outline-secondary" onclick="dashGoActual()">전략별 상세 → 실거래 분석</button>
|
||
</div>
|
||
<div class="col">
|
||
<small id="dash_meta" class="text-muted"></small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row g-3 mb-3" id="dash_cards">
|
||
<div class="col-md-3">
|
||
<div class="card p-3 stat-card">
|
||
<div class="stat-label">당일 거래대금 (합)</div>
|
||
<div class="stat-value" id="dash_card_turnover">—</div>
|
||
<small class="text-muted" id="dash_card_turnover_sub"></small>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<div class="card p-3 stat-card">
|
||
<div class="stat-label">당일 뽀찌 피크 (ON 전략 합)</div>
|
||
<div class="stat-value" id="dash_card_budget">—</div>
|
||
<small class="text-muted" id="dash_card_budget_sub"></small>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<div class="card p-3 stat-card">
|
||
<div class="stat-label">당일 실현손익 (합)</div>
|
||
<div class="stat-value" id="dash_card_pnl">—</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<div class="card p-3 stat-card">
|
||
<div class="stat-label">총수익률 (실현÷운용한도)</div>
|
||
<div class="stat-value" id="dash_card_ret">—</div>
|
||
<small class="text-muted">백테 bot_pct와 동일 분모</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card p-3">
|
||
<h6 class="mb-3">전략별 당일 운영</h6>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-hover mb-0" style="font-size:13px">
|
||
<thead>
|
||
<tr>
|
||
<th>전략</th>
|
||
<th>ON</th>
|
||
<th class="text-end">매수대금</th>
|
||
<th class="text-end">매도대금</th>
|
||
<th class="text-end">거래대금합</th>
|
||
<th class="text-end">청산</th>
|
||
<th class="text-end">보유</th>
|
||
<th class="text-end">실현손익</th>
|
||
<th class="text-end">운용한도</th>
|
||
<th class="text-end">당일뽀찌(피크)</th>
|
||
<th class="text-end">현재투입</th>
|
||
<th class="text-end">사용률</th>
|
||
<th class="text-end">수익률</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="dash_tbody"></tbody>
|
||
<tfoot>
|
||
<tr class="fw-bold" style="border-top:2px solid var(--border)">
|
||
<td>합계 (ON 한도 기준)</td>
|
||
<td>—</td>
|
||
<td class="text-end" id="dash_ft_buy">—</td>
|
||
<td class="text-end" id="dash_ft_sell">—</td>
|
||
<td class="text-end" id="dash_ft_turn">—</td>
|
||
<td class="text-end" id="dash_ft_closed">—</td>
|
||
<td class="text-end" id="dash_ft_open">—</td>
|
||
<td class="text-end" id="dash_ft_pnl">—</td>
|
||
<td class="text-end" id="dash_ft_limit">—</td>
|
||
<td class="text-end" id="dash_ft_used">—</td>
|
||
<td class="text-end" id="dash_ft_now">—</td>
|
||
<td class="text-end" id="dash_ft_usage">—</td>
|
||
<td class="text-end" id="dash_ft_ret">—</td>
|
||
<td></td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
<p class="text-muted mt-2 mb-0" style="font-size:11px" id="dash_notes"></p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ═══ 실거래 분석 탭 ═══════════════════════════════════════════════════ -->
|
||
<div id="tab-actual">
|
||
<div class="card p-3 mb-3">
|
||
<div class="row g-3 align-items-end">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" style="color:var(--muted);font-size:12px">전략 선택 (kis_trader 봇)</label><br>
|
||
<div class="d-flex flex-wrap gap-2 gap-md-3 mt-1 align-items-center" style="max-width:920px">
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="act_strategy" value="SCALP"> 스캘핑 (SCALP)
|
||
</label>
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="act_strategy" value="SHORT" checked> 꼬리잡기 (SHORT)
|
||
</label>
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="act_strategy" value="MOMENTUM"> 모멘텀
|
||
</label>
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="act_strategy" value="UPDOW"> 하락매수 (UPDOW)
|
||
</label>
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="act_strategy" value="BREAKOUT"> 돌파 (BREAKOUT)
|
||
</label>
|
||
<label class="d-flex align-items-center gap-1 mb-0" title="holding_bot.py 장기 홀딩">
|
||
<input type="radio" name="act_strategy" value="HOLDING"> 홀딩 (HOLDING)
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">시작일</label>
|
||
<input type="date" class="form-control" id="act_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">종료일</label>
|
||
<input type="date" class="form-control" id="act_end" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-primary" onclick="loadActual()">🔍 조회</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 요약 카드 (백테 탭과 동일 레이아웃 + 운용한도 대비 수익률) -->
|
||
<div class="row g-3 mb-3" id="act_summary_row">
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 거래</div><div class="stat-val" id="a_total">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">승률</div><div class="stat-val" id="a_winrate">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">순손익(수수료·세금 포함)</div><div class="stat-val" id="a_pnl">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">Profit Factor</div><div class="stat-val" id="a_pf">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">최대 낙폭(MDD)</div><div class="stat-val red" id="a_mdd">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">평균 보유(분)</div><div class="stat-val" id="a_hold">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 수익률(운용한도 대비)</div><div class="stat-val" id="a_bot_pct">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">일평균 수익률</div><div class="stat-val" id="a_daily_avg_pct">-</div>
|
||
</div></div>
|
||
</div>
|
||
<div id="act_filter_note" class="mb-2" style="display:none;font-size:12px;color:var(--muted)"></div>
|
||
<!-- 승/패 바 -->
|
||
<div class="card p-3 mb-3" id="act_winbar_card" style="display:none">
|
||
<div class="d-flex justify-content-between mb-1">
|
||
<span style="color:var(--green)" id="a_win_label">-</span>
|
||
<span style="color:var(--red)" id="a_loss_label">-</span>
|
||
</div>
|
||
<div class="ratio-bar">
|
||
<span class="ratio-fill-g" id="a_ratio_g" style="width:50%"></span>
|
||
<span class="ratio-fill-r" id="a_ratio_r" style="width:50%"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row g-3">
|
||
<!-- 누적 손익 곡선 -->
|
||
<div class="col-12 col-lg-7">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">누적 손익 곡선</div>
|
||
<canvas id="a_equity_chart" height="220"></canvas>
|
||
</div>
|
||
</div>
|
||
<!-- 매도 이유 / 상위종목 -->
|
||
<div class="col-12 col-lg-5">
|
||
<div class="card p-3 mb-3">
|
||
<div class="card-title mb-2">매도 이유 분포</div>
|
||
<canvas id="a_reason_chart" height="180"></canvas>
|
||
</div>
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">종목별 손익 TOP10</div>
|
||
<canvas id="a_code_chart" height="180"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 일별 P&L 바 -->
|
||
<div class="card p-3 mt-3">
|
||
<div class="card-title mb-2">일별 손익</div>
|
||
<canvas id="a_daily_chart" height="150"></canvas>
|
||
</div>
|
||
|
||
<!-- 거래 목록 -->
|
||
<div class="section-title">거래 내역 <span id="act_table_hint" style="font-size:11px;color:var(--muted);font-weight:400"></span></div>
|
||
<div id="act_trade_context" class="mb-2 p-2 rounded" style="font-size:12px;background:var(--bg-secondary, #1c2128);color:var(--muted);display:none"></div>
|
||
<div class="trade-sort-bar mb-2" data-tbody="act_tbody">
|
||
<span class="trade-sort-label">정렬</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn active" data-sort="exit_desc">매도 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="exit_asc">매도 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_desc">매수 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_asc">매수 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_desc">손익↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_asc">손익↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_desc">수익률↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_asc">수익률↓</button>
|
||
</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" id="act_table">
|
||
<thead><tr>
|
||
<th>종목</th><th>매수시각</th><th>매도시각</th>
|
||
<th>매수가</th><th>매도가</th><th>수량</th>
|
||
<th>손익(원)</th><th>수익률%</th><th>누적손익</th><th>누적%</th>
|
||
<th>보유(분)</th><th>체결디버그</th><th>매도사유</th>
|
||
</tr></thead>
|
||
<tbody id="act_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ═══ 운영 설정 (실매 env 실시간 조회·저장) ═════════════════════════════ -->
|
||
<div id="tab-liveconfig" style="display:none">
|
||
<div class="card p-3 mb-3">
|
||
<div class="row g-3 align-items-end">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" style="color:var(--muted);font-size:12px">기준일 (손익·익절 상태)</label>
|
||
<input type="date" id="lc_date" class="form-control form-control-sm" style="width:160px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-sm btn-primary" onclick="lcLoad()">🔄 새로고침</button>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-sm btn-success" onclick="lcSaveAll()">💾 전체 저장</button>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="d-flex align-items-center gap-2 mb-0" style="font-size:12px;color:var(--muted)">
|
||
<input type="checkbox" id="lc_auto_refresh" checked> 30초 자동 갱신
|
||
</label>
|
||
</div>
|
||
<div class="col">
|
||
<small id="lc_meta" class="text-muted"></small>
|
||
</div>
|
||
</div>
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.6;margin-top:8px">
|
||
DB <code>insert_env_snapshot</code> 즉시 저장 → <b>봇 재시작 없이</b> 다음 루프부터 반영.
|
||
마스터 키는 <b>env_config</b>, 전략 키는 <b>config_{전략}</b> 테이블로 자동 분리됩니다.
|
||
</div>
|
||
</div>
|
||
<div id="lc_status_cards" class="row g-3 mb-3"></div>
|
||
<div id="lc_groups"></div>
|
||
<div id="lc_save_result" class="mt-2" style="font-size:13px"></div>
|
||
</div>
|
||
|
||
<!-- ═══ 보유·매도 (DB 동기화) ═══════════════════════════════════════════ -->
|
||
<div id="tab-portfolio" style="display:none">
|
||
<div class="card p-3 mb-3">
|
||
<div style="font-size:12px;color:var(--muted);line-height:1.6">
|
||
<b>실거래 분석</b> = 오늘 <b>매도 완료</b> 내역(trade_history). <b>보유·매도</b> = 지금 <b>잔고</b>(HTS 실시간잔고와 동일).
|
||
<b>실계좌 대조</b>를 눌러야 삼성전자·삼화전자 등 전 종목이 보입니다. DB에 없는 종목은 <span class="badge-loss">미등록</span> — 봇 매도 버튼 없음(HTS 매도 또는 추후 동기화).
|
||
</div>
|
||
<div class="row g-3 align-items-end mt-2">
|
||
<div class="col-12">
|
||
<label class="form-label param-row" style="color:var(--muted);font-size:12px">전략 (실거래 분석 탭과 동일 ID)</label>
|
||
<div class="d-flex flex-wrap gap-2 gap-md-3 mt-1 align-items-center">
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="pf_strategy" value="ALL" checked> 전체
|
||
</label>
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="pf_strategy" value="SHORT"> SHORT
|
||
</label>
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="pf_strategy" value="MOMENTUM"> MOMENTUM
|
||
</label>
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="pf_strategy" value="UPDOW"> UPDOW
|
||
</label>
|
||
<label class="d-flex align-items-center gap-1 mb-0">
|
||
<input type="radio" name="pf_strategy" value="BREAKOUT"> BREAKOUT
|
||
</label>
|
||
</div>
|
||
<div class="col-12" style="font-size:11px;color:var(--muted)">
|
||
HOLDING(홀딩봇) 종목은 이 탭에 표시하지 않습니다 — 홀딩 전략 탭·실거래(HOLDING)에서만 조회.
|
||
</div>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-primary" onclick="pfLoad(false)">🔄 새로고침</button>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-outline-secondary" onclick="pfLoad(true)" title="한투 잔고 API 1회 (수 초)">📡 실계좌 대조</button>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-outline-success" onclick="pfReconcileOrphans()" title="봇이 매수했지만 active_trades 에 누락된 종목을 DB에 복구(매도 아님). 수동매수·보호종목 제외.">🧩 봇고아 DB복구</button>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-outline-danger" onclick="pfSellUntrackedAll()" title="active_trades 에 없는(전략 비어있는) 실계좌 보유분만 시장가 일괄매도. 봇 관리분은 건드리지 않음.">🧹 미등록 전량 매도</button>
|
||
</div>
|
||
<div class="col-auto">
|
||
<span class="text-muted" id="pf_meta" style="font-size:12px"></span>
|
||
</div>
|
||
</div>
|
||
<!-- 실계좌 대조 시 계좌 요약 (입금·예수금·평가) -->
|
||
<div class="row g-2 mt-2" id="pf_account_row" style="display:none">
|
||
<div class="col-6 col-md-3"><div class="card p-2" style="background:rgba(88,166,255,0.06);border-color:var(--accent)">
|
||
<div class="card-title" style="font-size:11px">총 입금액</div>
|
||
<div class="stat-val" id="pf_total_deposit" style="font-size:16px">—</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3"><div class="card p-2">
|
||
<div class="card-title" style="font-size:11px">예수금</div>
|
||
<div class="stat-val" id="pf_cash" style="font-size:16px">—</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3"><div class="card p-2">
|
||
<div class="card-title" style="font-size:11px">주식 평가금</div>
|
||
<div class="stat-val" id="pf_holdings_eval" style="font-size:16px">—</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3"><div class="card p-2">
|
||
<div class="card-title" style="font-size:11px">총자산(예수금+평가)</div>
|
||
<div class="stat-val" id="pf_total_asset" style="font-size:16px">—</div>
|
||
</div></div>
|
||
</div>
|
||
<div class="mt-2" style="font-size:11px;color:var(--muted);line-height:1.5">
|
||
<b>동기 배지:</b>
|
||
<span class="badge-win">OK</span> DB·실계좌 수량 일치 ·
|
||
<span class="badge-loss">주의</span> 수량 불일치(HTS에서 수동 매매했을 수 있음) ·
|
||
<span class="badge-loss">봇고아</span> 봇 매수 기록은 있는데 active_trades 없음 →
|
||
<b>🧩 봇고아 DB복구</b> ·
|
||
<span class="badge-win">홀딩봇</span> HOLDING 관리 종목(여기서 매도 안 함)
|
||
</div>
|
||
</div>
|
||
<div class="trade-sort-bar mb-2" id="pf_sort_bar">
|
||
<span class="trade-sort-label">정렬</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary pf-sort-btn active" data-sort="pnl_desc">수익률↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary pf-sort-btn" data-sort="pnl_asc">수익률↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary pf-sort-btn" data-sort="eval_desc">평가금↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary pf-sort-btn" data-sort="eval_asc">평가금↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary pf-sort-btn" data-sort="name_asc">종목명</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary pf-sort-btn" data-sort="untracked_first">미등록먼저</button>
|
||
</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" id="pf_table">
|
||
<thead><tr>
|
||
<th>전략</th><th>종목</th><th>매수시각</th><th>DB수량</th><th>실계좌</th><th>동기</th>
|
||
<th>DB매수가</th><th>실평단</th><th>현재가</th><th>수익률</th><th>평가금</th><th>매도</th>
|
||
</tr></thead>
|
||
<tbody id="pf_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
<div id="pf_empty" class="text-muted py-3" style="display:none;font-size:13px">
|
||
active_trades 에 보유 종목이 없습니다.
|
||
</div>
|
||
</div>
|
||
</div><!-- tab-portfolio end -->
|
||
|
||
<!-- ═══ 스캘핑 백테스트 탭 ═══════════════════════════════════════════════ -->
|
||
<div id="tab-backtest" style="display:none">
|
||
<div class="card p-3 mb-3" style="border-left:4px solid var(--accent)">
|
||
<div style="font-size:14px;line-height:1.7">
|
||
<b>📉 스캘핑 Reversal — 키움 <code>scalp_re</code> 조건검색 + RSI V자 반전</b><br>
|
||
<span style="color:var(--muted);font-size:12px">
|
||
• <b>SCAN</b>: 키움 조건검색 → <code>target_candidates_history</code> (strategy_id=SCALP)<br>
|
||
• <b>TRIGGER</b>: RSI 과매도 반등 · 낙폭필터 · (선택) MACD 골든크로스 — <code>scalping_engine</code> 라이브와 100% 동일<br>
|
||
• 모멘텀 추격은 <b>🌊 모멘텀 백테스트</b> 탭 사용 (SCALP 와 분리)
|
||
</span>
|
||
</div>
|
||
</div>
|
||
<div class="card p-3 mb-3">
|
||
<div class="row g-2 align-items-end mb-2">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">시작일</label>
|
||
<input type="date" class="form-control" id="bt_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">종료일</label>
|
||
<input type="date" class="form-control" id="bt_end" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="종목당 1회 매수 금액">1회투자(원)<span class="d-block text-muted fw-normal" style="font-size:10px">SCALP_SLOT_MONEY</span></label>
|
||
<input type="number" class="form-control" id="bt_slot" value="3000000" min="100000" step="100000" style="width:130px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="동시 보유 종목 수">동시보유(종)<span class="d-block text-muted fw-normal" style="font-size:10px">SCALP_MAX_STOCKS</span></label>
|
||
<input type="number" class="form-control" id="bt_max_stocks" value="3" min="1" max="50" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="총 운용한도 — 수익률% 분모">총운용한도(원)<span class="d-block text-muted fw-normal" style="font-size:10px">SCALP_TOTAL_BUDGET_KRW</span></label>
|
||
<input type="number" class="form-control" id="bt_total_budget" value="9000000" min="0" step="100000" style="width:130px">
|
||
</div>
|
||
<div class="col-12 mt-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="bt_use_univ_history" checked>
|
||
<label class="form-check-label" for="bt_use_univ_history" style="font-size:12px;color:var(--muted)">
|
||
<b>저장 후보 이력</b> (<code>target_candidates_history</code>, strategy_id=SCALP) — 체크: DB 슬롯·후보 / 해제: 반전 시뮬 유니버스
|
||
</label>
|
||
</div>
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="bt_env_timeline">
|
||
<label class="form-check-label" for="bt_env_timeline" style="font-size:12px;color:var(--muted)" title="ON: 봉 시각별 과거 env 스냅샷으로 파람 덮어씀. OFF(기본): 폼 파람 고정">
|
||
<b>env 타임라인</b> — 체크: 그 시각 DB설정 재현 / <b>해제(기본)</b>: 폼 파람으로 구간 전체
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<!-- 기본 파라미터 -->
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row">RSI 기간</label>
|
||
<input type="number" class="form-control" id="bt_rsi_period" value="3" min="2" max="14">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row">RSI 과매도</label>
|
||
<input type="number" class="form-control" id="bt_rsi_oversold" value="18" min="10" max="45" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="이 값 초과 시 고점추격으로 진입 금지">RSI 과열</label>
|
||
<input type="number" class="form-control" id="bt_rsi_overbought" value="75" min="50" max="100" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row">손절(%)</label>
|
||
<input type="number" class="form-control" id="bt_sl" value="1.5" min="0.3" max="5" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row">익절(%)</label>
|
||
<input type="number" class="form-control" id="bt_tp" value="1.5" min="0.3" max="5" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="익절 % 상한 — tp_pct가 이보다 크면 목표가는 이 값으로 캡">익절상한%</label>
|
||
<input type="number" class="form-control" id="bt_tp_max" value="2.0" min="0.3" max="10" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row">낙폭필터(%)</label>
|
||
<input type="number" class="form-control" id="bt_drop" value="2.0" min="0.5" max="5" step="0.1">
|
||
</div>
|
||
</div>
|
||
<!-- 고급 필터 (2행) -->
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="손익 후 같은 종목 재진입 금지 시간(분)">쿨다운(분)</label>
|
||
<input type="number" class="form-control" id="bt_cooldown" value="10" min="0" max="60" step="5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="현재봉 거래량 > 20봉평균 × N배. 0=비활성">거래량배수(0=끔)</label>
|
||
<input type="number" class="form-control" id="bt_vol_mult" value="0" min="0" max="5" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="어깨 발동: 진입가 대비 이 % 이상 올라야 고점 추적 시작">어깨발동%</label>
|
||
<input type="number" class="form-control" id="bt_smin" value="0.5" min="0" max="5" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="어깨 폭: 갱신된 고점 대비 이 % 하락 시 1순위 청산">어깨폭%</label>
|
||
<input type="number" class="form-control" id="bt_scut" value="0.3" min="0.1" max="3" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="매수 가능 시작 시각(HHMM)">매수시작</label>
|
||
<input type="number" class="form-control" id="bt_time_start" value="830" min="830" max="1500" step="10" style="width:80px">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="매수 가능 종료 시각(HHMM)">매수종료</label>
|
||
<input type="number" class="form-control" id="bt_time_end" value="1530" min="900" max="1530" step="10" style="width:80px">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="종목당 하루 최대 거래횟수">일일최대매수</label>
|
||
<input type="number" class="form-control" id="bt_max_daily" value="3" min="1" max="10">
|
||
</div>
|
||
</div>
|
||
<!-- TRIGGER (SCAN vs TRIGGER — tail·모멘텀 탭과 동일 패턴) -->
|
||
<div class="row g-2 align-items-center mt-2 p-2 rounded" style="background:#0d1117;border:1px solid #21262d">
|
||
<div class="col-12"><span class="text-muted" style="font-size:11px"><b style="color:var(--accent)">TRIGGER 필터</b> — HTS SCAN 통과 후 엔진 검사</span></div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="bt_skip_hts_dupes" checked>
|
||
<label class="form-check-label" for="bt_skip_hts_dupes" style="font-size:12px" title="SCALP_SKIP_HTS_SCAN_DUPES — 낙폭·RSI·거래량 중복 생략">HTS중복스킵</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="bt_require_reversal" checked>
|
||
<label class="form-check-label" for="bt_require_reversal" style="font-size:12px" title="SCALP_REQUIRE_REVERSAL_CANDLE">반전캔들필수</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="bt_use_defense" checked>
|
||
<label class="form-check-label" for="bt_use_defense" style="font-size:12px">진입방어 ON</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="bt_use_macd">
|
||
<label class="form-check-label" for="bt_use_macd" style="font-size:12px" title="SCALP_USE_MACD_CROSS">MACD골든크로스</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 방어 수치 -->
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="당일고가 대비 이 비율 이하면 진입 허용">고점추격방지</label>
|
||
<input type="number" class="form-control" id="bt_high_chase" value="0.96" min="0.5" max="1" step="0.01">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="당일 등락률 이 값 초과 시 진입 금지(%)">급등주필터(%)</label>
|
||
<input type="number" class="form-control" id="bt_max_daily_chg" value="20" min="0" max="100" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="이 가격 미만 종목 진입 금지(원)">최소가격(원)</label>
|
||
<input type="number" class="form-control" id="bt_min_price" value="1000" min="0" step="100">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="종목당 1회 최대 손실 한도(원)">1회최대손실(원)</label>
|
||
<input type="number" class="form-control" id="bt_max_loss_krw" value="200000" min="0" step="10000">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="본절사수 시 최소 순이익 마진(%)">본절마진(%)</label>
|
||
<input type="number" class="form-control" id="bt_min_margin" value="0.2" min="0" max="2" step="0.1">
|
||
</div>
|
||
<div class="col-12 col-md-auto mt-2 d-flex gap-2 flex-wrap">
|
||
<button class="btn btn-primary px-4" onclick="runBacktest()">🚀 백테스트 실행</button>
|
||
<button class="btn btn-success px-3" onclick="saveScalpConfig()">💾 봇에 설정저장</button>
|
||
<span class="text-muted" style="font-size:11px">탐색: CLI param_search_scalping.py</span>
|
||
</div>
|
||
</div>
|
||
<div class="mt-3 p-2 rounded" style="background:#0d1117;border:1px solid #21262d;font-size:11px;color:var(--muted)">
|
||
<b style="color:var(--accent)">📖 SCAN vs TRIGGER vs 청산</b><br>
|
||
SCAN: 키움 <code>scalp_re</code> · TRIGGER: RSI V자 + (skip OFF 시) 낙폭·거래량·반전캔들 · 청산: 어깨→익절→손절→금액손실→EOD (tp_max는 익절 상한) · 진입=신호봉 다음봉 시가 · 탐색: <code>param_search_scalping.py</code>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 파라미터 요약 -->
|
||
<div id="bt_params_bar" class="text-muted mb-3" style="font-size:12px;display:none"></div>
|
||
|
||
<!-- 요약 카드 (꼬리/모멘텀/돌파와 동일 8칸) -->
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 거래</div><div class="stat-val" id="b_total">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">승률</div><div class="stat-val" id="b_winrate">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">순손익(수수료·세금 포함)</div><div class="stat-val" id="b_pnl">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">Profit Factor</div><div class="stat-val" id="b_pf">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">최대 낙폭(MDD)</div><div class="stat-val red" id="b_mdd">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">평균 보유(분)</div><div class="stat-val" id="b_hold">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 수익률(운용한도 대비)</div><div class="stat-val" id="b_bot_pct">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">일평균 수익률</div><div class="stat-val" id="b_daily_avg_pct">-</div>
|
||
</div></div>
|
||
</div>
|
||
<!-- Buy & Hold 비교 -->
|
||
<!-- 승/패 바 -->
|
||
<div class="card p-3 mb-3" id="bt_winbar_card" style="display:none">
|
||
<div class="d-flex justify-content-between mb-1">
|
||
<span style="color:var(--green)" id="b_win_label">-</span>
|
||
<span style="color:var(--red)" id="b_loss_label">-</span>
|
||
</div>
|
||
<div class="ratio-bar">
|
||
<span class="ratio-fill-g" id="b_ratio_g" style="width:50%"></span>
|
||
<span class="ratio-fill-r" id="b_ratio_r" style="width:50%"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row g-3">
|
||
<div class="col-12 col-lg-8">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">누적 손익 곡선 (가상)</div>
|
||
<canvas id="b_equity_chart" height="220"></canvas>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-lg-4">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">매도 이유 분포</div>
|
||
<canvas id="b_reason_chart" height="200"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card p-3 mt-3">
|
||
<div class="card-title mb-2">일별 손익 (가상)</div>
|
||
<canvas id="b_daily_chart" height="150"></canvas>
|
||
</div>
|
||
|
||
<!-- 백테스트 거래 목록 -->
|
||
<div class="section-title">가상 거래 내역 (최근 200건)</div>
|
||
<div id="bt_trade_context" class="mb-2 p-2 rounded" style="font-size:12px;background:var(--bg-secondary, #1c2128);color:var(--muted);display:none"></div>
|
||
<div class="trade-sort-bar mb-2" data-tbody="bt_tbody">
|
||
<span class="trade-sort-label">정렬</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn active" data-sort="exit_desc">매도 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="exit_asc">매도 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_desc">매수 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_asc">매수 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_desc">손익↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_asc">손익↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_desc">수익률↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_asc">수익률↓</button>
|
||
</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" id="bt_table">
|
||
<thead><tr>
|
||
<th>종목</th><th>매수시각</th><th>매도시각</th>
|
||
<th>매수가</th><th>매도가</th><th>수량</th>
|
||
<th>손익(원)</th><th>수익률%</th><th>누적손익</th><th>누적%</th><th>보유(분)</th><th>매도사유</th><th>진입RSI</th>
|
||
</tr></thead>
|
||
<tbody id="bt_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div><!-- tab-backtest end -->
|
||
|
||
<!-- ═══ 꼬리잡기 백테스트 탭 ══════════════════════════════════════════════ -->
|
||
<div id="tab-tail" style="display:none">
|
||
<div class="card p-3 mb-3">
|
||
<!-- 기간 -->
|
||
<div class="row g-2 align-items-end mb-2">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">시작일</label>
|
||
<input type="date" class="form-control" id="tl_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">종료일</label>
|
||
<input type="date" class="form-control" id="tl_end" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="1회 매수 금액 — 실매 SLOT_MONEY_DEFAULT / resolve_invest_amount_krw">1회투자금(원)</label>
|
||
<input type="number" class="form-control" id="tl_slot" value="3000000" min="100000" step="100000" style="width:130px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="동시 보유 매입금 합 상한 — env SHORT_TOTAL_BUDGET_KRW (0=동시보유×1회투자금)">총 운용한도(원)</label>
|
||
<input type="number" class="form-control" id="tl_total_budget" value="9000000" min="0" step="100000" style="width:130px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="동시 보유 종목 수 — env SHORT_MAX_STOCKS / MAX_STOCKS">동시보유(종목)</label>
|
||
<input type="number" class="form-control" id="tl_max_stocks" value="3" min="1" max="50" step="1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="ws_candles.timeframe — DB에 해당 분봉이 있어야 함 (실매 3분 기본)">분봉(TF)</label>
|
||
<select class="form-control" id="tl_tf" style="width:100px">
|
||
<option value="3" selected>3분</option>
|
||
<option value="5">5분</option>
|
||
<option value="15">15분</option>
|
||
<option value="60">60분</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="limit_atr=ATR 지정가 대기 / align=다음봉 시가">진입모드</label>
|
||
<select class="form-select" id="tl_entry_mode" style="width:130px">
|
||
<option value="limit_atr" selected>C limit_atr</option>
|
||
<option value="align">A align</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="TAIL_LIMIT_ATR_MULT — anchor−ATR×배수">지정가×ATR</label>
|
||
<input type="number" class="form-control" id="tl_limit_atr_mult" value="1.5" min="0.5" max="5" step="0.1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="TAIL_LIMIT_ANCHOR">기준가</label>
|
||
<select class="form-select" id="tl_limit_anchor" style="width:110px">
|
||
<option value="signal_low" selected>신호저점</option>
|
||
<option value="signal_close">신호종가</option>
|
||
<option value="prev_close">전봉종가</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="TAIL_LIMIT_VALID_BARS — 체결 대기 봉 수(3분봉)">유효봉</label>
|
||
<input type="number" class="form-control" id="tl_limit_valid_bars" value="1" min="1" max="5" step="1" style="width:56px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="TAIL_LIMIT_FILL_SLIP_PCT — 백테 체결 보정">체결슬립(%)</label>
|
||
<input type="number" class="form-control" id="tl_limit_fill_slip" value="0" min="0" max="1" step="0.01" style="width:72px">
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 align-items-end mb-2">
|
||
<div class="col-12">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="tl_use_univ_history" checked>
|
||
<label class="form-check-label" for="tl_use_univ_history" style="font-size:12px;color:var(--muted)">
|
||
<b>저장 후보 이력</b> (<code>target_candidates_history</code>) — 체크: DB 슬롯·후보 / 해제: ws_candles 전 종목
|
||
</label>
|
||
</div>
|
||
<div class="form-check form-check-inline mt-1">
|
||
<input class="form-check-input" type="checkbox" id="tl_use_tick_db" checked>
|
||
<label class="form-check-label" for="tl_use_tick_db" style="font-size:12px;color:var(--muted)"
|
||
title="TAIL_BACKTEST_USE_TICK_DB — 기본 ON. limit_atr·align 진입가를 ws_ticks로 재생(실매 체결 정합)">
|
||
<b>틱 진입</b> (<code>ws_ticks</code>) — 기본 ON
|
||
</label>
|
||
</div>
|
||
<div class="form-check form-check-inline mt-1">
|
||
<input class="form-check-input" type="checkbox" id="tl_tick_fallback_ohlc">
|
||
<label class="form-check-label" for="tl_tick_fallback_ohlc" style="font-size:12px;color:var(--muted)"
|
||
title="TAIL_BACKTEST_TICK_FALLBACK_OHLC — 기본 OFF. 틱 없으면 체결 스킵(실매 정합). ON=3분봉 OHLC 폴백(유령거래)">
|
||
틱 없으면 <b>OHLC 폴백</b> (기본 OFF)
|
||
</label>
|
||
</div>
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="tl_env_timeline">
|
||
<label class="form-check-label" for="tl_env_timeline" style="font-size:12px;color:var(--muted)" title="ON: 봉 시각별 과거 env. OFF(기본): 폼 파람 고정">
|
||
<b>env 타임라인</b> — 체크: 그 시각 DB설정 재현 / <b>해제(기본)</b>: 폼 파람으로 구간 전체
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 핵심 파라미터 (1행) -->
|
||
<div class="row g-2 align-items-end">
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="당일 시가→저가 낙폭이 이 값 이상이어야 진입">낙폭필터(%)</label>
|
||
<input type="number" class="form-control" id="tl_drop" value="2.0" min="0.5" max="10" step="0.5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="(현재가-저가)/(고가-저가) 최소 회복 비율(%)">회복률(%)</label>
|
||
<input type="number" class="form-control" id="tl_rec" value="45" min="10" max="90" step="5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="꼬리길이/몸통길이 최소 비율 (망치봉 강도)">꼬리/몸통</label>
|
||
<input type="number" class="form-control" id="tl_tail" value="1.5" min="0.3" max="5" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row">손절(%)</label>
|
||
<input type="number" class="form-control" id="tl_sl" value="3.0" min="0.5" max="10" step="0.5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row">익절(%)</label>
|
||
<input type="number" class="form-control" id="tl_tp" value="5.0" min="0.5" max="15" step="0.5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="매수가 대비 이 값 이상 오른 뒤 어깨 컷 발동">어깨발동(%)</label>
|
||
<input type="number" class="form-control" id="tl_smin" value="0.3" min="0.1" max="2" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="갱신된 max_price 대비 이 % 하락 시 어깨 컷 (1순위 청산)">어깨컷(%)</label>
|
||
<input type="number" class="form-control" id="tl_scut" value="0.2" min="0.05" max="2" step="0.05">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="TAIL_TRAIL_PCT — 보조 트레일 하락폭(고점 대비). 0=OFF">보조트레일(%)</label>
|
||
<input type="number" class="form-control" id="tl_trail" value="0" min="0" max="5" step="0.1" style="width:80px">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="TAIL_TRAIL_ARM_PCT — 이 수익% 도달 후 보조트레일 무장. 0=즉시">트레일무장(%)</label>
|
||
<input type="number" class="form-control" id="tl_trail_arm" value="0" min="0" max="5" step="0.1" style="width:80px">
|
||
</div>
|
||
<div class="col-12 col-md-3">
|
||
<label class="form-label param-row" title="래칫 ON 시 단일 어깨 대체. 형식: 수익%:컷%,… (비우면 단일 어깨)">래칫단계 TAIL_RATCHET_TIERS</label>
|
||
<select class="form-select form-select-sm mb-1" id="tl_ratchet_preset"
|
||
title="파람서치 그리드 프리셋 — 고르면 아래 칸이 채워집니다(직접 수정 가능)"
|
||
onchange="btApplyPreset('tl_ratchet', this.value, true)">
|
||
<option value="__custom__">프리셋 선택…(직접입력)</option>
|
||
<option value="off">off (단일 어깨컷)</option>
|
||
<option value="0.5:0.3,1.0:0.25,2.0:0.2">0.5:0.3,1.0:0.25,2.0:0.2 (3단)</option>
|
||
<option value="1.0:0.4,2.0:0.3">1.0:0.4,2.0:0.3 (2단)</option>
|
||
</select>
|
||
<input type="text" class="form-control" id="tl_ratchet" value="" placeholder="0.5:0.3,1.0:0.25,2.0:0.2" style="font-size:12px" oninput="tlSyncRatchetShoulderColors&&tlSyncRatchetShoulderColors()">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="꼬리 길이 최소 비율(%) → TAIL_PCT_MIN">꼬리최소(%)</label>
|
||
<input type="number" class="form-control" id="tl_tail_pct" value="0.3" min="0.01" max="2" step="0.05">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="3분봉 회복위치 상한(%) → MAX_RECOVERY_RATIO_3M">3분최대회복(%)</label>
|
||
<input type="number" class="form-control" id="tl_max_rec_3m" value="90" min="50" max="100" step="5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="고점 대비 이 비율 이상이면 진입 거부(%) → HIGH_PRICE_CHASE_THRESHOLD">고점추격방지(%)</label>
|
||
<input type="number" class="form-control" id="tl_high_chase" value="96" min="90" max="100" step="1">
|
||
</div>
|
||
</div>
|
||
<!-- 당일 누적손익 다단트레일 — SHORT_DAILY_PROFIT_TARGET_ENABLED -->
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-12"><span style="font-size:11px;color:var(--muted)">📅 다단트레일 ON이면 당일 실현손익 고점 대비 되돌릴 때 <b>신규매수만</b> 중단. DB=<code>SHORT_DAILY_PROFIT_TARGET_ENABLED</code>. 이번만 끄려면 체크 해제 후 실행(봇저장 X면 DB 유지).</span></div>
|
||
<div class="col-auto">
|
||
<div class="form-check mt-3">
|
||
<input class="form-check-input" type="checkbox" id="tl_daily_profit_enabled">
|
||
<label class="form-check-label param-row" for="tl_daily_profit_enabled" title="SHORT_DAILY_PROFIT_TARGET_ENABLED — 다단트레일 ON/OFF. 로드=DB, 봇저장 시 DB 반영">다단트레일</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-md-4">
|
||
<label class="form-label param-row" title="다단 트레일(ratchet식): 수익원:컷%,… — 벌수록 컷% 타이트하게 사수. 비우면 단일 되돌림 사용. 예: 30000:50,100000:35,300000:25">다단규칙(수익원:컷%,…)</label>
|
||
<select class="form-select form-select-sm mb-1" id="tl_daily_trail_preset"
|
||
title="프리셋 — 고르면 아래 칸이 채워집니다(감시 스위치는 그대로)"
|
||
onchange="btApplyPreset('tl_daily_trail_tiers', this.value, false)">
|
||
<option value="__custom__">프리셋 선택…(직접입력)</option>
|
||
<option value="off">off (다단 숫자 비움)</option>
|
||
<option value="20000:40,50000:30,150000:20">보수 20000:40,50000:30,150000:20</option>
|
||
<option value="30000:50,100000:35,300000:25">중도 30000:50,100000:35,300000:25</option>
|
||
<option value="50000:60,200000:45,500000:30">공격 50000:60,200000:45,500000:30</option>
|
||
</select>
|
||
<input type="text" class="form-control" id="tl_daily_trail_tiers" value="" placeholder="30000:50,100000:35,300000:25" style="font-size:12px">
|
||
</div>
|
||
<div class="col-4 col-md-2">
|
||
<label class="form-label param-row" title="다단이 비었을 때만: 당일 실현손익 고점 대비 이 % 되돌리면 중단. 0=미사용">단일되돌림(%)</label>
|
||
<input type="number" class="form-control" id="tl_daily_trail_drop" value="0" min="0" max="90" step="5" style="width:110px">
|
||
</div>
|
||
<div class="col-4 col-md-2">
|
||
<label class="form-label param-row" title="단일 되돌림용: 이 수익(원) 이상 벌어야 감시 시작. 0이면 비활성(과민발동 방지)">발동최소수익(원)</label>
|
||
<input type="number" class="form-control" id="tl_daily_trail_arm" value="0" min="0" step="50000" style="width:130px">
|
||
</div>
|
||
<div class="col-4 col-md-2">
|
||
<label class="form-label param-row" title="trailing=트레일만 / both=고정목표(운영설정)+트레일 먼저 닿는 쪽">방식</label>
|
||
<select class="form-select" id="tl_daily_profit_mode" style="width:120px">
|
||
<option value="trailing" selected>trailing</option>
|
||
<option value="both">both</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<!-- V3 방어 파라미터 -->
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="최소 주가">최소가격(원)</label>
|
||
<input type="number" class="form-control" id="tl_min_price" value="1000" min="0" step="500">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="당일 최고/최저 상승폭 제한">최대급등(%)</label>
|
||
<input type="number" class="form-control" id="tl_max_daily_change" value="20" min="5" max="30" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="MA20 대비 가격 이격도 허용 범위">MA20이격(%)</label>
|
||
<input type="number" class="form-control" id="tl_ma20_above" value="3.0" min="1.0" max="10.0" step="0.5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="1회 매매 최대 손실 원화 (금액 컷)">최대손실컷(원)</label>
|
||
<input type="number" class="form-control" id="tl_max_loss_krw" value="200000" min="10000" step="10000">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="금액손실컷 발동 최소 하락률(%) — 이 미만은 흔들림으로 보고 미발동">손실컷최소하락(%)</label>
|
||
<input type="number" class="form-control" id="tl_min_drop_loss_cut" value="1.5" min="0.5" max="5" step="0.5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="ATR 기준 손절 배수 (변동성 대응)">ATR손절(배)</label>
|
||
<input type="number" class="form-control" id="tl_stop_atr" value="1.5" min="0.5" max="10" step="0.5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="ATR 기준 익절 배수 (2순위 백업)">ATR익절(배)</label>
|
||
<input type="number" class="form-control" id="tl_target_atr" value="2.0" min="1.0" max="20" step="0.5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="ATR 손절 % 하한 (캡)">ATR손절하한%</label>
|
||
<input type="number" class="form-control" id="tl_atr_sl_min" value="0.8" min="0.1" max="20" step="0.1" style="width:78px">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="ATR 손절 % 상한 (캡)">ATR손절상한%</label>
|
||
<input type="number" class="form-control" id="tl_atr_sl_max" value="1.0" min="0.5" max="30" step="0.1" style="width:78px">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="ATR 익절 % 하한 (캡)">ATR익절하한%</label>
|
||
<input type="number" class="form-control" id="tl_atr_tp_min" value="0.3" min="0.1" max="20" step="0.1" style="width:78px">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="ATR 익절 % 상한 (캡)">ATR익절상한%</label>
|
||
<input type="number" class="form-control" id="tl_atr_tp_max" value="1.0" min="0.2" max="30" step="0.1" style="width:78px">
|
||
</div>
|
||
</div>
|
||
<!-- 고급 파라미터 (2행) -->
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="RSI 계산 캔들 수 (실매·파라서치와 동일)">RSI기간</label>
|
||
<input type="number" class="form-control" id="tl_rsi_period" value="14" min="3" max="21" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="RSI 이 값 이상이면 과열로 진입 거부">RSI과열기준</label>
|
||
<input type="number" class="form-control" id="tl_rsi" value="78" min="50" max="95" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="청산 후 같은 종목 재진입 금지 시간(분)">쿨다운(분)</label>
|
||
<input type="number" class="form-control" id="tl_cool" value="30" min="0" max="120" step="5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row">매수시작(HHMM)</label>
|
||
<input type="number" class="form-control" id="tl_ts" value="830" min="900" max="1500" step="100">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row">매수종료(HHMM)</label>
|
||
<input type="number" class="form-control" id="tl_te" value="1530" min="900" max="1530" step="100">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="종목당 하루 최대 거래횟수 (안전판)">일일최대매수</label>
|
||
<input type="number" class="form-control" id="tl_maxd" value="20" min="1" max="50">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="종목당 당일 실현손익 한도(원, 양수) — 이하면 그 종목만 재진입 금지">종목손실한도(원)</label>
|
||
<input type="number" class="form-control" id="tl_symbol_loss_krw" value="30000" min="0" step="5000">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="1회투자금 대비 % — KRW·% 중 먼저 닿는 쪽 적용">종목손실한도(%)</label>
|
||
<input type="number" class="form-control" id="tl_symbol_loss_pct" value="1.5" min="0" max="10" step="0.5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="재진입 허용 최소 당일 누적순익(원, 수수료·세금 감안)">재진입최소(원)</label>
|
||
<input type="number" class="form-control" id="tl_reentry_min_edge" value="0" min="0" step="500">
|
||
</div>
|
||
<div class="col-auto d-flex align-items-end">
|
||
<div class="form-check mb-2">
|
||
<input class="form-check-input" type="checkbox" id="tl_eod_enabled" checked>
|
||
<label class="form-check-label param-row" for="tl_eod_enabled" title="ON=설정 시각 이후 보유 전량 당일청산">EOD청산</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="EOD 당일청산 시각 (HH:MM)">EOD시각</label>
|
||
<input type="text" class="form-control" id="tl_eod_hm" value="15:25" placeholder="15:25" style="width:72px">
|
||
</div>
|
||
</div>
|
||
<!-- TRIGGER 플래그 (SCAN vs TRIGGER — 실매·백테·저장 동일) -->
|
||
<div class="row g-2 align-items-center mt-2 p-2 rounded" style="background:#0d1117;border:1px solid #21262d">
|
||
<div class="col-12"><span class="text-muted" style="font-size:11px"><b style="color:var(--accent)">TRIGGER 필터</b> — 매수 직전 엔진 검사 (HTS tail 조건 통과 후)</span></div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="tl_skip_hts_dupes" checked>
|
||
<label class="form-check-label" for="tl_skip_hts_dupes" style="font-size:12px" title="HTS A조건(낙폭) 재검사 생략 — 이중필터 방지">HTS중복스킵</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="tl_use_rsi_filter" checked>
|
||
<label class="form-check-label" for="tl_use_rsi_filter" style="font-size:12px">RSI필터</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="tl_use_ma20_filter">
|
||
<label class="form-check-label" for="tl_use_ma20_filter" style="font-size:12px">MA20필터</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="tl_use_daily_range" checked>
|
||
<label class="form-check-label" for="tl_use_daily_range" style="font-size:12px">당일변동필터</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="tl_use_high_chase_f" checked>
|
||
<label class="form-check-label" for="tl_use_high_chase_f" style="font-size:12px">고점추격필터</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2" title="이 백테 1회에만 적용 (실매 미반영). 저장 시에만 DB 반영">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="tl_ob_filter" checked>
|
||
<label class="form-check-label" for="tl_ob_filter" style="font-size:12px">호가필터(백테)</label>
|
||
</div>
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="tl_pg_filter" checked>
|
||
<label class="form-check-label" for="tl_pg_filter" style="font-size:12px">프로그램필터(백테)</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="호가 스프레드 상한(%). kiwoom_0d 본체 재계산(6/25~)">스프레드(%)<span class="d-block text-muted fw-normal" style="font-size:10px">MAX_SPREAD</span></label>
|
||
<input type="number" step="0.01" class="form-control form-control-sm" id="tl_max_spread_pct" value="0.45">
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="tl_use_intraday_drop">
|
||
<label class="form-check-label" for="tl_use_intraday_drop" style="font-size:12px">당일낙폭필터</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<label class="form-label param-row" title="0=OFF. 신호봉 거래량 ≥ 직전 N봉평균×배수 (TRIGGER)">거래량배수</label>
|
||
<input type="number" class="form-control" id="tl_tail_vol_mult" value="0" min="0" max="10" step="0.1" style="width:78px">
|
||
</div>
|
||
<div class="col-6 col-md-1">
|
||
<label class="form-label param-row" title="거래량 평균 창(봉 수)">거래량창</label>
|
||
<input type="number" class="form-control" id="tl_tail_vol_win" value="5" min="1" max="30" step="1" style="width:58px">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" style="font-size:11px">봉등락MIN%</label>
|
||
<input type="number" class="form-control" id="tl_bar_chg_min" value="-10" min="-30" max="0" step="0.5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" style="font-size:11px">봉등락MAX%</label>
|
||
<input type="number" class="form-control" id="tl_bar_chg_max" value="-1.5" min="-30" max="0" step="0.5">
|
||
</div>
|
||
</div>
|
||
<!-- 반전 패턴 OR (TRIGGER — 낙폭·회복 필터 AND 유지) -->
|
||
<div class="row g-2 align-items-center mt-2 p-2 rounded" style="background:#0d1117;border:1px solid #21262d">
|
||
<div class="col-12"><span class="text-muted" style="font-size:11px"><b style="color:var(--accent)">반전 패턴</b> — 하나라도 충족 시 진입 (env <code>TAIL_PATTERN_*</code>)</span></div>
|
||
<div class="col-6 col-md-auto">
|
||
<div class="form-check form-check-inline">
|
||
<input class="form-check-input" type="checkbox" id="tl_pat_hammer" checked>
|
||
<label class="form-check-label" for="tl_pat_hammer" style="font-size:12px" title="TAIL_PATTERN_HAMMER">망치</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-auto">
|
||
<div class="form-check form-check-inline">
|
||
<input class="form-check-input" type="checkbox" id="tl_pat_pin">
|
||
<label class="form-check-label" for="tl_pat_pin" style="font-size:12px" title="TAIL_PATTERN_PIN">핀바</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-auto">
|
||
<div class="form-check form-check-inline">
|
||
<input class="form-check-input" type="checkbox" id="tl_pat_engulfing">
|
||
<label class="form-check-label" for="tl_pat_engulfing" style="font-size:12px" title="TAIL_PATTERN_ENGULFING">장악</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-auto">
|
||
<div class="form-check form-check-inline">
|
||
<input class="form-check-input" type="checkbox" id="tl_pat_piercing">
|
||
<label class="form-check-label" for="tl_pat_piercing" style="font-size:12px" title="TAIL_PATTERN_PIERCING">관통</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-auto">
|
||
<div class="form-check form-check-inline">
|
||
<input class="form-check-input" type="checkbox" id="tl_pat_harami">
|
||
<label class="form-check-label" for="tl_pat_harami" style="font-size:12px" title="TAIL_PATTERN_HARAMI">하라미</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-auto">
|
||
<div class="form-check form-check-inline">
|
||
<input class="form-check-input" type="checkbox" id="tl_pat_doji">
|
||
<label class="form-check-label" for="tl_pat_doji" style="font-size:12px" title="TAIL_PATTERN_DOJI">도지</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-auto">
|
||
<div class="form-check form-check-inline">
|
||
<input class="form-check-input" type="checkbox" id="tl_pat_morning_star">
|
||
<label class="form-check-label" for="tl_pat_morning_star" style="font-size:12px" title="TAIL_PATTERN_MORNING_STAR">샛별</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-12 col-md-auto mt-2 d-flex gap-2 flex-wrap">
|
||
<button class="btn btn-primary px-4" onclick="runTailBacktest()">🚀 백테스트 실행</button>
|
||
<button class="btn btn-success px-3" onclick="saveTailConfig()">💾 봇에 설정저장</button>
|
||
<button class="btn btn-outline-info px-3" onclick="loadTailSearchResults()">📂 탐색결과 불러오기</button>
|
||
<span class="text-muted" style="font-size:11px">탐색: CLI tail_param_search.py · 표에서 <b>폼반영</b>/<b>DB저장</b></span>
|
||
</div>
|
||
</div>
|
||
<!-- 파라미터 설명 -->
|
||
<div class="mt-3 p-2 rounded" style="background:#0d1117;border:1px solid #21262d;font-size:11px;color:var(--muted)">
|
||
<b style="color:var(--accent)">📖 파라미터 설명 (실매·파라서치·백테 동일 — tail_engine / config_short)</b>
|
||
<div class="row g-1 mt-1">
|
||
<div class="col-12 col-md-6">
|
||
<table style="width:100%;border-collapse:collapse">
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">분봉(TF)</td><td>백테·파라서치에 쓰는 <b>ws_candles.timeframe</b> (3·5·15·60). DB에 해당 분봉 봉이 있어야 함.</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">낙폭필터(%)</td><td>당일 시가→저가 하락폭 → DB: <b>MIN_DROP_RATE</b> (config_short)</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">회복률(%)</td><td>당일 저점 대비 회복 하한 → <b>MIN_RECOVERY_RATIO_SHORT</b></td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">3분최대회복(%)</td><td>3분봉 회복 위치 상한 → <b>MAX_RECOVERY_RATIO_3M</b></td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">꼬리/몸통</td><td>망 hammer → <b>TAIL_RATIO_MIN</b> · 패턴 OR → <b>TAIL_PATTERN_*</b></td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">청산순서</td><td><b>1)어깨(max_price)</b> → 2)ATR익절 → 3)ATR손절 → 4)금액손실컷</td></tr>
|
||
</table>
|
||
</div>
|
||
<div class="col-12 col-md-6">
|
||
<table style="width:100%;border-collapse:collapse">
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">어깨발동(%)</td><td>진입가 대비 이 수익% 이상이면 max_price 추적 → <b>SHOULDER_MIN_HIGH_PCT</b> (예: 0.3%)</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">어깨컷(%)</td><td><b>갱신된 max_price × (1−cut)</b> → <b>SHOULDER_CUT_PCT</b> (예: 0.2%)</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">ATR캡</td><td><b>TAIL_ATR_*_MIN/MAX_PCT</b> · 배수 <b>STOP/TARGET_ATR_MULTIPLIER_TAIL</b></td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">1회투자금</td><td>실매 <b>SLOT_MONEY_DEFAULT</b> / SHORT_MAX_BUY_AMOUNT (종목당 상한)</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">총 운용한도</td><td>동시 보유 매입금 합 ≤ <b>SHORT_TOTAL_BUDGET_KRW</b> (0=동시보유×1회투자금)</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">동시보유</td><td><b>SHORT_MAX_STOCKS</b> / MAX_STOCKS — 시각순 포트폴리오, 1봉 1매수</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">봇저장</td><td><code>insert_env_snapshot</code> → <b>config_short</b> + env_config 자동 분리</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">일일최대매수</td><td><b>TAIL_MAX_DAILY</b> — 무한루프 안전판(기본 20). 실질 제어는 아래 손실한도·재진입최소.</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">종목손실한도</td><td><b>TAIL_SYMBOL_DAILY_LOSS_LIMIT_KRW/PCT</b>(양수) — 종목 당일 실현손익이 −한도 이하면 그 종목만 재진입 금지. KRW·% 중 <b>먼저 닿는 쪽</b>.</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">재진입최소(원)</td><td><b>TAIL_REENTRY_MIN_EDGE_KRW</b> — 2회째 진입부터 당일 누적순익이 이 값 미만이면 차단(회전매매 방지).</td></tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="mt-1">⚡ 진입가 = <b>신호봉(3분봉) 다음 봉 시가</b> | 수수료 0.015%×2 + 거래세 0.18% 자동 차감 | 데이터: ws_candles 3분봉</div>
|
||
<div class="mt-1" style="color:var(--muted)">📌 백테는 <b>시각순 포트폴리오</b>(실매 MAX_STOCKS·총한도·1회 slot_money)로 실행됩니다. 웹·파라서치 맞추려면 시작/종료·TF·저장 이력·동시보유·총한도를 동일하게 두세요.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="tl_search_result" style="display:none" class="mb-3">
|
||
<div class="section-title">🔍 파라미터 탐색 결과 (CLI search_tail_*.json)</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" style="font-size:12px">
|
||
<thead id="tl_search_thead"><tr><th>-</th></tr></thead>
|
||
<tbody id="tl_search_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
<p id="tl_search_hint" class="text-muted" style="display:none;font-size:11px;margin-top:8px;line-height:1.45;"></p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 파라미터 요약 바 -->
|
||
<div id="tl_params_bar" class="text-muted mb-3" style="font-size:12px;display:none"></div>
|
||
|
||
<!-- 요약 카드 -->
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 거래</div><div class="stat-val" id="tl_total">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">승률</div><div class="stat-val" id="tl_winrate">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">순손익(수수료·세금 포함)</div><div class="stat-val" id="tl_pnl">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">Profit Factor</div><div class="stat-val" id="tl_pf">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">최대 낙폭(MDD)</div><div class="stat-val red" id="tl_mdd">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">평균 보유(분)</div><div class="stat-val" id="tl_hold">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 수익률(운용한도 대비)</div><div class="stat-val" id="tl_bot_pct">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">일평균 수익률</div><div class="stat-val" id="tl_daily_avg_pct">-</div>
|
||
</div></div>
|
||
</div>
|
||
<!-- 승/패 바 -->
|
||
<div class="card p-3 mb-3" id="tl_winbar_card" style="display:none">
|
||
<div class="d-flex justify-content-between mb-1">
|
||
<span style="color:var(--green)" id="tl_win_label">-</span>
|
||
<span style="color:var(--red)" id="tl_loss_label">-</span>
|
||
</div>
|
||
<div class="ratio-bar">
|
||
<span class="ratio-fill-g" id="tl_ratio_g" style="width:50%"></span>
|
||
<span class="ratio-fill-r" id="tl_ratio_r" style="width:50%"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row g-3">
|
||
<div class="col-12 col-lg-8">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">누적 손익 곡선 (가상)</div>
|
||
<canvas id="tl_equity_chart" height="220"></canvas>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-lg-4">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">매도 이유 분포</div>
|
||
<canvas id="tl_reason_chart" height="200"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card p-3 mt-3">
|
||
<div class="card-title mb-2">일별 손익 (가상)</div>
|
||
<canvas id="tl_daily_chart" height="150"></canvas>
|
||
</div>
|
||
|
||
<!-- 거래 내역 테이블 -->
|
||
<div class="section-title">가상 거래 내역 (최근 200건)</div>
|
||
<div id="tl_trade_context" class="mb-2 p-2 rounded" style="font-size:12px;background:var(--bg-secondary, #1c2128);color:var(--muted);display:none"></div>
|
||
<div class="trade-sort-bar mb-2" data-tbody="tl_tbody">
|
||
<span class="trade-sort-label">정렬</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn active" data-sort="exit_desc">매도 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="exit_asc">매도 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_desc">매수 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_asc">매수 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_desc">손익↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_asc">손익↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_desc">수익률↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_asc">수익률↓</button>
|
||
</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" id="tl_table">
|
||
<thead><tr>
|
||
<th>종목</th><th>매수시각</th><th>매도시각</th>
|
||
<th>매수가</th><th>매도가</th><th>수량</th>
|
||
<th>손익(원)</th><th>수익률%</th><th>누적손익</th><th>누적%</th>
|
||
<th>보유(분)</th><th>체결디버그</th><th>매도사유</th>
|
||
</tr></thead>
|
||
<tbody id="tl_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div><!-- tab-tail end -->
|
||
|
||
<!-- ═══ 더블 볼린저(DBBAND) — 종목별 파라미터 ═══════════════════════════════ -->
|
||
<div id="tab-dbband" style="display:none">
|
||
<div class="card p-3 mb-3">
|
||
<p class="mb-2" style="font-size:12px;color:var(--muted)">
|
||
<b>종목 1개씩</b> 파라미터·백테·탐색 (QQQM·379810 등 서로 다른 BB/MA).
|
||
백테·파라서치 데이터: <code>holding_min_candles</code> (아래 <b>키움/KIS 분봉 수집</b>으로 DB 저장).
|
||
실매 라이브 봉: <code>ws_candles</code> (영구구독 WS) — 백테와 별개.
|
||
저장: <code>dbband_stock_config</code> · 그리드 <code>DBBAND_GRID_*</code> env.
|
||
</p>
|
||
<div class="row g-2 align-items-end mb-2">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">종목</label>
|
||
<select class="form-control" id="db_code" style="min-width:220px"></select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">분봉</label>
|
||
<select class="form-control" id="db_tf" style="width:100px">
|
||
<option value="5">5분</option>
|
||
<option value="15" selected>15분</option>
|
||
<option value="60">60분</option>
|
||
<option value="3">3분</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">시작일</label>
|
||
<input type="date" class="form-control" id="db_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">종료일</label>
|
||
<input type="date" class="form-control" id="db_end" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="키움/KIS 분봉 수집 시작일 — holding_min_candles">분봉수집 시작</label>
|
||
<input type="date" class="form-control" id="db_fetch_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">1회투자(원)</label>
|
||
<input type="number" class="form-control" id="db_slot" value="3000000" min="100000" step="100000" style="width:120px">
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 align-items-end mb-2">
|
||
<div class="col-auto"><label class="form-label param-row">BB기간</label><input type="number" class="form-control" id="db_period" value="20" style="width:72px"></div>
|
||
<div class="col-auto"><label class="form-label param-row">Innerσ</label><input type="number" class="form-control" id="db_inner_std" value="2" step="0.1" style="width:72px"></div>
|
||
<div class="col-auto"><label class="form-label param-row">Outerσ</label><input type="number" class="form-control" id="db_outer_std" value="3" step="0.1" style="width:72px"></div>
|
||
<div class="col-auto"><label class="form-label param-row">추세MA</label><input type="number" class="form-control" id="db_trend_ma" value="200" style="width:80px"></div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="classic=영상원형(반대밴드·신호저점), v4_scalp=단타어깨컷">청산모드</label>
|
||
<select class="form-select" id="db_exit_mode" style="width:130px" onchange="dbSyncExitModeUi()">
|
||
<option value="classic" selected>영상원형</option>
|
||
<option value="v4_scalp">단타V4</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto"><label class="form-label param-row">손절%</label><input type="number" class="form-control" id="db_sl" value="2" step="0.5" style="width:72px" title="classic: 신호저점 우선(보조)"></div>
|
||
<div class="col-auto"><label class="form-label param-row">익절%</label><input type="number" class="form-control" id="db_tp" value="3" step="0.5" style="width:72px"></div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">익절모드</label>
|
||
<select class="form-select" id="db_tp_mode" style="width:120px">
|
||
<option value="opposite_band" selected>반대밴드</option>
|
||
<option value="pct">고정%</option>
|
||
<option value="rr">손익비</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto"><label class="form-label param-row">RR</label><input type="number" class="form-control" id="db_rr" value="2" step="0.5" style="width:72px"></div>
|
||
<div class="col-auto"><label class="form-label param-row">유효봉</label><input type="number" class="form-control" id="db_valid_bars" value="3" style="width:64px"></div>
|
||
<div class="col-auto" id="db_max_hold_wrap"><label class="form-label param-row">최대보유</label><input type="number" class="form-control" id="db_max_hold" value="0" min="0" style="width:64px" title="0=off (영상원형)"></div>
|
||
</div>
|
||
<div class="row g-2 align-items-end">
|
||
<div class="col-auto form-check mt-2">
|
||
<input class="form-check-input" type="checkbox" id="db_use_trend" checked>
|
||
<label class="form-check-label" for="db_use_trend">추세 MA 필터</label>
|
||
</div>
|
||
<div class="col-auto form-check mt-2">
|
||
<input class="form-check-input" type="checkbox" id="db_env_timeline">
|
||
<label class="form-check-label" for="db_env_timeline" style="font-size:12px;color:var(--muted)" title="ON: 봉 시각별 과거 env. OFF(기본): 폼 파람 고정">env 타임라인</label>
|
||
</div>
|
||
<div class="col-12 col-md-auto mt-2 d-flex gap-1 flex-wrap align-items-center">
|
||
<span class="align-self-center me-1" style="font-size:11px;color:var(--muted)">분봉수집</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary" style="color:#58a6ff;border-color:#58a6ff" onclick="dbFetchMinKiwoom(60)" title="KR=키움 ka10080 / US=KIS 해외분봉 → holding_min_candles">60분</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary" style="color:#58a6ff;border-color:#58a6ff" onclick="dbFetchMinKiwoom(15)" title="백테 TF와 동일하게 맞출 것">15분</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary" style="color:#58a6ff;border-color:#58a6ff" onclick="dbFetchMinKiwoom(5)">5분</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary" style="color:#58a6ff;border-color:#58a6ff" onclick="dbFetchMinKiwoom(3)">3분</button>
|
||
<span id="db_min_badge" class="align-self-center" style="font-size:11px;color:var(--muted)">DB봉: —</span>
|
||
<span id="db_min_status" style="font-size:11px;color:var(--accent);align-self:center"></span>
|
||
</div>
|
||
<div class="col-auto mt-2">
|
||
<button class="btn btn-primary" onclick="runDbBandBacktest()">▶ 백테</button>
|
||
<button class="btn btn-outline-info ms-1" onclick="runDbBandParamSearch()">🔍 파라서치</button>
|
||
<button class="btn btn-outline-secondary ms-1" onclick="saveDbBandStockConfig()">💾 종목저장</button>
|
||
</div>
|
||
<div class="col-auto mt-2"><span id="db_param_source" class="badge badge-secondary" style="font-size:11px"></span></div>
|
||
</div>
|
||
</div>
|
||
<div id="db_params_bar" class="text-muted mb-3" style="font-size:12px;display:none"></div>
|
||
|
||
<div id="db_result_area" style="display:none">
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3"><div class="card-title">총 거래</div><div class="stat-val" id="db_total">-</div></div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3"><div class="card-title">승률</div><div class="stat-val" id="db_winrate">-</div></div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3"><div class="card-title">순손익(수수료·세금 포함)</div><div class="stat-val" id="db_pnl">-</div></div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3"><div class="card-title">Profit Factor</div><div class="stat-val" id="db_pf">-</div></div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3"><div class="card-title">최대 낙폭(MDD)</div><div class="stat-val red" id="db_mdd">-</div></div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3"><div class="card-title">평균 보유(분)</div><div class="stat-val" id="db_hold">-</div></div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3"><div class="card-title">총 수익률(운용한도 대비)</div><div class="stat-val" id="db_bot_pct">-</div></div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3"><div class="card-title">일평균 수익률</div><div class="stat-val" id="db_daily_avg_pct">-</div></div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3"><div class="card-title">백테 봉수</div><div class="stat-val" id="db_candles">-</div></div></div>
|
||
</div>
|
||
<div class="card p-3 mb-3" id="db_winbar_card" style="display:none">
|
||
<div class="d-flex justify-content-between mb-1">
|
||
<span style="color:var(--green)" id="db_win_label">-</span>
|
||
<span style="color:var(--red)" id="db_loss_label">-</span>
|
||
</div>
|
||
<div class="ratio-bar">
|
||
<span class="ratio-fill-g" id="db_ratio_g" style="width:50%"></span>
|
||
<span class="ratio-fill-r" id="db_ratio_r" style="width:50%"></span>
|
||
</div>
|
||
</div>
|
||
<div class="row g-3 mb-3" id="db_bnh_row">
|
||
<div class="col-12"><div class="card p-3" style="border-color:var(--accent);background:rgba(88,166,255,0.05)">
|
||
<div class="card-title" style="color:var(--accent)">📊 Buy & Hold 벤치마크 (같은 기간·1회투자금)</div>
|
||
<div class="row g-3 mt-1">
|
||
<div class="col-6 col-md-3"><div class="card-title">봇 수익률</div><div class="stat-val" id="db_bot_pct_bnh">-</div></div>
|
||
<div class="col-6 col-md-3"><div class="card-title">B&H 수익률</div><div class="stat-val" id="db_bnh_pct">-</div></div>
|
||
<div class="col-6 col-md-3"><div class="card-title">B&H 손익(원)</div><div class="stat-val" id="db_bnh_pnl">-</div></div>
|
||
<div class="col-6 col-md-3"><div class="card-title">알파(봇−B&H)</div><div class="stat-val" id="db_alpha">-</div></div>
|
||
</div>
|
||
</div></div>
|
||
</div>
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-12 col-lg-8">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">누적 손익 곡선 (가상)</div>
|
||
<canvas id="db_equity_chart" height="220"></canvas>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-lg-4">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">청산 사유 분포</div>
|
||
<canvas id="db_reason_chart" height="200"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card p-3">
|
||
<table class="table table-hover"><thead><tr>
|
||
<th>방향</th><th>매수</th><th>매도</th><th>진입</th><th>청산</th><th>손익</th><th>분</th><th>사유</th>
|
||
</tr></thead><tbody id="db_tbody"></tbody></table>
|
||
</div>
|
||
</div><!-- db_result_area -->
|
||
<div id="db_search_results" class="card p-3 mt-3" style="display:none">
|
||
<div class="card-title mb-2">파라서치 상위</div>
|
||
<div class="table-responsive"><table class="table table-sm"><thead><tr>
|
||
<th>#</th><th>손익</th><th>승률</th><th>거래</th><th>Inner/Outer</th><th>MA</th><th>적용</th>
|
||
</tr></thead><tbody id="db_search_tbody"></tbody></table></div>
|
||
</div>
|
||
</div><!-- tab-dbband end -->
|
||
|
||
<!-- ═══ 돌파매매 백테스트 탭 ═════════════════════════════════════════════ -->
|
||
<div id="tab-breakout" style="display:none">
|
||
<div class="card p-3 mb-3">
|
||
<div class="row g-2 align-items-end flex-wrap">
|
||
<!-- 기간 (꼬리 탭과 동일 col-auto) -->
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">시작일</label>
|
||
<input type="date" class="form-control" id="bo_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">종료일</label>
|
||
<input type="date" class="form-control" id="bo_end" style="width:150px">
|
||
</div>
|
||
<!-- 매수 룰 (키움 'breakout' 조건식 1:1 매핑) -->
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="직전 N봉 최대고가 돌파 검사 (키움: 1봉)">Lookback(분봉)</label>
|
||
<input type="number" class="form-control" id="bo_lookback" value="1" min="1" max="60" step="1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="직전 N봉 평균 거래량 윈도우 (키움: 1봉)">VolWin(분봉)</label>
|
||
<input type="number" class="form-control" id="bo_vol_win" value="7" min="1" max="60" step="1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="1분 거래량÷유통주식×100 (키움 ka10001 dstr_stk). 1차 거래량 게이트">1분회전율min(%)<span class="d-block text-muted fw-normal" style="font-size:10px">유통주식 대비 · BREAKOUT_MIN_TURNOVER_1M_PCT</span></label>
|
||
<input type="number" class="form-control" id="bo_min_turnover" value="0.05" min="0" max="5" step="0.01" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="0=OFF. 켜면 직전 N봉 평균×배수 추가 검사 (HTS 300%=3)">거래량배수(보조)<span class="d-block text-muted fw-normal" style="font-size:10px">0=OFF · BREAKOUT_VOL_MULT</span></label>
|
||
<input type="number" class="form-control" id="bo_vol_mult" value="0" min="0" max="10" step="0.5" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="직전봉 등락률 하한">직전봉↑min(%)</label>
|
||
<input type="number" class="form-control" id="bo_prev_min" value="0.5" min="0" max="20" step="0.5" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="직전봉 등락률 상한">직전봉↑max(%)</label>
|
||
<input type="number" class="form-control" id="bo_prev_max" value="8.0" min="0" max="30" step="0.5" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="intrabar=B(봉내 돌파·HTS E) align=A(다음봉 시가)">진입모드</label>
|
||
<select class="form-select" id="bo_entry_mode" style="width:120px">
|
||
<option value="intrabar" selected>B intrabar</option>
|
||
<option value="align">A align</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="백테 B안 터치가 보정(%)">B슬리피지(%)</label>
|
||
<input type="number" class="form-control" id="bo_intrabar_slip" value="0" min="0" max="1" step="0.01" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="1회 매수 금액 — BREAKOUT_SLOT_MONEY">1회투자(원)</label>
|
||
<input type="number" class="form-control" id="bo_slot" value="200000" min="100000" step="100000" style="width:130px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="동시 보유 — BREAKOUT_MAX_STOCKS">동시보유(종)</label>
|
||
<input type="number" class="form-control" id="bo_max_stocks" value="20" min="1" max="50" step="1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="총 운용한도 — 수익률% 분모">총운용한도(원)</label>
|
||
<input type="number" class="form-control" id="bo_total_budget" value="2000000" min="0" step="100000" style="width:130px">
|
||
</div>
|
||
</div>
|
||
<!-- TRIGGER (SCAN vs TRIGGER — 스캘핑·모멘텀 탭과 동일 패턴) -->
|
||
<div class="row g-2 align-items-center mt-2 p-2 rounded" style="background:#0d1117;border:1px solid #21262d">
|
||
<div class="col-12"><span class="text-muted" style="font-size:11px"><b style="color:var(--accent)">TRIGGER 필터</b> — HTS breakout SCAN 통과 후 엔진 검사</span></div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="bo_skip_hts_dupes" checked>
|
||
<label class="form-check-label" for="bo_skip_hts_dupes" style="font-size:12px" title="BREAKOUT_SKIP_HTS_SCAN_DUPES — 일봉 돌파·등락·거래량 중복 생략">HTS중복스킵</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 매도/포지션 (2행) -->
|
||
<div class="row g-2 align-items-end mt-1 flex-wrap">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="fixed=고정% 손절 · atr=변동성(ATR) 비례 동적 손절">손절모드<span class="d-block text-muted fw-normal" style="font-size:10px">BREAKOUT_SL_MODE</span></label>
|
||
<select class="form-select" id="bo_sl_mode" style="width:96px" onchange="boSyncSlModeColors()">
|
||
<option value="fixed" selected>fixed(%)</option>
|
||
<option value="atr">atr(동적)</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="sl_mode=fixed 일 때 진입가 대비 이 % 하락 시 손절">손절(%)</label>
|
||
<input type="number" class="form-control" id="bo_sl" value="3.0" min="0.5" max="10" step="0.1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="ATR(RMA) 기간 — sl_mode=atr 일 때 변동성 측정 창">ATR기간<span class="d-block text-muted fw-normal" style="font-size:10px">BREAKOUT_ATR_PERIOD</span></label>
|
||
<input type="number" class="form-control" id="bo_atr_period" value="14" min="5" max="60" step="1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="손절폭(%)=ATR×배수/진입가 — sl_mode=atr 일 때">ATR손절배<span class="d-block text-muted fw-normal" style="font-size:10px">BREAKOUT_ATR_SL_MULT</span></label>
|
||
<input type="number" class="form-control" id="bo_atr_sl_mult" value="2.0" min="0.5" max="10" step="0.1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="ATR 손절 % 하한 — 휩쏘 방지(너무 타이트해지는 것 차단)">ATR손절하한%<span class="d-block text-muted fw-normal" style="font-size:10px">MIN_PCT</span></label>
|
||
<input type="number" class="form-control" id="bo_atr_sl_min" value="0.8" min="0.1" max="20" step="0.1" style="width:78px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="ATR 손절 % 상한 — 급변동 시 과대 손실 방지">ATR손절상한%<span class="d-block text-muted fw-normal" style="font-size:10px">MAX_PCT</span></label>
|
||
<input type="number" class="form-control" id="bo_atr_sl_max" value="6.0" min="0.5" max="30" step="0.1" style="width:78px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="진입가 대비 이 % 상승 시 익절">익절(%)</label>
|
||
<input type="number" class="form-control" id="bo_tp" value="10.0" min="0.5" max="20" step="0.1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="고점 대비 이 % 하락 시 트레일링 청산">트레일(%)</label>
|
||
<input type="number" class="form-control" id="bo_trail" value="1.5" min="0.1" max="5" step="0.1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="고점이 진입가×(1+이%) 도달 후에만 보조 트레일 무장. 0=즉시무장(기존). 진입 직후 본전청산 방지">트레일무장(%)</label>
|
||
<input type="number" class="form-control" id="bo_trail_arm" value="0" min="0" max="5" step="0.1" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="익절 미달 시 — 진입가 대비 이 % 이상 올라야 고점 추적(2순위 어깨)">어깨발동(%)</label>
|
||
<input type="number" class="form-control" id="bo_shoulder_smin" value="0.5" min="0.05" max="5" step="0.05" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="익절 미달 시 — 고점 대비 이 % 하락 시 2순위 어깨컷">어깨폭(%)</label>
|
||
<input type="number" class="form-control" id="bo_shoulder_scut" value="0.2" min="0.05" max="5" step="0.05" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="매수 가능 시작 (HHMM)">매수시작</label>
|
||
<input type="number" class="form-control" id="bo_time_start" value="830" min="830" max="1500" step="100" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="매수 가능 종료 (HHMM, 골든타임)">매수종료</label>
|
||
<input type="number" class="form-control" id="bo_time_end" value="1030" min="900" max="1530" step="30" style="width:80px">
|
||
</div>
|
||
<div class="col-auto d-flex align-items-end">
|
||
<div class="form-check mb-2">
|
||
<input class="form-check-input" type="checkbox" id="bo_eod_enabled" checked>
|
||
<label class="form-check-label param-row" for="bo_eod_enabled" title="ON=설정 시각 이후 보유 전량 당일청산">EOD청산</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="EOD 당일청산 시각 (HH:MM)">EOD시각</label>
|
||
<input type="text" class="form-control" id="bo_eod_hm" value="15:15" placeholder="15:15" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="0=OFF · 진입 후 N분 경과 시 시간컷 청산">최대보유(분)</label>
|
||
<input type="number" class="form-control" id="bo_max_hold" value="0" min="0" max="390" step="1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="종목당 일일 최대 진입 횟수">일일최대</label>
|
||
<input type="number" class="form-control" id="bo_max_daily" value="100" min="1" max="100" step="1" style="width:64px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="종목당 매도 후 재진입 금지(분)">쿨다운(분)</label>
|
||
<input type="number" class="form-control" id="bo_cooldown" value="30" min="0" max="240" step="5" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="당일 시가 대비 이 % 초과 상승이면 진입 금지">급등주(%)</label>
|
||
<input type="number" class="form-control" id="bo_max_chg" value="15" min="0" max="50" step="1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="이 가격 미만 종목 진입 금지(원)">최소가격</label>
|
||
<input type="number" class="form-control" id="bo_min_price" value="1000" min="0" step="100" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="저항선을 이 % 이상 '확실히' 넘겨야 진입. 선만 살짝 찌르는 가짜돌파(휩쏘) 차단. 0=OFF">돌파확인여유(%)</label>
|
||
<input type="number" class="form-control" id="bo_confirm_margin" value="0" min="0" max="5" step="0.05" style="width:90px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="돌파봉 양봉 몸통(종가-시가)/시가 가 이 % 이상이어야 진입. 도지·윗꼬리(찌르고 빠짐) 차단. 0=OFF">양봉몸통최소(%)</label>
|
||
<input type="number" class="form-control" id="bo_body_min" value="0" min="0" max="10" step="0.05" style="width:90px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="다단 래칫 — 값 있으면 단일 어깨컷 대체. 형식 수익%:컷%,… (BREAKOUT_RATCHET_TIERS). 비우면 OFF">래칫티어</label>
|
||
<input type="text" class="form-control" id="bo_ratchet" value="" placeholder="3:1.5,6:1.0" style="width:160px;font-size:12px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="종목당 1회 최대 손실(원)">1회최대손실</label>
|
||
<input type="number" class="form-control" id="bo_max_loss" value="200000" min="0" step="10000" style="width:110px">
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="bo_use_ema_f">
|
||
<label class="form-check-label" for="bo_use_ema_f" style="font-size:12px">EMA추세필터 (TRIGGER)</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2" title="이 백테 1회에만 적용 (실매 미반영). 저장 시에만 DB 반영">
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="bo_ob_filter" checked>
|
||
<label class="form-check-label" for="bo_ob_filter" style="font-size:12px">호가필터(백테)</label>
|
||
</div>
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="bo_pg_filter" checked>
|
||
<label class="form-check-label" for="bo_pg_filter" style="font-size:12px">프로그램필터(백테)</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="호가 스프레드 상한(%). kiwoom_0d 본체 재계산(6/25~)">스프레드(%)<span class="d-block text-muted fw-normal" style="font-size:10px">MAX_SPREAD</span></label>
|
||
<input type="number" step="0.01" class="form-control form-control-sm" id="bo_max_spread_pct" value="0.45">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="EMA 추세 필터 빠른 기간">EMA빠름<span class="d-block text-muted fw-normal" style="font-size:10px">fast · BREAKOUT_EMA_FAST_PERIOD</span></label>
|
||
<input type="number" class="form-control" id="bo_ema_fast" value="9" min="2" max="60" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="EMA 추세 필터 느린 기간">EMA느림<span class="d-block text-muted fw-normal" style="font-size:10px">slow · BREAKOUT_EMA_SLOW_PERIOD</span></label>
|
||
<input type="number" class="form-control" id="bo_ema_slow" value="21" min="3" max="120" step="1">
|
||
</div>
|
||
</div>
|
||
<!-- 당일 누적손익 다단트레일 — BREAKOUT_DAILY_PROFIT_TARGET_ENABLED -->
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-12"><span style="font-size:11px;color:var(--muted)">📅 다단트레일 ON이면 당일 실현손익 고점 대비 되돌릴 때 <b>신규매수만</b> 중단. DB=<code>BREAKOUT_DAILY_PROFIT_TARGET_ENABLED</code>. 이번만 끄려면 체크 해제 후 실행(봇저장 X면 DB 유지).</span></div>
|
||
<div class="col-auto">
|
||
<div class="form-check mt-3">
|
||
<input class="form-check-input" type="checkbox" id="bo_daily_profit_enabled">
|
||
<label class="form-check-label param-row" for="bo_daily_profit_enabled" title="BREAKOUT_DAILY_PROFIT_TARGET_ENABLED — 다단트레일 ON/OFF. 로드=DB, 봇저장 시 DB 반영">다단트레일</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-md-4">
|
||
<label class="form-label param-row" title="다단 트레일(ratchet식): 수익원:컷%,… — 벌수록 컷% 타이트. 비우면 단일 되돌림 사용. 예: 30000:50,100000:35,300000:25">다단규칙(수익원:컷%,…)</label>
|
||
<select class="form-select form-select-sm mb-1" id="bo_daily_trail_preset"
|
||
title="프리셋 — 고르면 아래 칸이 채워집니다(감시 스위치는 그대로)"
|
||
onchange="btApplyPreset('bo_daily_trail_tiers', this.value, false)">
|
||
<option value="__custom__">프리셋 선택…(직접입력)</option>
|
||
<option value="off">off (다단 숫자 비움)</option>
|
||
<option value="20000:40,50000:30,150000:20">보수 20000:40,50000:30,150000:20</option>
|
||
<option value="30000:50,100000:35,300000:25">중도 30000:50,100000:35,300000:25</option>
|
||
<option value="50000:60,200000:45,500000:30">공격 50000:60,200000:45,500000:30</option>
|
||
</select>
|
||
<input type="text" class="form-control" id="bo_daily_trail_tiers" value="" placeholder="30000:50,100000:35,300000:25" style="font-size:12px">
|
||
</div>
|
||
<div class="col-4 col-md-2">
|
||
<label class="form-label param-row" title="다단이 비었을 때만: 당일 실현손익 고점 대비 이 % 되돌리면 중단. 0=미사용">단일되돌림(%)</label>
|
||
<input type="number" class="form-control" id="bo_daily_trail_drop" value="0" min="0" max="90" step="5" style="width:110px">
|
||
</div>
|
||
<div class="col-4 col-md-2">
|
||
<label class="form-label param-row" title="단일 되돌림용: 이 수익(원) 이상 벌어야 감시 시작. 0이면 비활성(과민발동 방지)">발동최소수익(원)</label>
|
||
<input type="number" class="form-control" id="bo_daily_trail_arm" value="0" min="0" step="50000" style="width:130px">
|
||
</div>
|
||
<div class="col-4 col-md-2">
|
||
<label class="form-label param-row" title="trailing=고점되돌림만 / both=고정목표(운영설정)+트레일 먼저 닿는 쪽">방식</label>
|
||
<select class="form-select" id="bo_daily_profit_mode" style="width:120px">
|
||
<option value="trailing" selected>trailing</option>
|
||
<option value="both">both</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-12">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="bo_use_univ_history" checked>
|
||
<label class="form-check-label" for="bo_use_univ_history" style="font-size:12px;color:var(--muted)">
|
||
<b>저장 후보 이력</b> (<code>target_candidates_history</code>) — 체크: DB 슬롯·후보 / 해제: ws_candles 전 종목
|
||
</label>
|
||
</div>
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="bo_env_timeline">
|
||
<label class="form-check-label" for="bo_env_timeline" style="font-size:12px;color:var(--muted)" title="ON: 봉 시각별 과거 env. OFF(기본): 폼 파람 고정">
|
||
<b>env 타임라인</b> — 체크: 그 시각 DB설정 재현 / <b>해제(기본)</b>: 폼 파람으로 구간 전체
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-md-auto mt-2 d-flex gap-2 flex-wrap">
|
||
<button class="btn btn-primary px-4" onclick="runBreakoutBacktest()">🚀 백테스트 실행</button>
|
||
<button type="button" class="btn btn-outline-info px-3" onclick="saveBreakoutConfig()" title="현재 입력값을 BREAKOUT_* env 에 저장">💾 봇에 설정저장</button>
|
||
<span class="text-muted" style="font-size:11px">탐색: CLI param_search_breakout.py · 입력 기본값=최신 fast 1위</span>
|
||
</div>
|
||
</div>
|
||
<!-- 파라미터 설명 -->
|
||
<div class="mt-3 p-2 rounded" style="background:#0d1117;border:1px solid #21262d;font-size:11px;color:var(--muted)">
|
||
<b style="color:var(--accent)">📖 키움 'breakout' 조건식 ↔ 봇 룰 매핑</b>
|
||
<div class="row g-1 mt-1">
|
||
<div class="col-12 col-md-6">
|
||
<table style="width:100%;font-size:11px;border-collapse:collapse">
|
||
<tr><td style="color:#3fb950;padding:1px 6px;white-space:nowrap">진입모드 B</td><td><b>intrabar</b>=봉 안 저항 돌파·현재가 (실매·HTS E) · <b>align</b>=확정봉 후 다음봉 시가 (구 A안)</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">Lookback / VolWin</td><td>둘 다 <b>1</b>이면 키움 'breakout' 조건과 100% 동일 (직전 1봉 기준)</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">1분회전율 / 거래량배수</td><td><b>회전율</b>=유통주식 대비 1분 체결%(ka10001) 1차 · <b>거래량배수</b>=직전 N봉 평균×배수(0=OFF, HTS 300%=3)</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">직전봉 등락률</td><td>키움 조건은 <b>1~10%</b>. 0.5~15% 범위에서 튜닝 가능.</td></tr>
|
||
<tr><td style="color:#d29922;padding:1px 6px;white-space:nowrap">매수시작/종료</td><td>파라서치 fast는 <b>10:30·11:30</b> 종료 탐색. 웹에서 15:30이면 1위 조합과 불일치·수익 악화.</td></tr>
|
||
<tr><td style="color:#d29922;padding:1px 6px;white-space:nowrap">운용한도</td><td>총수익률·일평균 % 분모. 파라서치 <code>--total-budget</code> 와 동일해야 비교 가능.</td></tr>
|
||
</table>
|
||
</div>
|
||
<div class="col-12 col-md-6">
|
||
<table style="width:100%;font-size:11px;border-collapse:collapse">
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">손절/익절/트레일</td><td>봇 BREAKOUT_STOP_LOSS_PCT=-2% / TAKE_PROFIT=+5% / TRAIL=1.5% 기본</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">트레일무장(%)</td><td>고점이 진입가×(1+무장%) 도달 후에만 보조 트레일 작동. <b>0=즉시</b> · 백테 1.5% 권장(본전청산↓)</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">급등주(%)</td><td>당일 시가 대비 누적 상승률. 이 값 초과 종목은 이격 과열로 진입 금지.</td></tr>
|
||
<tr><td style="color:#58a6ff;padding:1px 6px;white-space:nowrap">일일최대 / 쿨다운</td><td>돌파는 종목당 1번/일 권장. 손절 후 30분 재진입 금지로 휩쏘 회피.</td></tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 파라미터 요약 바 (꼬리 탭과 동일) -->
|
||
<div id="bo_params_bar" class="text-muted mb-3" style="font-size:12px;display:none"></div>
|
||
|
||
<!-- 결과 영역 (첫 백테스트 성공 후 표시) -->
|
||
<div id="bo_result_area" style="display:none">
|
||
<!-- 요약 카드 — 꼬리 탭과 동일 stat-val 레이아웃 -->
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 거래</div><div class="stat-val" id="bo_total">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">승률</div><div class="stat-val" id="bo_winrate">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">순손익(수수료·세금 포함)</div><div class="stat-val" id="bo_pnl">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">Profit Factor</div><div class="stat-val" id="bo_pf">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">최대 낙폭(MDD)</div><div class="stat-val red" id="bo_mdd">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">평균 보유(분)</div><div class="stat-val" id="bo_hold">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 수익률(운용한도 대비)</div><div class="stat-val" id="bo_bot_pct">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">일평균 수익률</div><div class="stat-val" id="bo_daily_avg_pct">-</div>
|
||
</div></div>
|
||
</div>
|
||
<!-- 승/패 바 -->
|
||
<div class="card p-3 mb-3" id="bo_winbar_card" style="display:none">
|
||
<div class="d-flex justify-content-between mb-1">
|
||
<span style="color:var(--green)" id="bo_win_label">-</span>
|
||
<span style="color:var(--red)" id="bo_loss_label">-</span>
|
||
</div>
|
||
<div class="ratio-bar">
|
||
<span class="ratio-fill-g" id="bo_ratio_g" style="width:50%"></span>
|
||
<span class="ratio-fill-r" id="bo_ratio_r" style="width:50%"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row g-3">
|
||
<div class="col-12 col-lg-8">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">누적 손익 곡선 (가상)</div>
|
||
<canvas id="bo_equity_chart" height="220"></canvas>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-lg-4">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">매도 이유 분포</div>
|
||
<canvas id="bo_reason_chart" height="200"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card p-3 mt-3">
|
||
<div class="card-title mb-2">일별 손익 (가상)</div>
|
||
<canvas id="bo_daily_chart" height="150"></canvas>
|
||
</div>
|
||
|
||
<!-- 거래 내역 -->
|
||
<div class="section-title">가상 거래 내역 (최근 200건)</div>
|
||
<div id="bo_trade_context" class="mb-2 p-2 rounded" style="font-size:12px;background:var(--bg-secondary, #1c2128);color:var(--muted);display:none"></div>
|
||
<div class="trade-sort-bar mb-2" data-tbody="bo_tbody">
|
||
<span class="trade-sort-label">정렬</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn active" data-sort="exit_desc">매도 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="exit_asc">매도 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_desc">매수 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_asc">매수 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_desc">손익↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_asc">손익↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_desc">수익률↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_asc">수익률↓</button>
|
||
</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover">
|
||
<thead><tr>
|
||
<th>종목</th><th>매수시각</th><th>매도시각</th>
|
||
<th>매수가</th><th>매도가</th><th>수량</th>
|
||
<th>손익(원)</th><th>수익률%</th><th>누적손익</th><th>누적%</th>
|
||
<th>보유(분)</th><th>체결디버그</th><th>매도사유</th>
|
||
</tr></thead>
|
||
<tbody id="bo_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div><!-- bo_result_area -->
|
||
</div><!-- tab-breakout end -->
|
||
|
||
<!-- ═══ 박스권 돌파(RANGE_BREAK) 백테스트 탭 ═══════════════════════════════ -->
|
||
<div id="tab-range_break" style="display:none">
|
||
<div class="card p-3 mb-3">
|
||
<div class="row g-2 align-items-end flex-wrap">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">시작일</label>
|
||
<input type="date" class="form-control" id="rb_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">종료일</label>
|
||
<input type="date" class="form-control" id="rb_end" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="박스 형성 lookback(분)">박스Lookback(분)</label>
|
||
<input type="number" class="form-control" id="rb_box_lb" value="30" min="10" max="120" step="5" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="박스 고저폭 상한(%)">박스폭max(%)</label>
|
||
<input type="number" class="form-control" id="rb_box_max_w" value="2.5" min="0.5" max="8" step="0.1" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="박스 평균거래량 ≤ 기준×배수">횡보거래량×</label>
|
||
<input type="number" class="form-control" id="rb_setup_vol" value="0.8" min="0.3" max="1.5" step="0.1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="박스 구간 최소 음봉 수">음봉min</label>
|
||
<input type="number" class="form-control" id="rb_bear_min" value="1" min="0" max="10" step="1" style="width:64px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">VolWin</label>
|
||
<input type="number" class="form-control" id="rb_vol_win" value="7" min="1" max="60" style="width:64px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">거래량배수</label>
|
||
<input type="number" class="form-control" id="rb_vol_mult" value="2.0" min="1" max="10" step="0.5" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">1회투자(원)</label>
|
||
<input type="number" class="form-control" id="rb_slot" value="200000" min="100000" step="100000" style="width:130px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">동시보유(종)</label>
|
||
<input type="number" class="form-control" id="rb_max_stocks" value="20" min="1" max="50" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">총운용한도(원)</label>
|
||
<input type="number" class="form-control" id="rb_total_budget" value="2000000" min="0" step="100000" style="width:130px">
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 align-items-end mt-1 flex-wrap">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">손절(%)</label>
|
||
<input type="number" class="form-control" id="rb_sl" value="3.0" min="0.5" max="10" step="0.1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">익절(%)</label>
|
||
<input type="number" class="form-control" id="rb_tp" value="10.0" min="0.5" max="20" step="0.1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">트레일(%)</label>
|
||
<input type="number" class="form-control" id="rb_trail" value="1.5" min="0.1" max="5" step="0.1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">트레일무장(%)</label>
|
||
<input type="number" class="form-control" id="rb_trail_arm" value="1.5" min="0" max="5" step="0.1" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">어깨발동(%)</label>
|
||
<input type="number" class="form-control" id="rb_shoulder_smin" value="3.0" min="0.05" max="5" step="0.05" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">어깨폭(%)</label>
|
||
<input type="number" class="form-control" id="rb_shoulder_scut" value="0.5" min="0.05" max="5" step="0.05" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">매수시작</label>
|
||
<input type="number" class="form-control" id="rb_time_start" value="1030" min="900" max="1500" step="30" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">매수종료</label>
|
||
<input type="number" class="form-control" id="rb_time_end" value="1520" min="1000" max="1530" step="10" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">일일최대</label>
|
||
<input type="number" class="form-control" id="rb_max_daily" value="1" min="1" max="5" style="width:64px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">쿨다운(분)</label>
|
||
<input type="number" class="form-control" id="rb_cooldown" value="30" min="0" max="240" step="5" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">급등주(%)</label>
|
||
<input type="number" class="form-control" id="rb_max_chg" value="25" min="0" max="50" step="1" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">최소가격</label>
|
||
<input type="number" class="form-control" id="rb_min_price" value="1000" min="0" step="100" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">1회최대손실</label>
|
||
<input type="number" class="form-control" id="rb_max_loss" value="200000" min="0" step="10000" style="width:110px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<div class="form-check mt-4">
|
||
<input class="form-check-input" type="checkbox" id="rb_use_high_chase" checked>
|
||
<label class="form-check-label" for="rb_use_high_chase" style="font-size:12px">고점추격필터</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-12">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="rb_use_univ_history" checked>
|
||
<label class="form-check-label" for="rb_use_univ_history" style="font-size:12px;color:var(--muted)">
|
||
<b>저장 후보 이력</b> (<code>target_candidates_history</code>, strategy_id=RANGE_BREAK)
|
||
</label>
|
||
</div>
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="rb_env_timeline">
|
||
<label class="form-check-label" for="rb_env_timeline" style="font-size:12px;color:var(--muted)" title="ON: 봉 시각별 과거 env. OFF(기본): 폼 파람 고정">
|
||
<b>env 타임라인</b> — 체크: 그 시각 DB설정 재현 / <b>해제(기본)</b>: 폼 파람으로 구간 전체
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-md-auto mt-2 d-flex gap-2 flex-wrap">
|
||
<button class="btn btn-primary px-4" onclick="runRangeBreakBacktest()">🚀 백테스트 실행</button>
|
||
<button type="button" class="btn btn-outline-info px-3" onclick="saveRangeBreakConfig()">💾 봇에 설정저장</button>
|
||
<span class="text-muted" style="font-size:11px">탐색: CLI param_search_range_break.py</span>
|
||
</div>
|
||
</div>
|
||
<div class="mt-3 p-2 rounded" style="background:#0d1117;border:1px solid #21262d;font-size:11px;color:var(--muted)">
|
||
<b style="color:var(--accent)">📖 박스권 돌파 — SCAN vs TRIGGER</b><br>
|
||
SCAN: HTS momentum(F·G·J) · TRIGGER: N분 박스(저거래 횡보) → 양봉+거래량 폭발로 상단 돌파 · 청산: 박스실패→익절→어깨→손절→트레일
|
||
</div>
|
||
</div>
|
||
<div id="rb_params_bar" class="text-muted mb-3" style="font-size:12px;display:none"></div>
|
||
<div id="rb_result_area" style="display:none">
|
||
<!-- 요약 카드 — 꼬리/스캘핑과 동일 8칸 -->
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 거래</div><div class="stat-val" id="rb_total">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">승률</div><div class="stat-val" id="rb_winrate">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">순손익(수수료·세금 포함)</div><div class="stat-val" id="rb_pnl">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">Profit Factor</div><div class="stat-val" id="rb_pf">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">최대 낙폭(MDD)</div><div class="stat-val red" id="rb_mdd">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">평균 보유(분)</div><div class="stat-val" id="rb_hold">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 수익률(운용한도 대비)</div><div class="stat-val" id="rb_bot_pct">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">일평균 수익률</div><div class="stat-val" id="rb_daily_avg_pct">-</div>
|
||
</div></div>
|
||
</div>
|
||
<div class="card p-3 mb-3" id="rb_winbar_card" style="display:none">
|
||
<div class="d-flex justify-content-between mb-1">
|
||
<span style="color:var(--green)" id="rb_win_label">-</span>
|
||
<span style="color:var(--red)" id="rb_loss_label">-</span>
|
||
</div>
|
||
<div class="ratio-bar">
|
||
<span class="ratio-fill-g" id="rb_ratio_g" style="width:50%"></span>
|
||
<span class="ratio-fill-r" id="rb_ratio_r" style="width:50%"></span>
|
||
</div>
|
||
</div>
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-md-6"><div class="card p-3"><div class="card-title">누적손익</div><canvas id="rb_equity_chart" height="120"></canvas></div></div>
|
||
<div class="col-md-3"><div class="card p-3"><div class="card-title">청산사유</div><canvas id="rb_reason_chart" height="120"></canvas></div></div>
|
||
<div class="col-md-3"><div class="card p-3"><div class="card-title">일별손익</div><canvas id="rb_daily_chart" height="120"></canvas></div></div>
|
||
</div>
|
||
<div id="rb_trade_context" class="mb-2 p-2 rounded" style="font-size:12px;background:var(--bg-secondary, #1c2128);color:var(--muted);display:none"></div>
|
||
<div class="trade-sort-bar mb-2" data-tbody="rb_tbody">
|
||
<span class="trade-sort-label">정렬</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn active" data-sort="exit_desc">매도 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="exit_asc">매도 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_desc">매수 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_asc">매수 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_desc">손익↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_asc">손익↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_desc">수익률↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_asc">수익률↓</button>
|
||
</div>
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">거래내역</div>
|
||
<div class="table-responsive"><table class="table table-sm table-hover">
|
||
<thead><tr>
|
||
<th>종목</th><th>매수시각</th><th>매도시각</th>
|
||
<th>매수가</th><th>매도가</th><th>수량</th>
|
||
<th>손익(원)</th><th>수익률%</th><th>누적손익</th><th>누적%</th><th>보유(분)</th><th>매도사유</th>
|
||
</tr></thead>
|
||
<tbody id="rb_tbody"></tbody>
|
||
</table></div>
|
||
</div>
|
||
</div>
|
||
</div><!-- tab-range_break end -->
|
||
|
||
<!-- ═══ 모멘텀 백테스트 탭 ═══════════════════════════════════════════════ -->
|
||
<!--
|
||
[모멘텀 전략 = 키움 'scalp' 조건검색(갭상승+신고가) 추종]
|
||
- 봇: STRATEGY_MOMENTUM_ENABLED=true 로 켜면 MomentumStrategy 가독립 쓰레드로 동작.
|
||
- 청산: momentum_engine 전용 — 래칫/어깨 → 트레일 → 손절 → 익절상한(tp_max) → 장마감.
|
||
- env 키 <code>MOMENTUM_*</code> 전용.
|
||
- 백엔드: /api/backtest/momentum → momentum_engine (SCALP reversal 과 분리).
|
||
-->
|
||
<div id="tab-momentum" style="display:none">
|
||
|
||
<!-- 헤더 안내 카드 -->
|
||
<div class="card p-3 mb-3" style="border-left:4px solid var(--accent)">
|
||
<div style="font-size:14px;line-height:1.7">
|
||
<b>🌊 모멘텀 전략 = SCALP(reversal)와 분리된 별도 추세추종 전략</b><br>
|
||
<span style="color:var(--muted);font-size:12px">
|
||
• <b>진입</b>: 키움 <code>scalp</code> 조건검색(갭상승+신고가+거래량 폭증) → 봇 자체 RSI 강세/거래량 spike/양봉 검증<br>
|
||
• <b>청산</b>: <code>momentum_engine</code> — <b>래칫/어깨·트레일 우선</b>, 익절%는 <b>tp_max 상한(마지막)</b> · 손절/EOD<br>
|
||
• <b>봇 ON</b>: <code>STRATEGY_MOMENTUM_ENABLED=true</code> + <code>CONDITION_MOMENTUM_NAME/SEQ</code> 설정<br>
|
||
• env 키: <code>MOMENTUM_*</code> 전용
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 공통 기간/슬롯 -->
|
||
<div class="card p-3 mb-3">
|
||
<div class="row g-2 align-items-end">
|
||
<div class="col-auto">
|
||
<label class="form-label">시작일</label>
|
||
<input type="date" class="form-control" id="mom_start">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label">종료일</label>
|
||
<input type="date" class="form-control" id="mom_end">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="종목당 1회 매수 금액 — 백테·파라serch --slot-money 와 동일">1회투자(원)<span class="d-block text-muted fw-normal" style="font-size:10px">MOMENTUM_SLOT_MONEY</span></label>
|
||
<input type="number" class="form-control" id="mom_slot_money" value="200000" min="100000" step="100000" style="width:130px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="동시 보유 종목 수 — 백테·파라serch --max-stocks">동시보유(종)<span class="d-block text-muted fw-normal" style="font-size:10px">MOMENTUM_MAX_STOCKS</span></label>
|
||
<input type="number" class="form-control" id="mom_slots" value="20" min="1" max="50" style="width:72px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="총 운용한도 — 수익률% 분모">총운용한도(원)<span class="d-block text-muted fw-normal" style="font-size:10px">MOMENTUM_TOTAL_BUDGET_KRW</span></label>
|
||
<input type="number" class="form-control" id="mom_total_budget" value="2000000" min="0" step="100000" style="width:130px">
|
||
</div>
|
||
<div class="col-12" id="mom_portfolio_warn" style="display:none;font-size:12px;color:#f85149"></div>
|
||
<div class="col-auto" style="font-size:11px;color:var(--muted)">
|
||
※ <b>1회투자</b>=포트폴리오 매수금(돌파 탭과 동일). <b>1회최대손실÷손절%</b> 자동계산값(천만 등)과 다릅니다.
|
||
</div>
|
||
<div class="col-12 mt-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="mom_use_univ_history" checked>
|
||
<label class="form-check-label" for="mom_use_univ_history" style="font-size:12px;color:var(--muted)">
|
||
<b>저장 후보 이력</b> 사용 (<code>target_candidates_history</code>) — <b>체크(기본)</b> = DB 슬롯·후보 재현 (<code>param_search_momentum</code> 기본과 동일).
|
||
체크 해제 = 모멘텀 시뮬 유니버스 (<code>--fallback-universe</code>).
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 모멘텀 TRIGGER V4 — 돌파·눌림재돌파 패턴 OR + V4 어깨청산 (라이브 check_buy_signal_momentum_live 와 1:1) -->
|
||
<div class="card p-3 mb-3">
|
||
<div class="card-title" style="font-size:13px;color:var(--accent)">📈 모멘텀 TRIGGER V4 (추격 패턴)</div>
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-12"><span class="text-muted" style="font-size:11px"><b style="color:var(--accent)">추격 패턴</b> — 하나라도 충족 시 진입 (env <code>MOMENTUM_PATTERN_*</code>)</span></div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="mom_pat_breakout" checked>
|
||
<label class="form-check-label" for="mom_pat_breakout" style="font-size:12px" title="MOMENTUM_PATTERN_BREAKOUT">N분 고가 돌파 + 양봉 + 거래량</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="mom_pat_pullback" checked>
|
||
<label class="form-check-label" for="mom_pat_pullback" style="font-size:12px" title="MOMENTUM_PATTERN_PULLBACK">스윙고점 → 눌림 → 재돌파</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="돌파 패턴: 직전 N분 고가 돌파 관찰 구간">돌파관찰(분)<span class="d-block text-muted fw-normal" style="font-size:10px">chase lookback · MOMENTUM_CHASE_LOOKBACK_MIN</span></label>
|
||
<input type="number" class="form-control" id="mom_chase_lookback" value="10" min="3" max="60" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="눌림 패턴: 스윙고점 탐색 구간(분)">눌림관찰(분)<span class="d-block text-muted fw-normal" style="font-size:10px">pullback window · MOMENTUM_PULLBACK_LOOKBACK_MIN</span></label>
|
||
<input type="number" class="form-control" id="mom_pullback_lookback" value="15" min="5" max="60" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="눌림 최소 깊이(%) — 너무 얕은 눌림 제외">눌림min(%)<span class="d-block text-muted fw-normal" style="font-size:10px">pullback floor · MOMENTUM_PULLBACK_MIN_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_pullback_min" value="0.3" min="0" max="10" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="눌림 최대 깊이(%) — 너무 깊은 눌림 제외">눌림max(%)<span class="d-block text-muted fw-normal" style="font-size:10px">pullback cap · MOMENTUM_PULLBACK_MAX_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_pullback_max" value="3.0" min="0.5" max="15" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="눌림 구간 평균거래량 ≤ 기준×배수 (V3 setup)">눌림Vol×<span class="d-block text-muted fw-normal" style="font-size:10px">MOMENTUM_SETUP_VOL_MAX_MULT</span></label>
|
||
<input type="number" class="form-control" id="mom_setup_vol" value="0.8" min="0" max="2" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="눌림 구간 최소 음봉 수 (V3 setup)">눌림음봉min<span class="d-block text-muted fw-normal" style="font-size:10px">MOMENTUM_SETUP_BEAR_BARS_MIN</span></label>
|
||
<input type="number" class="form-control" id="mom_setup_bear" value="1" min="0" max="10" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="RSI3가 이 값 이상이어야 진입 (약세 제외)">RSI min<span class="d-block text-muted fw-normal" style="font-size:10px">RSI floor · MOMENTUM_RSI_MIN</span></label>
|
||
<input type="number" class="form-control" id="mom_rsi_min" value="50" min="30" max="95" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="RSI 상한 필터 ON 시 이 값 초과 진입 금지">RSI max<span class="d-block text-muted fw-normal" style="font-size:10px">RSI cap · MOMENTUM_RSI_MAX</span></label>
|
||
<input type="number" class="form-control" id="mom_rsi_max" value="90" min="50" max="100" step="1">
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check mt-3">
|
||
<input class="form-check-input" type="checkbox" id="mom_use_rsi_max_f">
|
||
<label class="form-check-label" for="mom_use_rsi_max_f" style="font-size:12px" title="MOMENTUM_USE_RSI_MAX_FILTER">RSI 상한필터 (기본 OFF)</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="현재봉 거래량 ≥ 직전 N봉 평균 × 이 배수">거래량배수<span class="d-block text-muted fw-normal" style="font-size:10px">vol spike · MOMENTUM_VOL_MULT</span></label>
|
||
<input type="number" class="form-control" id="mom_vol_mult" value="1.5" min="0" max="50" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="거래량 평균 계산용 직전 봉 개수">관찰봉수<span class="d-block text-muted fw-normal" style="font-size:10px">vol window · MOMENTUM_VOL_WIN</span></label>
|
||
<input type="number" class="form-control" id="mom_vol_win" value="5" min="2" max="30" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="매수 종료시각(HHMM)">매수종료<span class="d-block text-muted fw-normal" style="font-size:10px">buy cutoff · MOMENTUM_TIME_END_HM</span></label>
|
||
<input type="number" class="form-control" id="mom_time_end_buy" value="1430" min="900" max="1530" step="100">
|
||
</div>
|
||
<div class="col-12 col-md-5">
|
||
<div class="mt-1" style="font-size:11px;color:var(--muted)">
|
||
ℹ️ V4 TRIGGER: <b>돌파 OR 눌림재돌파</b> + RSI 하한 + 거래량 + (선택) EMA 추세. 청산은 V4 어깨·트레일·손절 순.
|
||
고점추격·시가과열·RSI상한은 <b>기본 OFF</b> — 필요 시 아래 방어 체크박스에서 켜세요.
|
||
<br>레거시 시가컷: <code>mom_max_from_open=999</code> 이면 비활성.
|
||
</div>
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="레거시: 당일 시가 대비 과열 상한(%). 999=비활성">시가+과열(%)<span class="d-block text-muted fw-normal" style="font-size:10px">legacy · MOMENTUM_MAX_FROM_OPEN_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_max_from_open" value="999" min="-50" max="999" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="레거시: 당일 시가 대비 약세 하한(%)">시가+약세(%)<span class="d-block text-muted fw-normal" style="font-size:10px">legacy · MOMENTUM_MIN_FROM_OPEN_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_min_from_open" value="-999" min="-999" max="50" step="1">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 청산/공통 파라미터 (momentum_engine 전용 — SCALP reversal 과 분리) -->
|
||
<div class="card p-3 mb-3">
|
||
<div class="card-title" style="font-size:13px;color:var(--accent)">🛑 청산 / 공통 (momentum_engine 전용)</div>
|
||
<p class="mb-2" style="font-size:11px;color:var(--muted)">
|
||
청산 순서: <b>래칫/어깨 → 트레일 → 손절 → 시간컷 → 금액손실컷 → 익절(tp_max 상한) → 장마감</b>
|
||
(실매 MomentumStrategy · param_search 와 동일. SCALP reversal V자 청산과 별도)
|
||
</p>
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="고정 손절률 (%)">손절(%)<span class="d-block text-muted fw-normal" style="font-size:10px">stop-loss % · MOMENTUM_STOP_LOSS_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_sl" value="1.5" min="0.1" max="5" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="고정 익절률 (%) — 어깨·트레일 이후 tp_max 상한">익절(%)<span class="d-block text-muted fw-normal" style="font-size:10px">take-profit cap · MOMENTUM_TAKE_PROFIT_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_tp" value="2.5" min="0.1" max="10" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="min(tp, tp_max) — 하드 캡, 어깨 미청산 시에만">익절상한%<span class="d-block text-muted fw-normal" style="font-size:10px">tp max cap · MOMENTUM_TP_MAX_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_tp_max" value="2.0" min="0.3" max="10" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="어깨 발동: 진입가 대비 이 % 이상 올라야 고점 추적">어깨발동%<span class="d-block text-muted fw-normal" style="font-size:10px">shoulder arm · MOMENTUM_SHOULDER_MIN_HIGH_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_smin" value="0.5" min="0" max="5" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="고점 대비 이 % 하락 시 어깨컷 (래칫 미발동 시)">어깨폭%<span class="d-block text-muted fw-normal" style="font-size:10px">shoulder cut · MOMENTUM_SHOULDER_CUT_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_scut" value="0.3" min="0.1" max="3" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="고점 대비 이 % 하락 시 트레일 청산">트레일%<span class="d-block text-muted fw-normal" style="font-size:10px">trail cut · MOMENTUM_TRAIL_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_trail" value="0" min="0" max="5" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="트레일 무장: 진입가 대비 이 % 이상 수익 후 추적">트레일무장%<span class="d-block text-muted fw-normal" style="font-size:10px">trail arm · MOMENTUM_TRAIL_ARM_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_trail_arm" value="0" min="0" max="10" step="0.1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="최대 보유 1분봉 수 (0=비활성)">최대보유(봉)<span class="d-block text-muted fw-normal" style="font-size:10px">time cut · MOMENTUM_MAX_HOLD_BARS</span></label>
|
||
<input type="number" class="form-control" id="mom_max_hold" value="0" min="0" max="120" step="1">
|
||
</div>
|
||
<div class="col-12 col-md-3">
|
||
<label class="form-label param-row" title="수익 구간별 본절 상향 (예: 0.5:0.1,1.0:0.3)">래칫티어<span class="d-block text-muted fw-normal" style="font-size:10px">ratchet tiers · MOMENTUM_RATCHET_TIERS</span></label>
|
||
<input type="text" class="form-control" id="mom_ratchet" value="" placeholder="0.5:0.1,1.0:0.3 (빈칸=OFF)">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="손익 후 같은 종목 재진입 금지(분)">쿨다운(분)<span class="d-block text-muted fw-normal" style="font-size:10px">re-entry cooldown · MOMENTUM_COOLDOWN_SEC</span></label>
|
||
<input type="number" class="form-control" id="mom_cooldown" value="10" min="0" max="60" step="5">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="매수 시작 시각(HHMM). 모멘텀 탭은 매수종료가 위 '매수종료(추격)' 따로 적용">매수시작<span class="d-block text-muted fw-normal" style="font-size:10px">buy start HHMM · MOMENTUM_TIME_START</span></label>
|
||
<input type="number" class="form-control" id="mom_time_start" value="900" min="900" max="1500" step="100">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="종목당 하루 최대 거래 횟수">일일최대매수<span class="d-block text-muted fw-normal" style="font-size:10px">max entries/day · MOMENTUM_MAX_DAILY</span></label>
|
||
<input type="number" class="form-control" id="mom_max_daily" value="5" min="1" max="20">
|
||
</div>
|
||
<div class="col-auto d-flex align-items-end">
|
||
<div class="form-check mb-2">
|
||
<input class="form-check-input" type="checkbox" id="mom_eod_enabled" checked>
|
||
<label class="form-check-label param-row" for="mom_eod_enabled" title="ON=설정 시각 이후 보유 전량 당일청산">EOD청산</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-auto d-flex align-items-end">
|
||
<div class="form-check mb-2">
|
||
<input class="form-check-input" type="checkbox" id="mom_skip_pre_sub">
|
||
<label class="form-check-label param-row" for="mom_skip_pre_sub" title="정합용: 종목 첫 ws_tick 분 이전 진입 제외 (파람 탐색은 OFF 권장)">구독전분제외<span class="d-block text-muted fw-normal" style="font-size:10px">MOMENTUM_BACKTEST_SKIP_PRE_SUBSCRIBE</span></label>
|
||
</div>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="EOD 당일청산 시각 (HH:MM)">EOD시각<span class="d-block text-muted fw-normal" style="font-size:10px">MOMENTUM_EOD_HM</span></label>
|
||
<input type="text" class="form-control" id="mom_eod_hm" value="15:25" placeholder="15:25" style="width:72px">
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 align-items-end mt-1">
|
||
<div class="col-12 col-md-2">
|
||
<label class="form-label param-row" title="OFF면 진입 방어(낙폭/고점추격/급등/최소가격)를 비활성화하고, 손절/익절/장마감청산은 유지">방어로직<span class="d-block text-muted fw-normal" style="font-size:10px">entry filters · MOMENTUM_USE_DEFENSE_FILTERS</span></label>
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="mom_use_defense" checked>
|
||
<label class="form-check-label" for="mom_use_defense">진입 방어 ON</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-md-2">
|
||
<label class="form-label param-row" title="이 백테 1회에만 적용 (실매 미반영). 저장 시에만 DB 반영">TRIGGER 필터(백테)<span class="d-block text-muted fw-normal" style="font-size:10px">호가·프로그램 · 끄고/켜고 비교용</span></label>
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="mom_ob_filter" checked>
|
||
<label class="form-check-label" for="mom_ob_filter">호가필터 ON</label>
|
||
</div>
|
||
<span id="mom_ob_filter_note" class="d-block text-muted" style="font-size:10px"></span>
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="mom_pg_filter" checked>
|
||
<label class="form-check-label" for="mom_pg_filter">프로그램필터 ON</label>
|
||
</div>
|
||
<span id="mom_pg_filter_note" class="d-block text-muted" style="font-size:10px"></span>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<label class="form-label param-row" title="호가 스프레드 상한(%). 0.45=0.45%. kiwoom_0d 본체 재계산(6/25~). 본체 없는 날은 log 판정 폴백">스프레드상한(%)<span class="d-block text-muted fw-normal" style="font-size:10px">MOMENTUM_ORDERBOOK_MAX_SPREAD_PCT</span></label>
|
||
<input type="number" step="0.01" class="form-control form-control-sm" id="mom_max_spread_pct" value="0.45">
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check mt-3">
|
||
<input class="form-check-input" type="checkbox" id="mom_use_high_chase_f">
|
||
<label class="form-check-label" for="mom_use_high_chase_f" style="font-size:12px">고점추격필터 (기본 OFF)</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check mt-3">
|
||
<input class="form-check-input" type="checkbox" id="mom_use_daily_range">
|
||
<label class="form-check-label" for="mom_use_daily_range" style="font-size:12px">당일변동필터 (기본 OFF)</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-6 col-md-2">
|
||
<div class="form-check mt-3">
|
||
<input class="form-check-input" type="checkbox" id="mom_use_ema_f" checked>
|
||
<label class="form-check-label" for="mom_use_ema_f" style="font-size:12px">EMA추세필터 (기본 ON)</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="EMA 추세 필터 빠른 기간">EMA빠름<span class="d-block text-muted fw-normal" style="font-size:10px">fast period · MOMENTUM_EMA_FAST_PERIOD</span></label>
|
||
<input type="number" class="form-control" id="mom_ema_fast" value="9" min="2" max="60" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="EMA 추세 필터 느린 기간">EMA느림<span class="d-block text-muted fw-normal" style="font-size:10px">slow period · MOMENTUM_EMA_SLOW_PERIOD</span></label>
|
||
<input type="number" class="form-control" id="mom_ema_slow" value="21" min="3" max="120" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="당일고가 대비 이 비율 이하면 진입 허용">고점추격방지<span class="d-block text-muted fw-normal" style="font-size:10px">near-high gate · HIGH_CHASE_THR</span></label>
|
||
<input type="number" class="form-control" id="mom_high_chase" value="0.96" min="0.5" max="1" step="0.01">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="당일 등락률 이 값 초과 시 진입 금지(%)">급등주필터(%)<span class="d-block text-muted fw-normal" style="font-size:10px">intraday range cap · MAX_DAILY_CHG</span></label>
|
||
<input type="number" class="form-control" id="mom_max_daily_chg" value="20" min="0" max="100" step="1">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="이 가격 미만 종목 진입 금지(원)">최소가격(원)<span class="d-block text-muted fw-normal" style="font-size:10px">min tick price · MOMENTUM_MIN_PRICE</span></label>
|
||
<input type="number" class="form-control" id="mom_min_price" value="1000" min="0" step="100">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="종목당 1회 최대 손실 한도(원)">1회최대손실(원)<span class="d-block text-muted fw-normal" style="font-size:10px">loss cap KRW · MOMENTUM_MAX_LOSS_PER_TRADE_KRW</span></label>
|
||
<input type="number" class="form-control" id="mom_max_loss_krw" value="200000" min="0" step="10000">
|
||
</div>
|
||
<div class="col-4 col-md-1">
|
||
<label class="form-label param-row" title="본절사수 시 최소 순이익 마진(%)">본절마진(%)<span class="d-block text-muted fw-normal" style="font-size:10px">breakeven buffer · MOMENTUM_MIN_PROFIT_PCT</span></label>
|
||
<input type="number" class="form-control" id="mom_min_margin" value="0.2" min="0" max="50" step="0.1">
|
||
</div>
|
||
<!-- 당일 누적손익 다단트레일 — MOMENTUM_DAILY_PROFIT_TARGET_ENABLED -->
|
||
<div class="col-12 mt-1"><span style="font-size:11px;color:var(--muted)">📅 다단트레일 ON이면 당일 실현손익 고점 대비 되돌릴 때 <b>신규매수만</b> 중단. DB=<code>MOMENTUM_DAILY_PROFIT_TARGET_ENABLED</code>. 이번만 끄려면 체크 해제 후 실행(봇저장 X면 DB 유지).</span></div>
|
||
<div class="col-auto">
|
||
<div class="form-check mt-2">
|
||
<input class="form-check-input" type="checkbox" id="mom_daily_profit_enabled">
|
||
<label class="form-check-label param-row" for="mom_daily_profit_enabled" title="MOMENTUM_DAILY_PROFIT_TARGET_ENABLED — 다단트레일 ON/OFF. 로드=DB, 봇저장 시 DB 반영">다단트레일</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-md-4">
|
||
<label class="form-label param-row" title="다단 트레일(ratchet식): 수익원:컷%,… — 벌수록 컷% 타이트. 비우면 단일 되돌림 사용. 예: 30000:50,100000:35,300000:25">다단규칙(수익원:컷%,…)</label>
|
||
<select class="form-select form-select-sm mb-1" id="mom_daily_trail_preset"
|
||
title="프리셋 — 고르면 아래 칸이 채워집니다(감시 스위치는 그대로)"
|
||
onchange="btApplyPreset('mom_daily_trail_tiers', this.value, false)">
|
||
<option value="__custom__">프리셋 선택…(직접입력)</option>
|
||
<option value="off">off (다단 숫자 비움)</option>
|
||
<option value="20000:40,50000:30,150000:20">보수 20000:40,50000:30,150000:20</option>
|
||
<option value="30000:50,100000:35,300000:25">중도 30000:50,100000:35,300000:25</option>
|
||
<option value="50000:60,200000:45,500000:30">공격 50000:60,200000:45,500000:30</option>
|
||
</select>
|
||
<input type="text" class="form-control" id="mom_daily_trail_tiers" value="" placeholder="30000:50,100000:35,300000:25" style="font-size:12px">
|
||
</div>
|
||
<div class="col-4 col-md-2">
|
||
<label class="form-label param-row" title="다단이 비었을 때만: 당일 실현손익 고점 대비 이 % 되돌리면 중단. 0=미사용">단일되돌림(%)</label>
|
||
<input type="number" class="form-control" id="mom_daily_trail_drop" value="0" min="0" max="90" step="5" style="width:110px">
|
||
</div>
|
||
<div class="col-4 col-md-2">
|
||
<label class="form-label param-row" title="단일 되돌림용: 이 수익(원) 이상 벌어야 감시 시작. 0이면 비활성(과민발동 방지)">발동최소수익(원)</label>
|
||
<input type="number" class="form-control" id="mom_daily_trail_arm" value="0" min="0" step="50000" style="width:130px">
|
||
</div>
|
||
<div class="col-4 col-md-2">
|
||
<label class="form-label param-row" title="trailing=트레일만 / both=고정목표(운영설정)+트레일 먼저 닿는 쪽">방식</label>
|
||
<select class="form-select" id="mom_daily_profit_mode" style="width:120px">
|
||
<option value="trailing" selected>trailing</option>
|
||
<option value="both">both</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-12 mt-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" id="mom_use_univ_history" checked>
|
||
<label class="form-check-label" for="mom_use_univ_history" style="font-size:12px;color:var(--muted)">
|
||
<b>저장 후보 이력</b> (<code>target_candidates_history</code>) — 체크: DB 슬롯·후보 / 해제: 시뮬 유니버스
|
||
</label>
|
||
</div>
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input" type="checkbox" id="mom_env_timeline">
|
||
<label class="form-check-label" for="mom_env_timeline" style="font-size:12px;color:var(--muted)" title="ON: 봉 시각별 과거 env. OFF(기본): 폼 파람 고정">
|
||
<b>env 타임라인</b> — 체크: 그 시각 DB설정 재현 / <b>해제(기본)</b>: 폼 파람으로 구간 전체
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-md-auto mt-2 d-flex gap-2 flex-wrap">
|
||
<button class="btn btn-primary px-4" onclick="runMomentumBacktest()">🚀 백테스트 실행</button>
|
||
<button type="button" class="btn btn-outline-info px-3" onclick="saveMomentumConfig()" title="현재 입력값을 config_momentum + env_config 에 저장 (실매 MomentumStrategy 동일 소스)">💾 봇에 설정저장</button>
|
||
<button class="btn btn-outline-info px-3" onclick="loadMomentumSearchResults()">📂 탐색결과 불러오기</button>
|
||
<span class="text-muted" style="font-size:11px">탐색: CLI param_search_momentum.py · 표에서 <b>폼반영</b>/<b>DB저장</b> · 저장 후보 이력 체크 시 <b>1~3분</b></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="mom_search_result" style="display:none" class="mb-3">
|
||
<div class="section-title">🔍 파라미터 탐색 결과 (CLI search_momentum_*.json)</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" style="font-size:12px">
|
||
<thead id="mom_search_thead"><tr><th>-</th></tr></thead>
|
||
<tbody id="mom_search_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
<p id="mom_search_hint" class="text-muted" style="display:none;font-size:11px;margin-top:8px;line-height:1.45;"></p>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="mom_params_bar" class="text-muted mb-3" style="font-size:12px;display:none"></div>
|
||
|
||
<!-- 결과 요약 (꼬리잡기 탭과 동일 레이아웃) -->
|
||
<div id="mom_result_area" style="display:none">
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 거래</div><div class="stat-val" id="mom_total">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">승률</div><div class="stat-val" id="mom_winrate">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">순손익(수수료·세금 포함)</div><div class="stat-val" id="mom_pnl">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">Profit Factor</div><div class="stat-val" id="mom_pf">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">최대 낙폭(MDD)</div><div class="stat-val red" id="mom_mdd">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">평균 보유(분)</div><div class="stat-val" id="mom_hold">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">총 수익률(운용한도 대비)</div><div class="stat-val" id="mom_bot_pct">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-3 col-lg-2"><div class="card p-3">
|
||
<div class="card-title">일평균 수익률</div><div class="stat-val" id="mom_daily_avg_pct">-</div>
|
||
</div></div>
|
||
</div>
|
||
<!-- 승/패 바 -->
|
||
<div class="card p-3 mb-3" id="mom_winbar_card" style="display:none">
|
||
<div class="d-flex justify-content-between mb-1">
|
||
<span style="color:var(--green)" id="mom_win_label">-</span>
|
||
<span style="color:var(--red)" id="mom_loss_label">-</span>
|
||
</div>
|
||
<div class="ratio-bar">
|
||
<span class="ratio-fill-g" id="mom_ratio_g" style="width:50%"></span>
|
||
<span class="ratio-fill-r" id="mom_ratio_r" style="width:50%"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row g-3">
|
||
<div class="col-12 col-lg-8">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">누적 손익 곡선 (가상)</div>
|
||
<canvas id="mom_equity_chart" height="220"></canvas>
|
||
</div>
|
||
</div>
|
||
<div class="col-12 col-lg-4">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">매도 이유 분포</div>
|
||
<canvas id="mom_reason_chart" height="200"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card p-3 mt-3">
|
||
<div class="card-title mb-2">일별 손익 (가상)</div>
|
||
<canvas id="mom_daily_chart" height="150"></canvas>
|
||
</div>
|
||
|
||
<!-- 거래 내역 (꼬리잡기와 동일 테이블) -->
|
||
<div class="section-title">가상 거래 내역 (최근 200건)</div>
|
||
<div id="mom_trade_context" class="mb-2 p-2 rounded" style="font-size:12px;background:var(--bg-secondary, #1c2128);color:var(--muted);display:none"></div>
|
||
<div class="trade-sort-bar mb-2" data-tbody="mom_tbody">
|
||
<span class="trade-sort-label">정렬</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn active" data-sort="exit_desc">매도 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="exit_asc">매도 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_desc">매수 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_asc">매수 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_desc">손익↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_asc">손익↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_desc">수익률↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_asc">수익률↓</button>
|
||
</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" id="mom_table">
|
||
<thead><tr>
|
||
<th>종목</th><th>매수시각</th><th>매도시각</th>
|
||
<th>매수가</th><th>매도가</th><th>수량</th>
|
||
<th>손익(원)</th><th>수익률%</th><th>누적손익</th><th>누적%</th>
|
||
<th>보유(분)</th><th>체결디버그</th><th>매도사유</th>
|
||
</tr></thead>
|
||
<tbody id="mom_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div><!-- mom_result_area -->
|
||
|
||
<p class="mt-2 mb-0" style="font-size:11px;color:var(--muted)">
|
||
파라미터 그리드 탐색은 CLI <code>param_search_momentum.py</code> — 웹은 페이지 로드 시
|
||
<code>/api/env/params</code> → <b>config_momentum</b> + env_config 병합값으로 입력란 자동 채움.
|
||
</p>
|
||
|
||
</div><!-- tab-momentum end -->
|
||
|
||
<!-- ═══ 홀딩 전략 탭 ═══════════════════════════════════════════════════════ -->
|
||
<div id="tab-holding" style="display:none">
|
||
|
||
<!-- 공통 기간 -->
|
||
<div class="card p-3 mb-3">
|
||
<div class="row g-2 align-items-end flex-wrap">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">시작일</label>
|
||
<input type="date" class="form-control" id="hd_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">종료일</label>
|
||
<input type="date" class="form-control" id="hd_end" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">캔들 수집 시작일</label>
|
||
<input type="date" class="form-control" id="hd_fetch_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">탐색 최소거래</label>
|
||
<input type="number" class="form-control" id="hd_min_trades" value="1" min="0" max="30" step="1" style="width:88px"
|
||
title="TOP에 올릴 최소 완료 거래 수. 0=제한 없음(느림). 1=1회라도 체결된 조합 포함">
|
||
</div>
|
||
<div class="col-auto mt-auto">
|
||
<button class="btn btn-secondary" onclick="hdLoadStocks()">🔄 종목 목록 갱신</button>
|
||
</div>
|
||
</div>
|
||
<div class="mt-2" style="font-size:11px;color:var(--muted)">
|
||
⚡ 일봉 기반 전략 | RSI 3단계 분할매수 (35/30/25) | 수익률+익절 / RSI과열 / 손절 | <code>holding_candles</code> DB 사용<br>
|
||
📋 <b>종목 목록</b>은 저장소 루트의 <code>long_term_watchlist.json</code> (<code>items[]</code> 의 <code>code</code>·<code>name</code>) 에서 불러옵니다. 편집 후 <b>종목 목록 갱신</b>을 누르세요.
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 종목 카드 목록 (JS로 동적 생성) -->
|
||
<div id="hd_stock_list" class="row g-3"></div>
|
||
|
||
<!-- 백테스트 결과 영역 (선택한 종목) -->
|
||
<div id="hd_result_area" style="display:none" class="mt-4">
|
||
<div class="section-title" id="hd_result_title">백테스트 결과</div>
|
||
<div id="hd_bt_params_echo" class="text-muted" style="font-size:11px;margin:-4px 0 10px 0;display:none;line-height:1.45"></div>
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-6 col-md-2"><div class="card p-3">
|
||
<div class="card-title">총 거래</div><div class="stat-val" id="hd_total">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-2"><div class="card p-3">
|
||
<div class="card-title">승률</div><div class="stat-val" id="hd_wr">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-2"><div class="card p-3">
|
||
<div class="card-title">순손익(수수료·세금 포함)</div><div class="stat-val" id="hd_pnl">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-2"><div class="card p-3">
|
||
<div class="card-title">Profit Factor</div><div class="stat-val" id="hd_pf">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-2"><div class="card p-3">
|
||
<div class="card-title">최대 낙폭(MDD)</div><div class="stat-val red" id="hd_mdd">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-2"><div class="card p-3">
|
||
<div class="card-title">평균 보유(일)</div><div class="stat-val" id="hd_hold">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-2"><div class="card p-3">
|
||
<div class="card-title">총 수익률(운용한도 대비)</div><div class="stat-val" id="hd_bot_pct_sum">-</div>
|
||
</div></div>
|
||
<div class="col-6 col-md-2"><div class="card p-3">
|
||
<div class="card-title">일평균 수익률</div><div class="stat-val" id="hd_daily_avg_pct">-</div>
|
||
</div></div>
|
||
</div>
|
||
<!-- Buy & Hold 비교 -->
|
||
<div class="row g-3 mb-3" id="hd_bnh_row" style="display:none">
|
||
<div class="col-12"><div class="card p-3" style="border-color:var(--accent);background:rgba(88,166,255,0.05)">
|
||
<div class="card-title" style="color:var(--accent)">📊 Buy & Hold 벤치마크 비교 <small class="text-muted">("가만히 들고 있었으면?")</small></div>
|
||
<div class="text-muted" style="font-size:11px;margin-bottom:6px">전체 구간 = 백테스트 첫 봉 종가 → 마지막 종가 (봇과 기간은 같으나 진입 시점만 다름)</div>
|
||
<div class="row g-3 mt-1">
|
||
<div class="col-6 col-md-3"><div class="card-title">봇 수익률(투자금 대비)</div><div class="stat-val" id="hd_bot_pct">-</div></div>
|
||
<div class="col-6 col-md-3"><div class="card-title">B&H 수익률(전체)</div><div class="stat-val" id="hd_bnh_pct">-</div></div>
|
||
<div class="col-6 col-md-3"><div class="card-title">B&H 손익(전체·원)</div><div class="stat-val" id="hd_bnh_pnl">-</div></div>
|
||
<div class="col-6 col-md-3"><div class="card-title">알파(봇 − 전체 B&H)</div><div class="stat-val" id="hd_alpha">-</div></div>
|
||
</div>
|
||
</div></div>
|
||
</div>
|
||
<div class="row g-3 mb-3" id="hd_bnh_aligned_row" style="display:none">
|
||
<div class="col-12"><div class="card p-3" style="border-color:#58a6ff;background:rgba(88,166,255,0.07)">
|
||
<div class="card-title" style="color:#58a6ff">📌 시뮬과 동일 구간 B&H <small class="text-muted">(MA·RSI 준비 완료 봉의 종가 → 마지막 종가)</small></div>
|
||
<div class="text-muted" style="font-size:11px;margin-bottom:6px">봇 엔진이 첫 매매 판단을 내리는 봉부터 같은 조건으로 들고 간다고 가정한 벤치마크입니다.</div>
|
||
<div class="row g-3 mt-1">
|
||
<div class="col-6 col-md-3"><div class="card-title">B&H 수익률(동일구간)</div><div class="stat-val" id="hd_bnh_aligned_pct">-</div></div>
|
||
<div class="col-6 col-md-3"><div class="card-title">B&H 손익(동일구간·원)</div><div class="stat-val" id="hd_bnh_aligned_pnl">-</div></div>
|
||
<div class="col-6 col-md-3"><div class="card-title">알파(봇 − 동일구간 B&H)</div><div class="stat-val" id="hd_alpha_aligned">-</div></div>
|
||
</div>
|
||
</div></div>
|
||
</div>
|
||
<div id="hd_candle_block" class="mb-3" style="display:none">
|
||
<div class="card p-3">
|
||
<div class="card-title mb-2">일봉·봉 목록 <small class="text-muted">(최신순 · 전일(직전 봉) 대비)</small></div>
|
||
<div class="text-muted" style="font-size:10px;margin-bottom:6px">「전일비」열은 <b>실제 시장 등락</b>입니다. RSI·MA 등 카드 숫자를 바꿔도 여기 %는 바뀌지 않습니다.</div>
|
||
<div class="table-responsive" style="max-height:440px;overflow-y:auto">
|
||
<table class="table table-sm table-hover" style="font-size:11px">
|
||
<thead><tr>
|
||
<th>일시</th><th>시가</th><th>고가</th><th>저가</th><th>종가</th>
|
||
<th>전일비(원)</th><th>전일비(%)</th>
|
||
</tr></thead>
|
||
<tbody id="hd_candle_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-12 col-lg-8"><div class="card p-3">
|
||
<div class="card-title mb-2">누적 손익 곡선</div>
|
||
<canvas id="hd_equity_chart" height="220"></canvas>
|
||
</div></div>
|
||
<div class="col-12 col-lg-4"><div class="card p-3">
|
||
<div class="card-title mb-2">매도 이유 분포</div>
|
||
<canvas id="hd_reason_chart" height="200"></canvas>
|
||
</div></div>
|
||
</div>
|
||
<!-- 파라미터 탐색 결과 -->
|
||
<div id="hd_search_result" style="display:none">
|
||
<div class="section-title">🔍 파라미터 탐색 결과 (TOP 20)</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" style="font-size:12px">
|
||
<thead id="hd_search_thead"><tr>
|
||
<th>-</th><th>손익(원)</th><th>승률</th><th>거래</th><th>PF</th><th>보유(일)</th><th>적용</th>
|
||
</tr></thead>
|
||
<tbody id="hd_search_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
<p id="hd_search_hint" class="text-muted" style="display:none;font-size:11px;margin-top:8px;line-height:1.45;"></p>
|
||
</div>
|
||
</div>
|
||
<!-- 거래 내역 -->
|
||
<div class="section-title mt-3">가상 거래 내역 (최근 200건)</div>
|
||
<div id="hd_trade_context" class="mb-2 p-2 rounded" style="font-size:12px;background:var(--bg-secondary, #1c2128);color:var(--muted);display:none"></div>
|
||
<div class="trade-sort-bar mb-2" data-tbody="hd_trade_tbody">
|
||
<span class="trade-sort-label">정렬</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn active" data-sort="exit_desc">매도 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="exit_asc">매도 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_desc">매수 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_asc">매수 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_desc">손익↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_asc">손익↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_desc">수익률↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_asc">수익률↓</button>
|
||
</div>
|
||
<div class="card p-3">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" style="font-size:12px">
|
||
<thead><tr>
|
||
<th>종목</th><th>매수일</th><th>매도일</th><th>매수가</th><th>매도가</th>
|
||
<th>수량</th><th>손익(원)</th><th>수익률%</th><th>누적손익</th><th>누적%</th><th>보유(일)</th><th>매도사유</th>
|
||
</tr></thead>
|
||
<tbody id="hd_trade_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div><!-- tab-holding end -->
|
||
|
||
<!-- ═══ 박스엔진 UPDOWN (kis_trader/engine/updown_box) ═══════════════════════════ -->
|
||
<div id="tab-updownbox" style="display:none">
|
||
|
||
<!-- 안내 -->
|
||
<div class="card p-3 mb-3">
|
||
<h6 class="mb-1">📦 박스권(횡보) 하단 되돌림 매수 — 신규 엔진</h6>
|
||
<div class="text-muted" style="font-size:12px;line-height:1.7">
|
||
조건검색 → <b>박스필터(SCAN)</b> → <code>updown_watchlist</code>(sticky, 최대 30) → 하단 근접 매수 ·
|
||
청산 스택 <b>박스이탈 → 패닉(고점-%) → 래칫(어깨컷) → 익절 → 손절</b>.<br>
|
||
글로벌 파라미터(<code>UPDOWN_BOX_*</code>)는 <b>운영설정 탭</b>에서 저장 — 여기선 백테/파라서치로 검증 후 1위를 ENV에 적용.
|
||
백테=실매 동일 엔진(<code>run_backtest_box</code>). 데이터: <code>holding_min_candles</code>(기본 15분).
|
||
</div>
|
||
</div>
|
||
|
||
<!-- watchlist 패널 -->
|
||
<div class="card p-3 mb-3">
|
||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||
<h6 class="mb-0">⭐ 관심종목 (updown_watchlist)
|
||
<small class="text-muted" id="ubx_watch_stat">— active 0 / max 0</small></h6>
|
||
<div>
|
||
<label class="form-check-label me-2" style="font-size:12px">
|
||
<input type="checkbox" id="ubx_watch_active_only" onchange="ubxLoadWatch()"> active만</label>
|
||
<button class="btn btn-sm btn-secondary" onclick="ubxLoadWatch()">🔄 새로고침</button>
|
||
</div>
|
||
</div>
|
||
<div class="row g-2 align-items-end mb-2">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" style="font-size:11px">코드</label>
|
||
<input type="text" class="form-control form-control-sm" id="ubx_add_code" placeholder="005930" style="width:110px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" style="font-size:11px">이름</label>
|
||
<input type="text" class="form-control form-control-sm" id="ubx_add_name" placeholder="(선택)" style="width:120px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" style="font-size:11px" title="박스권 바닥가. 현재가가 이 값×(1−이탈여유%) 밑으로 떨어지면 '박스이탈' 손절. 0=캔들에서 자동계산">박스하단</label>
|
||
<input type="number" class="form-control form-control-sm" id="ubx_add_low" placeholder="0=자동" style="width:100px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" style="font-size:11px" title="박스권 천장가. 0=캔들에서 자동계산">박스상단</label>
|
||
<input type="number" class="form-control form-control-sm" id="ubx_add_high" placeholder="0=자동" style="width:100px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-sm btn-success" onclick="ubxAddWatch()" title="같은 코드면 덮어쓰기(수정). 박스하단/상단 0이면 엔진이 자동 계산">➕ 추가/수정</button>
|
||
</div>
|
||
</div>
|
||
<div class="text-muted mb-2" style="font-size:11px">
|
||
💡 박스하단/상단은 차트의 횡보 바닥·천장 가격. <b>모르면 0</b>으로 두면 엔진이 캔들에서 자동 계산합니다.
|
||
같은 코드로 다시 [추가/수정]하면 덮어써집니다(행의 <b>수정</b> 버튼이 값을 폼에 불러옵니다).
|
||
</div>
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" style="font-size:12px">
|
||
<thead><tr>
|
||
<th>코드</th><th>이름</th><th>상태</th><th>소스</th><th>박스하단</th><th>박스상단</th>
|
||
<th>점수</th><th>추가일</th><th>최근신호</th><th></th>
|
||
</tr></thead>
|
||
<tbody id="ubx_watch_tbody"><tr><td colspan="10" class="text-muted">로딩…</td></tr></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 백테/파라서치 입력 -->
|
||
<div class="card p-3 mb-3">
|
||
<div class="row g-2 align-items-end flex-wrap">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="단일 백테용 / 파라서치는 codes(쉼표) 또는 watchlist">종목코드</label>
|
||
<input type="text" class="form-control" id="ubx_code" placeholder="005930 (목록에서 선택/직접입력)" style="width:230px"
|
||
list="ubx_stock_options" onchange="ubxLoadStockCfg(this.value)" oninput="ubxLoadStockCfg(this.value)">
|
||
<datalist id="ubx_stock_options"></datalist>
|
||
<div id="ubx_stock_cfg_badge" class="mt-1" style="font-size:11px"></div>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">분봉(TF)</label>
|
||
<select class="form-select" id="ubx_tf" style="width:90px">
|
||
<option value="15" selected>15분</option>
|
||
<option value="60">60분</option>
|
||
<option value="5">5분</option>
|
||
<option value="3">3분</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">시작일</label>
|
||
<input type="date" class="form-control" id="ubx_start" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">종료일</label>
|
||
<input type="date" class="form-control" id="ubx_end" style="width:150px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-info" onclick="ubxRunBacktest()">📊 박스 백테</button>
|
||
</div>
|
||
</div>
|
||
|
||
<hr class="my-2" style="border-color:#30363d">
|
||
|
||
<div class="row g-2 align-items-end flex-wrap">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="박스 lookback (UPDOWN_BOX_LOOKBACK_BARS)">박스봉</label>
|
||
<input type="number" class="form-control" id="ubx_lookback_bars" step="1" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="박스 최대 높이% (UPDOWN_BOX_RANGE_MAX_PCT)">범위상한%</label>
|
||
<input type="number" class="form-control" id="ubx_range_max_pct" step="0.5" style="width:90px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="밴드폭 상한% (UPDOWN_BOX_BB_BW_MAX)">밴드폭%</label>
|
||
<input type="number" class="form-control" id="ubx_bb_bw_max" step="0.5" style="width:90px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="MA 기울기 허용% (UPDOWN_BOX_MA_SLOPE_TOL_PCT)">기울기%</label>
|
||
<input type="number" class="form-control" id="ubx_ma_slope_tol_pct" step="0.1" style="width:90px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="하단 근접 진입% (UPDOWN_BOX_NEAR_LOW_PCT)">하단근접%</label>
|
||
<input type="number" class="form-control" id="ubx_near_low_pct" step="0.1" style="width:90px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="익절% (UPDOWN_BOX_TP_PCT)">익절%</label>
|
||
<input type="number" class="form-control" id="ubx_tp_pct" step="0.5" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="하드손절% (UPDOWN_BOX_STOP_LOSS_PCT)">손절%</label>
|
||
<input type="number" class="form-control" id="ubx_stop_loss_pct" step="0.1" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="박스이탈 여유% (UPDOWN_BOX_BREACH_BUFFER_PCT)">이탈여유%</label>
|
||
<input type="number" class="form-control" id="ubx_breach_buffer_pct" step="0.1" style="width:90px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="패닉 고점대비% (UPDOWN_PANIC_FROM_HIGH_PCT)">패닉%</label>
|
||
<input type="number" class="form-control" id="ubx_panic_from_high_pct" step="0.5" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="래칫 무장+% (UPDOWN_BOX_SHOULDER_MIN_HIGH_PCT)">어깨발동%</label>
|
||
<input type="number" class="form-control" id="ubx_shoulder_min_high_pct" step="0.1" style="width:90px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="래칫 컷 고점대비-% (UPDOWN_BOX_SHOULDER_CUT_PCT)">어깨폭%</label>
|
||
<input type="number" class="form-control" id="ubx_shoulder_cut_pct" step="0.1" style="width:90px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="다단 래칫 — 값 있으면 단일 어깨컷 대체. 형식 수익%:컷%,… (UPDOWN_BOX_RATCHET_TIERS)">다단래칫(수익%:컷%,…)</label>
|
||
<input type="text" class="form-control" id="ubx_ratchet_tiers" placeholder="2:1.5,5:1.0" style="width:160px;font-size:12px"
|
||
oninput="ubxSyncRatchetShoulderColors&&ubxSyncRatchetShoulderColors()">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="보유한도 봉 (UPDOWN_BOX_MAX_HOLD_BARS)">보유한도</label>
|
||
<input type="number" class="form-control" id="ubx_max_hold_bars" step="1" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="ON 이면 박스 상단을 위로 돌파한 뒤엔 익절(tp)을 끄고 래칫(트레일)만으로 추세를 끝까지 추종. 횡보 중엔 평소대로 tp로 짧게. (UPDOWN_BOX_BREAKOUT_FOLLOW)">돌파추종</label>
|
||
<select class="form-control" id="ubx_breakout_follow" style="width:90px">
|
||
<option value="0">OFF</option>
|
||
<option value="1">ON(추종)</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-sm btn-outline-secondary" onclick="ubxLoadCfg()" title="운영설정 UPDOWN_BOX_* 글로벌 현재값 불러오기">글로벌 불러오기</button>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-sm btn-outline-primary" onclick="ubxSaveStockCfg()" title="위 [종목코드]의 종목별 파라미터로 현재 입력값을 고정 저장(핀). 실매·백테 모두 이 종목엔 이 값 적용">💾 종목설정 저장</button>
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-sm btn-outline-warning" onclick="ubxClearStockCfg()" title="이 종목의 종목별 핀 해제 → 글로벌로 복귀">↩ 글로벌복귀</button>
|
||
</div>
|
||
</div>
|
||
|
||
<hr class="my-2" style="border-color:#30363d">
|
||
|
||
<div class="row g-2 align-items-end flex-wrap">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row" title="파라서치 종목 — 쉼표 구분. 비우면 위 종목코드 1개">탐색 종목(codes)</label>
|
||
<input type="text" class="form-control" id="ubx_codes" placeholder="005930,000660,005380" style="width:280px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-check-label" style="font-size:12px">
|
||
<input type="checkbox" id="ubx_from_watchlist"> watchlist active 사용</label>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">모드</label>
|
||
<select class="form-select" id="ubx_mode" style="width:100px">
|
||
<option value="fast" selected>fast(4축)</option>
|
||
<option value="full">full(7축)</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">최소거래</label>
|
||
<input type="number" class="form-control" id="ubx_min_trades" value="3" min="0" step="1" style="width:80px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-warning" onclick="ubxRunParamSearch()">🔍 파라미터 탐색</button>
|
||
</div>
|
||
</div>
|
||
<div class="mt-1 text-muted" style="font-size:11px" id="ubx_status"></div>
|
||
</div>
|
||
|
||
<!-- 결과: 요약 -->
|
||
<div class="card p-3 mb-3" id="ubx_summary_card" style="display:none">
|
||
<h6 class="mb-2">백테 요약 <small class="text-muted" id="ubx_summary_sub"></small></h6>
|
||
<div id="ubx_summary"></div>
|
||
</div>
|
||
|
||
<!-- 결과: 파라서치 top -->
|
||
<div class="card p-3 mb-3" id="ubx_ps_card" style="display:none">
|
||
<h6 class="mb-2">파라서치 상위 <small class="text-muted" id="ubx_ps_sub"></small></h6>
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" style="font-size:12px">
|
||
<thead><tr>
|
||
<th>#</th><th>초과수익 α%</th><th>합산손익%</th><th>B&H%</th><th>PF</th><th>승률%</th><th>거래</th><th>파라미터</th><th></th>
|
||
</tr></thead>
|
||
<tbody id="ubx_ps_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 결과: 거래 목록 (다른 전략과 동일한 공통 컴포넌트 renderVirtualTrades 사용) -->
|
||
<div class="card p-3 mb-3" id="ubx_trades_card" style="display:none">
|
||
<h6 class="mb-2">거래 목록 <small class="text-muted" id="ubx_trades_sub"></small></h6>
|
||
<div id="ubx_trade_context" class="mb-2 p-2 rounded" style="font-size:12px;background:var(--bg-secondary, #1c2128);color:var(--muted);display:none"></div>
|
||
<div class="trade-sort-bar mb-2" data-tbody="ubx_trades_tbody">
|
||
<span class="trade-sort-label">정렬</span>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn active" data-sort="exit_desc">매도 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="exit_asc">매도 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_desc">매수 최신</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="buy_asc">매수 오래된순</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_desc">손익↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="pnl_asc">손익↓</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_desc">수익률↑</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary trade-sort-btn" data-sort="rate_asc">수익률↓</button>
|
||
</div>
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" style="font-size:12px">
|
||
<thead><tr>
|
||
<th>종목</th><th>매수시각</th><th>매도시각</th>
|
||
<th>매수가</th><th>매도가</th><th>수량</th>
|
||
<th>손익(원)</th><th>수익률%</th><th>누적손익</th><th>누적%</th><th>보유(봉)</th><th>청산사유</th>
|
||
</tr></thead>
|
||
<tbody id="ubx_trades_tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- tab-updownbox end -->
|
||
|
||
<!-- ═══ 하락매수 Updow (kis_trader/strategies/updow_buy) ═════════════════════════ -->
|
||
<div id="tab-updow" style="display:none">
|
||
<!-- ═══ 영구구독 관리 (국내 WS H0STCNT0 + 해외 WS HDFSCNT0) ═══ -->
|
||
<div class="card p-3 mb-3">
|
||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||
<h6 class="mb-0">📡 영구구독 관리 <small class="text-muted">(KR=국내 WS · US=해외 WS)</small></h6>
|
||
<button class="btn btn-sm btn-outline-secondary" type="button" onclick="permLoad()">새로고침</button>
|
||
</div>
|
||
<div class="row g-2 align-items-end flex-wrap mb-2">
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">코드</label>
|
||
<input class="form-control" id="perm_code" style="width:110px" placeholder="QQQM/005930">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">시장</label>
|
||
<select class="form-select" id="perm_market" style="width:90px" onchange="permOnMarket()">
|
||
<option value="KR">KR</option>
|
||
<option value="US">US</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">거래소</label>
|
||
<select class="form-select" id="perm_exch" style="width:100px">
|
||
<option value="KRX">KRX</option>
|
||
<option value="NASD">NASD</option>
|
||
<option value="NYSE">NYSE</option>
|
||
<option value="AMEX">AMEX</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">심볼</label>
|
||
<input class="form-control" id="perm_symbol" style="width:100px" placeholder="(기본=코드)">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">TF분</label>
|
||
<input class="form-control" id="perm_tf" type="number" value="15" style="width:70px">
|
||
</div>
|
||
<div class="col-auto">
|
||
<label class="form-label param-row">메모</label>
|
||
<input class="form-control" id="perm_note" style="width:140px" placeholder="용도">
|
||
</div>
|
||
<div class="col-auto">
|
||
<button class="btn btn-sm btn-primary" type="button" onclick="permSave()">추가/수정</button>
|
||
</div>
|
||
</div>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-bordered align-middle mb-0" style="font-size:.85rem">
|
||
<thead><tr>
|
||
<th>코드</th><th>시장</th><th>거래소</th><th>심볼</th><th>TF</th><th>tr_key</th><th>ON</th><th>메모</th><th></th>
|
||
</tr></thead>
|
||
<tbody id="perm_tbody"><tr><td colspan="9" class="text-muted">로딩…</td></tr></tbody>
|
||
</table>
|
||
</div>
|
||
<small class="text-muted">⚠️ 해외(US) 실시간시세는 KIS '해외 실시간시세' 미신청 시 15분 지연. tr_key=D+거래소(NAS/NYS/AMS)+심볼</small>
|
||
</div>
|
||
|
||
</div><!-- tab-updow end -->
|
||
|
||
</div><!-- container end -->
|
||
|
||
<script src="{{ url_for('static', filename='js/backtest.js') }}"></script>
|
||
</body>
|
||
</html> |