Files
kis_bot/static/css/backtest.css
Your Name 0780b2cdd0 feat: Enhance Optuna integration and logging for backtesting framework
Changes:
- Added new API endpoints for continuing and confirming Optuna jobs, allowing for better management of ongoing studies.
- Introduced detailed logging for tick feed tracking and order book processing, improving traceability of vendor performance during backtests.
- Updated database schema to include new fields for managing Optuna study results, enhancing the ability to track study progress and outcomes.
- Refactored existing functions to utilize the new logging and tracking features, ensuring consistency across the backtesting framework.

Impact:
- These enhancements improve the robustness and transparency of the Optuna backtesting process, facilitating better analysis and optimization of trading strategies.
2026-08-21 19:05:23 +09:00

340 lines
13 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ── Bootstrap dark-theme 변수 오버라이드 ── */
[data-bs-theme="dark"] {
--bs-body-bg: #0d1117;
--bs-body-color: #e6edf3;
--bs-border-color: #21262d;
--bs-secondary-bg: #161b22;
--bs-tertiary-bg: #161b22;
--bs-table-color: #e6edf3;
--bs-table-bg: transparent;
--bs-table-border-color: #21262d;
--bs-table-hover-bg: rgba(88,166,255,.07);
--bs-table-hover-color: #e6edf3;
--bs-form-control-bg: #21262d;
--bs-form-control-color: #e6edf3;
--bs-input-bg: #21262d;
--bs-input-color: #e6edf3;
--bs-link-color: #58a6ff;
}
:root {
--bg: #0d1117; --surface: #161b22; --border: #21262d;
--text: #e6edf3; --muted: #8b949e; --accent: #58a6ff;
--green: #3fb950; --red: #f85149; --yellow: #d29922; --purple: #bc8cff;
}
* { box-sizing: border-box; }
body { background: var(--bg) !important; color: var(--text) !important;
font-family: 'Segoe UI', sans-serif; font-size: 14px; }
/* 네비 / 탭 */
.navbar-brand { font-weight: 700; letter-spacing: 1px; color: var(--accent) !important; }
.nav-tabs .nav-link { color: var(--muted); border: none; padding: 10px 20px; }
.nav-tabs .nav-link.active { color: var(--accent); border-bottom: 2px solid var(--accent); background: transparent; }
.nav-tabs { border-bottom: 1px solid var(--border); }
/* 카드 */
.card { background: var(--surface) !important; border: 1px solid var(--border) !important; border-radius: 10px; }
.card-title { font-size: 12px; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 4px; }
.stat-val { font-size: 26px; font-weight: 700; color: var(--text); }
.stat-val.green { color: var(--green) !important; }
.stat-val.red { color: var(--red) !important; }
/* 폼 컨트롤 */
.form-control, .form-select, input[type=number], input[type=date] {
background: #21262d !important; border: 1px solid #30363d !important;
color: var(--text) !important; border-radius: 6px;
}
.form-control:focus, .form-select:focus, input:focus {
background: #21262d !important; color: var(--text) !important;
border-color: var(--accent) !important; box-shadow: none !important;
}
.btn-primary { background: var(--accent) !important; border: none !important; font-weight: 600; color: #0d1117 !important; }
.btn-primary:hover { background: #79b8ff !important; }
label, .form-label { color: var(--muted) !important; font-size: 12px; }
/* 테이블 — Bootstrap dark theme가 대부분 처리, 남은 것만 보정 */
.table { font-size: 12px; }
.table td, .table th { color: var(--text) !important; border-color: var(--border) !important; padding: 6px 10px; }
.table thead th { color: var(--muted) !important; }
.table-responsive { max-height: 420px; overflow-y: auto; }
.table-responsive::-webkit-scrollbar { width: 5px; }
.table-responsive::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
/* 배지 */
.badge-win { background: rgba(63,185,80,.2); color: var(--green) !important; padding: 2px 8px; border-radius: 20px; }
.badge-loss { background: rgba(248,81,73,.2); color: var(--red) !important; padding: 2px 8px; border-radius: 20px; }
.badge-flat { background: rgba(210,153,34,.15); color: var(--yellow) !important; padding: 2px 8px; border-radius: 20px; }
.badge-reason { background: rgba(88,166,255,.12); color: #8b949e !important; padding: 2px 8px; border-radius: 20px; font-size: 11px; white-space: nowrap; }
.trade-sort-bar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 12px; }
.trade-sort-bar .trade-sort-label { color: var(--muted); margin-right: 4px; font-weight: 600; }
.trade-sort-btn { font-size: 11px !important; padding: 2px 8px !important; }
.trade-sort-btn.active { background: rgba(88,166,255,.22) !important; border-color: var(--accent) !important; color: var(--accent) !important; }
/* 스피너 */
.spin-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.55);
z-index: 9999; align-items: center; justify-content: center; }
.spin-overlay.show { display: flex; }
.trade-db-chart-overlay {
position: fixed; inset: 0; z-index: 10050;
background: rgba(0,0,0,.65);
align-items: center; justify-content: center;
padding: 16px;
}
.trade-db-chart-panel {
width: min(960px, 96vw);
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 14px 16px 12px;
box-shadow: 0 12px 40px rgba(0,0,0,.45);
}
.trade-ext-links a { color: var(--accent); text-decoration: none; }
.trade-ext-links a:hover { text-decoration: underline; }
.spinner { width: 48px; height: 48px; border: 4px solid var(--border);
border-top-color: var(--accent); border-radius: 50%; animation: spin .9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
/* 기타 */
canvas { background: transparent !important; }
.section-title { font-size: 13px; font-weight: 600; color: var(--muted);
text-transform: uppercase; letter-spacing: 1px; margin: 24px 0 12px; }
input[type=radio] { accent-color: var(--accent); }
.ratio-bar { height: 8px; border-radius: 4px; background: var(--border); margin-top: 4px; overflow: hidden; }
.ratio-fill-g { height: 100%; border-radius: 4px 0 0 4px; background: var(--green); display: inline-block; }
.ratio-fill-r { height: 100%; border-radius: 0 4px 4px 0; background: var(--red); display: inline-block; float: right; }
.text-pnl-pos { color: var(--green) !important; }
.text-pnl-neg { color: var(--red) !important; }
/* 보유·실거래 보유중 — 업비트식 틱 플래시 (표시만) */
.live-quote-flash-up {
animation: liveQuoteFlashUp 0.45s ease;
}
.live-quote-flash-down {
animation: liveQuoteFlashDown 0.45s ease;
}
@keyframes liveQuoteFlashUp {
from { background-color: rgba(63, 185, 80, 0.35); }
to { background-color: transparent; }
}
@keyframes liveQuoteFlashDown {
from { background-color: rgba(248, 81, 73, 0.35); }
to { background-color: transparent; }
}
.live-quote-stale { opacity: 0.55; }
/* 파라미터 설명 툴팁 */
.param-help { font-size: 10px; color: var(--muted); margin-top: 2px; }
/* 운영 설정 탭 — 최대 2열, 위에서 아래로 읽기 */
.lc-field-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px 20px;
max-width: 920px;
}
@media (max-width: 700px) {
.lc-field-grid { grid-template-columns: 1fr; }
}
.lc-field {
min-width: 0;
}
.lc-field input.form-control {
max-width: 100%;
}
.lc-field-label { font-size: 12px; color: var(--muted); display: block; margin-bottom: 2px; line-height: 1.35; }
.lc-field-hint { font-size: 10px; color: var(--muted); margin-top: 2px; line-height: 1.35; }
.lc-field-tbl { font-size: 10px; color: #58a6ff; margin-left: 4px; }
.lc-field-key { font-size: 10px; color: #8b949e; margin-left: 4px; font-weight: normal; }
/* 키/테이블 태그: 평소엔 숨기고 호버 시만 — 라벨·입력에 시선 집중 */
.lc-field-key,
.lc-field-tbl {
opacity: 0.35;
transition: opacity 0.12s ease;
}
.lc-field:hover .lc-field-key,
.lc-field:hover .lc-field-tbl,
.lc-field:focus-within .lc-field-key,
.lc-field:focus-within .lc-field-tbl {
opacity: 1;
}
/* 카테고리 안 전략·주제 구역 */
.lc-strat-stack {
display: flex;
flex-direction: column;
gap: 12px;
max-width: 960px;
}
.lc-strat-block {
border: 1px solid var(--border);
border-left-width: 4px;
border-radius: 8px;
padding: 10px 12px 12px;
background: rgba(22, 27, 34, 0.55);
}
.lc-strat-head {
display: flex;
align-items: baseline;
gap: 8px;
margin-bottom: 8px;
padding-bottom: 5px;
border-bottom: 1px solid var(--border);
font-size: 13px;
font-weight: 650;
letter-spacing: 0.02em;
color: var(--text);
}
.lc-strat-head .lc-strat-sid {
font-size: 11px;
font-weight: 500;
color: var(--muted);
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.lc-topic-head {
font-size: 12px;
font-weight: 600;
color: var(--muted);
margin: 4px 0 8px;
padding-left: 2px;
}
.lc-strat-common { border-left-color: #6e7681; }
.lc-strat-short { border-left-color: #39d2c0; }
.lc-strat-momentum { border-left-color: #d29922; }
.lc-strat-breakout { border-left-color: #3fb950; }
.lc-strat-updow { border-left-color: #58a6ff; }
.lc-strat-scalp { border-left-color: #8b949e; }
.lc-strat-range_break { border-left-color: #79c0ff; }
.lc-strat-dbband { border-left-color: #f0883e; }
.lc-strat-other { border-left-color: #bc8cff; }
.lc-strat-topic { border-left-color: #6e7681; }
.lc-strat-short .lc-strat-head { color: #39d2c0; }
.lc-strat-momentum .lc-strat-head { color: #d29922; }
.lc-strat-breakout .lc-strat-head { color: #3fb950; }
.lc-strat-updow .lc-strat-head { color: #58a6ff; }
.lc-strat-scalp .lc-strat-head { color: #c9d1d9; }
.lc-strat-common .lc-strat-head { color: #8b949e; }
/* OHLC 폴백 — 정합 위험 (절대규칙: 틱 모드에서 숫자 변조 금지). UI만 경고 표시 */
.lc-field-danger,
.bt-ohlc-fallback-danger {
background: rgba(248, 81, 73, 0.18) !important;
border: 1px solid rgba(248, 81, 73, 0.65) !important;
border-radius: 6px;
padding: 6px 10px !important;
margin: 4px 0;
}
.lc-field-danger .lc-field-label,
.bt-ohlc-fallback-danger label,
.bt-ohlc-fallback-danger .form-check-label {
color: #ff7b72 !important;
font-weight: 600;
}
.lc-field-danger .lc-field-hint,
.bt-ohlc-fallback-danger .bt-ohlc-fallback-warn {
color: #ffa198 !important;
font-size: 11px;
}
.ob-stamp { font-size: 10px; line-height: 1.35; }
.ob-stamp-danger {
color: #f85149 !important;
font-weight: 700;
}
.ob-metric-ok { color: var(--green) !important; font-weight: 600; }
.ob-metric-bad { color: var(--red) !important; font-weight: 600; }
/* 거래표 — 정합 예외 경로(OHLC폴백·틱공백EOD 등) */
tr.trade-row-parity-ex {
background: rgba(248, 81, 73, 0.16) !important;
position: relative;
}
tr.trade-row-parity-ex td {
border-color: rgba(248, 81, 73, 0.35) !important;
}
td.trade-name-cell { position: relative; padding-top: 14px !important; }
.parity-cause-corner {
position: absolute;
top: 2px;
right: 4px;
font-size: 9px;
font-weight: 700;
color: #ff7b72;
background: rgba(248, 81, 73, 0.25);
border: 1px solid rgba(248, 81, 73, 0.55);
border-radius: 3px;
padding: 0 4px;
line-height: 1.4;
white-space: nowrap;
max-width: 110px;
overflow: hidden;
text-overflow: ellipsis;
}
/* Optuna 전역/탭 프로그레스 */
.optuna-nav-bar { min-width: 180px; }
.optuna-nav-bar.d-none { display: none !important; }
.optuna-prog-track {
height: 6px; border-radius: 4px; background: var(--border); overflow: hidden;
}
.optuna-prog-fill {
height: 100%; border-radius: 4px; background: var(--accent);
transition: width .35s ease;
}
.optuna-prog-fill.is-done { background: var(--green); }
.optuna-prog-fill.is-error { background: var(--red); }
.optuna-prog-fill.is-post { background: #d29922; }
.opt-join-overlay {
display: none;
position: fixed;
inset: 0;
z-index: 2200;
background: rgba(0, 0, 0, 0.62);
align-items: center;
justify-content: center;
padding: 16px;
}
.opt-join-overlay.is-open { display: flex; }
.opt-join-panel {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
max-width: 860px;
width: 100%;
max-height: 90vh;
overflow: auto;
padding: 16px;
}
.opt-join-pre {
font-size: 11px;
white-space: pre-wrap;
word-break: break-all;
background: #0d1117;
border: 1px solid var(--border);
border-radius: 6px;
padding: 10px;
color: var(--text);
max-height: 220px;
overflow: auto;
}
/* 오늘 운영 — 조건검색 이력(키움/LS) */
.dash-univ-table .dash-univ-src-kiwoom { color: #58a6ff; font-weight: 600; }
.dash-univ-table .dash-univ-src-kis { color: #3fb950; font-weight: 600; }
.dash-univ-table .dash-univ-src-ls { color: #bc8cff; font-weight: 600; }
.dash-univ-table tr.dash-univ-group-start td { border-top: 2px solid var(--border); }
.dash-univ-table tr.dash-univ-stale td { opacity: 0.85; }
/* 전략×2행(10행)이 잘리지 않도록 — 전역 .table-responsive 420px 오버라이드 */
.dash-univ-wrap.table-responsive { max-height: none; overflow-y: visible; }
/* 오늘 운영 — 전략별 키움/LS 매매 두 줄 */
.dash-ops-table .dash-univ-src-kiwoom { color: #58a6ff; font-weight: 600; }
.dash-ops-table .dash-univ-src-kis { color: #3fb950; font-weight: 600; }
.dash-ops-table .dash-univ-src-ls { color: #bc8cff; font-weight: 600; }
.dash-ops-table tr.dash-broker-head td {
background: rgba(88, 166, 255, 0.08);
font-weight: 700;
border-top: 2px solid var(--border);
color: var(--text);
}
.dash-ops-table tr.dash-broker-head.dash-broker-kis td { background: rgba(63, 185, 80, 0.08); }
.dash-ops-table tr.dash-ops-group-start td { border-top: 2px solid var(--border); }
.dash-ops-table tr.dash-ops-inactive td { opacity: 0.55; }