Files
kis_bot/static/css/backtest.css
Your Name 36a3e2b4a1 feat: Enhance trading system with new permanent subscription features and order book management
Changes:
- Added a new API endpoint for managing permanent subscriptions, allowing users to enable or disable subscriptions dynamically.
- Implemented a function to fill candle data from Kiwoom, ensuring that only relevant data is inserted into the database.
- Introduced a mechanism to handle master subscription states, improving the management of subscription statuses.
- Updated the database schema to include new fields for managing subscription states and order book filtering.

Impact:
- These enhancements improve the flexibility and reliability of the trading system, allowing for better management of subscriptions and order book data, while reducing the risk of data inconsistencies.

히스토리 align 제거 븅신같은 초기설계 아예 제거
진입모드에 구멍메움
호가진입을 켜도 호가가 안들어올때 호가 안보고 그냥 사버림
2026-08-15 23:01:14 +09:00

296 lines
12 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); }
/* 오늘 운영 — 조건검색 이력(키움/LS) */
.dash-univ-table .dash-univ-src-kiwoom { color: #58a6ff; 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-ls { color: #bc8cff; font-weight: 600; }
.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; }