first commit
This commit is contained in:
266
templates/pages/autotrade.html
Normal file
266
templates/pages/autotrade.html
Normal file
@@ -0,0 +1,266 @@
|
||||
{{ template "base.html" . }}
|
||||
|
||||
{{ define "sidebar" }}{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="space-y-5">
|
||||
|
||||
<!-- 페이지 제목 + 상태바 -->
|
||||
<div class="flex items-center justify-between flex-wrap gap-3">
|
||||
<h1 class="text-xl font-bold text-gray-800">자동매매</h1>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span id="statusDot" class="w-3 h-3 rounded-full bg-gray-300"></span>
|
||||
<span id="statusText" class="text-sm font-medium text-gray-600">중지</span>
|
||||
</div>
|
||||
<button onclick="startEngine()" id="btnStart"
|
||||
class="px-4 py-2 text-sm font-medium bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
|
||||
시작
|
||||
</button>
|
||||
<button onclick="stopEngine()" id="btnStop"
|
||||
class="px-4 py-2 text-sm font-medium bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition-colors">
|
||||
중지
|
||||
</button>
|
||||
<button onclick="emergencyStop()"
|
||||
class="px-4 py-2 text-sm font-medium bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors">
|
||||
⚠ 긴급청산
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 요약 카드 3개 -->
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-4">
|
||||
<p class="text-xs text-gray-500 mb-1">진행중 포지션</p>
|
||||
<p id="statActivePos" class="text-2xl font-bold text-gray-800">0</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-4">
|
||||
<p class="text-xs text-gray-500 mb-1">오늘 매매 횟수</p>
|
||||
<p id="statTradeCount" class="text-2xl font-bold text-gray-800">0</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-4">
|
||||
<p class="text-xs text-gray-500 mb-1">오늘 손익</p>
|
||||
<p id="statTotalPL" class="text-2xl font-bold text-gray-800">0원</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 감시 소스 설정 -->
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-4">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-sm font-semibold text-gray-800">감시 소스 설정</h2>
|
||||
<span class="text-xs text-gray-400">매수 신호를 가져올 종목 범위를 선택하세요</span>
|
||||
</div>
|
||||
<div class="flex flex-col lg:flex-row gap-4">
|
||||
<!-- 체결강도 자동감지 토글 -->
|
||||
<div class="flex items-center gap-3 p-3 rounded-lg border border-gray-100 bg-gray-50 min-w-[200px]">
|
||||
<div class="flex-1">
|
||||
<p class="text-sm font-medium text-gray-800">체결강도 자동감지</p>
|
||||
<p class="text-xs text-gray-400">거래량 상위 20종목 실시간 분석</p>
|
||||
</div>
|
||||
<label class="inline-flex items-center cursor-pointer">
|
||||
<input type="checkbox" id="wsScanner" checked onchange="saveWatchSource()"
|
||||
class="sr-only peer">
|
||||
<div class="w-11 h-6 bg-gray-200 peer-checked:bg-blue-600 rounded-full peer
|
||||
peer-focus:ring-2 peer-focus:ring-blue-300 transition-colors relative
|
||||
after:content-[''] after:absolute after:top-[2px] after:left-[2px]
|
||||
after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all
|
||||
peer-checked:after:translate-x-5"></div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- 테마 선택 -->
|
||||
<div class="flex-1 p-3 rounded-lg border border-gray-100 bg-gray-50">
|
||||
<p class="text-sm font-medium text-gray-800 mb-2">테마 감시</p>
|
||||
<!-- 테마 드롭다운 + 추가 버튼 -->
|
||||
<div class="flex gap-2 mb-2">
|
||||
<select id="themeSelect"
|
||||
class="flex-1 px-3 py-1.5 text-xs border border-gray-200 rounded-lg bg-white focus:outline-none focus:ring-2 focus:ring-blue-400">
|
||||
<option value="">테마를 선택하세요...</option>
|
||||
</select>
|
||||
<button onclick="addSelectedTheme()"
|
||||
class="px-3 py-1.5 text-xs font-medium bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors whitespace-nowrap">
|
||||
+ 추가
|
||||
</button>
|
||||
</div>
|
||||
<!-- 선택된 테마 태그 목록 -->
|
||||
<div id="selectedThemes" class="flex flex-wrap gap-1.5 min-h-[28px]">
|
||||
<span class="text-xs text-gray-400" id="noThemeMsg">선택된 테마 없음</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 규칙 + 포지션 -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
|
||||
<!-- 매매 규칙 -->
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-4">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-sm font-semibold text-gray-800">매매 규칙</h2>
|
||||
<button onclick="showAddRuleModal()"
|
||||
class="px-3 py-1.5 text-xs font-medium bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
|
||||
+ 규칙 추가
|
||||
</button>
|
||||
</div>
|
||||
<div id="rulesList" class="space-y-3">
|
||||
<p class="text-xs text-gray-400 text-center py-4">규칙이 없습니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 현재 포지션 -->
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-4">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-sm font-semibold text-gray-800">현재 포지션</h2>
|
||||
<span class="text-xs text-gray-400">5초 자동 갱신</span>
|
||||
</div>
|
||||
<div id="positionsList">
|
||||
<p class="text-xs text-gray-400 text-center py-4">보유 포지션 없음</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 매매 로그 -->
|
||||
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-4">
|
||||
<div class="flex items-center justify-between mb-3 flex-wrap gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2 class="text-sm font-semibold text-gray-800">매매 로그</h2>
|
||||
<span id="wsStatus" class="text-xs text-gray-400">○ 연결중...</span>
|
||||
</div>
|
||||
<div class="flex gap-1 text-xs">
|
||||
<button onclick="setLogFilter('all')" id="filterAll"
|
||||
class="px-3 py-1 rounded-full bg-gray-800 text-white font-medium">전체</button>
|
||||
<button onclick="setLogFilter('action')" id="filterAction"
|
||||
class="px-3 py-1 rounded-full bg-gray-100 text-gray-600 hover:bg-gray-200">매매만</button>
|
||||
</div>
|
||||
<label class="flex items-center gap-1 text-xs text-gray-400 cursor-pointer">
|
||||
<input type="checkbox" id="autoScrollChk" checked class="w-3 h-3 accent-blue-500">
|
||||
자동스크롤
|
||||
</label>
|
||||
<span id="logUpdateTime" class="text-xs text-gray-400"></span>
|
||||
</div>
|
||||
<div id="logsWrapper" class="overflow-y-auto rounded border border-gray-100" style="max-height:480px;">
|
||||
<table class="w-full text-xs">
|
||||
<thead class="sticky top-0 bg-white">
|
||||
<tr class="text-left text-gray-400 border-b border-gray-100">
|
||||
<th class="pb-2 pt-2 px-1 font-medium w-36">시각</th>
|
||||
<th class="pb-2 pt-2 px-1 font-medium w-16">레벨</th>
|
||||
<th class="pb-2 pt-2 px-1 font-medium w-20">종목</th>
|
||||
<th class="pb-2 pt-2 px-1 font-medium">내용</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="logsList">
|
||||
<tr><td colspan="4" class="py-4 text-center text-gray-400">로그가 없습니다.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 규칙 추가/수정 모달 -->
|
||||
<div id="ruleModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
|
||||
<div class="bg-white rounded-xl shadow-xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
|
||||
<div class="p-6">
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h3 id="modalTitle" class="text-base font-semibold text-gray-800">규칙 추가</h3>
|
||||
<button onclick="hideModal()" class="text-gray-400 hover:text-gray-600 text-lg">✕</button>
|
||||
</div>
|
||||
|
||||
<div class="space-y-4">
|
||||
<input type="hidden" id="ruleId">
|
||||
|
||||
<!-- 규칙명 -->
|
||||
<div>
|
||||
<label class="block text-xs font-medium text-gray-700 mb-1">규칙명</label>
|
||||
<input id="fName" type="text" placeholder="예: 강한매수 전략"
|
||||
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400">
|
||||
</div>
|
||||
|
||||
<!-- 진입 조건 -->
|
||||
<div class="border-t pt-4">
|
||||
<p class="text-xs font-semibold text-gray-600 mb-3">진입 조건</p>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label class="flex items-center justify-between text-xs text-gray-700 mb-1">
|
||||
<span>최소 상승점수 (RiseScore)</span>
|
||||
<span id="riseScoreVal" class="font-semibold text-blue-600">60</span>
|
||||
</label>
|
||||
<input id="fRiseScore" type="range" min="0" max="100" value="60"
|
||||
oninput="document.getElementById('riseScoreVal').textContent=this.value"
|
||||
class="w-full accent-blue-600">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-700 mb-1">최소 체결강도</label>
|
||||
<input id="fCntrStr" type="number" value="110" step="1" min="0"
|
||||
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400">
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<input id="fRequireBullish" type="checkbox" class="w-4 h-4 accent-blue-600">
|
||||
<label class="text-xs text-gray-700">AI 호재 신호 필요</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 주문 설정 -->
|
||||
<div class="border-t pt-4">
|
||||
<p class="text-xs font-semibold text-gray-600 mb-3">주문 설정</p>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label class="block text-xs text-gray-700 mb-1">1회 주문금액 (원)</label>
|
||||
<input id="fOrderAmount" type="number" value="500000" step="10000" min="10000"
|
||||
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-700 mb-1">최대 보유 종목 수</label>
|
||||
<input id="fMaxPositions" type="number" value="3" min="1" max="20"
|
||||
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 청산 조건 -->
|
||||
<div class="border-t pt-4">
|
||||
<p class="text-xs font-semibold text-gray-600 mb-3">청산 조건</p>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label class="block text-xs text-gray-700 mb-1">손절 (%)</label>
|
||||
<input id="fStopLoss" type="number" value="-3" step="0.5"
|
||||
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-700 mb-1">익절 (%)</label>
|
||||
<input id="fTakeProfit" type="number" value="5" step="0.5"
|
||||
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-700 mb-1">최대 보유 시간 (분, 0=무제한)</label>
|
||||
<input id="fMaxHold" type="number" value="60" min="0"
|
||||
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400">
|
||||
</div>
|
||||
<div class="flex items-end pb-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<input id="fExitBeforeClose" type="checkbox" checked class="w-4 h-4 accent-blue-600">
|
||||
<label class="text-xs text-gray-700">장마감 전 청산 (15:20)</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3 pt-2">
|
||||
<button type="button" onclick="submitRule()"
|
||||
class="flex-1 py-2.5 text-sm font-medium bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
|
||||
저장
|
||||
</button>
|
||||
<button type="button" onclick="hideModal()"
|
||||
class="flex-1 py-2.5 text-sm font-medium bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-colors">
|
||||
취소
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ define "scripts" }}
|
||||
<script src="/static/js/autotrade.js"></script>
|
||||
{{ end }}
|
||||
Reference in New Issue
Block a user