Compare commits
2 Commits
054754ad34
...
80457fe6c4
| Author | SHA1 | Date | |
|---|---|---|---|
| 80457fe6c4 | |||
| c43163629d |
@@ -45,6 +45,8 @@ AI에게 맡기지는 않습니다. AI는 장 전/장중/장후 시장을 분석
|
|||||||
- DB: SQLite (`data/stockbot.db`)
|
- DB: SQLite (`data/stockbot.db`)
|
||||||
- 알림: Discord Webhook
|
- 알림: Discord Webhook
|
||||||
- AI/ML: 시장 분석과 관찰용 점수 기록까지만 사용
|
- AI/ML: 시장 분석과 관찰용 점수 기록까지만 사용
|
||||||
|
- 스케줄러 작업은 숨김 실행으로 등록하고, 장중 봇 본체는 Windows에서
|
||||||
|
`pythonw.exe`를 우선 사용해 콘솔 창 없이 백그라운드로 실행합니다.
|
||||||
|
|
||||||
운영 모드는 아래처럼 나뉩니다.
|
운영 모드는 아래처럼 나뉩니다.
|
||||||
|
|
||||||
@@ -79,6 +81,10 @@ powershell -ExecutionPolicy Bypass -File scripts\setup_scheduler.ps1
|
|||||||
powershell -ExecutionPolicy Bypass -File scripts\run_training_pipeline.ps1
|
powershell -ExecutionPolicy Bypass -File scripts\run_training_pipeline.ps1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
운영 중 봇을 직접 켜야 할 때는 `python app/main.py`보다
|
||||||
|
`python scripts\start_bot.py`를 사용합니다. 이 경로는 기존 봇을 정리한 뒤
|
||||||
|
콘솔 없는 백그라운드 프로세스로 새 봇을 띄우고 Discord 시작 알림을 보냅니다.
|
||||||
|
|
||||||
## 에이전트 운영 문서
|
## 에이전트 운영 문서
|
||||||
|
|
||||||
- `AGENTS.md`: Codex가 읽는 운영 지침
|
- `AGENTS.md`: Codex가 읽는 운영 지침
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
# 2026-07-02 일일 결산
|
||||||
|
|
||||||
|
## 오늘 결과
|
||||||
|
|
||||||
|
| 항목 | 값 |
|
||||||
|
|---|---|
|
||||||
|
| 거래 건수 | 0건 |
|
||||||
|
| 승/패 | 0승 0패 |
|
||||||
|
| 순손익 | 0원 |
|
||||||
|
| 수수료 | 0원 |
|
||||||
|
|
||||||
|
**오늘 거래 없음 — 강한 약세 환경에서 완전 패스 (정상 방어 행동)**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 장 개요
|
||||||
|
|
||||||
|
### 아침 컨텍스트 (08:15 생성)
|
||||||
|
|
||||||
|
- **글로벌 리스크**: 높음 | **심리 점수**: 33/100
|
||||||
|
- SOX **-6.27%** / S&P500 -0.22% / NASDAQ -0.66%
|
||||||
|
- CPI 3.2% 예상 상회 → 금리 인하 기대 약화
|
||||||
|
- 외국인 폭매도 지속
|
||||||
|
- `trade_allowed: false`, `position_size_multiplier: 0.5`
|
||||||
|
- 회피 섹터: 반도체 / 반도체장비 / 석유화학
|
||||||
|
|
||||||
|
### 장중 흐름
|
||||||
|
|
||||||
|
- KOSPI **-2.8%** 하락 — 인버스 ETF 폭등
|
||||||
|
- 금융업 급락, 건설·기계만 강세
|
||||||
|
- 점심 컨텍스트 `lunch_trade_allowed: false`, 배율 ×0.5 유지
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 봇 행동 분석
|
||||||
|
|
||||||
|
### 유니버스 및 목표가
|
||||||
|
|
||||||
|
- 전체 유니버스: **11종목** (ETF 제외)
|
||||||
|
- 유효 목표가: **7/11종목** (4종목 거래대금 100억 미달 제외)
|
||||||
|
- 024840, 010960, 002780, 007610 → 거래대금 미달로 제외
|
||||||
|
- 유효 7종목 모두 장중 목표가 미달 (시장 전체 하락으로 돌파 없음)
|
||||||
|
|
||||||
|
### AI 필터 동작
|
||||||
|
|
||||||
|
| 종목 | 처리 결과 |
|
||||||
|
|---|---|
|
||||||
|
| 삼성전자(005930) | **AI 거래 차단** — SOX-6.27%·CPI·外人 이유 명시 |
|
||||||
|
| 나머지 6종목 | 목표가 미달 (시장 약세로 돌파 미발생) |
|
||||||
|
|
||||||
|
- 아침 AI 블락 → 삼성전자 반도체 섹터 진입 완전 차단 ✓
|
||||||
|
- 장중(11:21) midday_context 로드 후 점심 진입 중단 활성화 ✓
|
||||||
|
- 14:50 강제 청산 — 포지션 없어 즉시 완료 ✓
|
||||||
|
|
||||||
|
### 평가
|
||||||
|
|
||||||
|
오늘은 **KOSPI -2.8%, SOX -6.27%** 의 강한 약세장이었다. 7종목 모두 시가 대비 하락 또는 횡보하여 돌파 목표가 미달이 정상이다. AI 필터가 리스크를 사전에 정확히 감지하여 전체 진입을 실질적으로 차단했고, 결과적으로 자본 보존에 성공했다.
|
||||||
|
|
||||||
|
- **AI 필터 정확도**: 우수 — 고리스크 환경(SOX -6%+, 외인 폭매도) 사전 감지
|
||||||
|
- **거래량 필터**: 정상 동작 — 거래대금 미달 4종목 자동 제외
|
||||||
|
- **강제 청산**: 포지션 없어 즉시 완료
|
||||||
|
- **과매매 위험**: 없음 (0건)
|
||||||
|
- **집행 오류**: 없음
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 최근 30일 누적 성과
|
||||||
|
|
||||||
|
| 지표 | 값 | 기준 | 상태 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 운영 거래일 | 18일 | 30일 이상 | ❌ |
|
||||||
|
| 승률 | 50.8% | > 48% | ✅ |
|
||||||
|
| MDD | -2.9% | < -10% | ✅ |
|
||||||
|
| Sharpe | -0.70 | > 1.0 | ❌ |
|
||||||
|
| L3 발동 | 0회 | 월 2회 이하 | ✅ |
|
||||||
|
|
||||||
|
**실전 전환 불가** — 2개 기준 미달 (거래일 부족, Sharpe 음수)
|
||||||
|
|
||||||
|
### Sharpe 음수 원인 분석
|
||||||
|
|
||||||
|
6/22 단일 대형 손실(-110,270원)이 분모(변동성) 대비 수익 기대를 끌어내리고 있다.
|
||||||
|
6/22 데이터 제외 시 최근 7거래일 수익 추세는 개선 중 (6/30 +66K, 7/1 +70K).
|
||||||
|
샤프 개선은 안정적 수익 누적이 필요하며 현 단계에서 전략 변경보다 데이터 축적이 우선이다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 전략 제안
|
||||||
|
|
||||||
|
없음. 오늘 거래 0건으로 판단 근거 부족. 시스템이 의도대로 동작했다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 라이브 준비 점검
|
||||||
|
|
||||||
|
- 30일 운영: 18일 진행 중 (12일 더 필요)
|
||||||
|
- 승률: 50.8% ✅
|
||||||
|
- MDD: -2.9% ✅
|
||||||
|
- Sharpe: -0.70 ❌
|
||||||
|
- L3 발동: 0회 ✅
|
||||||
|
|
||||||
|
**실전 전환 미충족** — 조건 2개 불충족.
|
||||||
@@ -1,5 +1,17 @@
|
|||||||
# Implementation Log
|
# Implementation Log
|
||||||
|
|
||||||
|
## 2026-07-02
|
||||||
|
|
||||||
|
- Hardened Windows background operation so users do not need to keep a visible
|
||||||
|
console window open:
|
||||||
|
- `scripts/start_bot.py` now starts `app/main.py` with `pythonw.exe` when it is
|
||||||
|
available.
|
||||||
|
- `scripts/_watchdog.py` uses the same `pythonw.exe` restart path.
|
||||||
|
- `scripts/setup_scheduler.ps1` registers scheduled PowerShell tasks with
|
||||||
|
`-WindowStyle Hidden` and marks task settings as hidden.
|
||||||
|
- Updated `README.md` with the background-operation rule and the preferred
|
||||||
|
manual start command.
|
||||||
|
|
||||||
## 2026-06-10
|
## 2026-06-10
|
||||||
|
|
||||||
- Enabled wake-from-sleep behavior for Scheduler tasks:
|
- Enabled wake-from-sleep behavior for Scheduler tasks:
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ from app.main import load_env
|
|||||||
load_env()
|
load_env()
|
||||||
|
|
||||||
|
|
||||||
|
def _bot_python() -> str:
|
||||||
|
if os.name == "nt":
|
||||||
|
pythonw = Path(sys.executable).with_name("pythonw.exe")
|
||||||
|
if pythonw.exists():
|
||||||
|
return str(pythonw)
|
||||||
|
return sys.executable
|
||||||
|
|
||||||
|
|
||||||
def _is_process_alive(pid: int) -> bool:
|
def _is_process_alive(pid: int) -> bool:
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["tasklist", "/FI", f"PID eq {pid}", "/NH"],
|
["tasklist", "/FI", f"PID eq {pid}", "/NH"],
|
||||||
@@ -69,7 +77,7 @@ def _restart_bot() -> int:
|
|||||||
log_path = PROJECT / "logs" / "bot_stderr.log"
|
log_path = PROJECT / "logs" / "bot_stderr.log"
|
||||||
with open(log_path, "a", encoding="utf-8") as log:
|
with open(log_path, "a", encoding="utf-8") as log:
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
[sys.executable, "-u", "app/main.py"],
|
[_bot_python(), "-u", "app/main.py"],
|
||||||
cwd=PROJECT,
|
cwd=PROJECT,
|
||||||
creationflags=creationflags,
|
creationflags=creationflags,
|
||||||
stdout=log,
|
stdout=log,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ function Register-StockTask {
|
|||||||
$Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek $Weekdays -At $Time
|
$Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek $Weekdays -At $Time
|
||||||
$Action = New-ScheduledTaskAction `
|
$Action = New-ScheduledTaskAction `
|
||||||
-Execute "powershell.exe" `
|
-Execute "powershell.exe" `
|
||||||
-Argument "-NonInteractive -ExecutionPolicy Bypass -File `"$Project\scripts\$Script`"" `
|
-Argument "-NoProfile -WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -File `"$Project\scripts\$Script`"" `
|
||||||
-WorkingDirectory $Project
|
-WorkingDirectory $Project
|
||||||
$Settings = New-ScheduledTaskSettingsSet `
|
$Settings = New-ScheduledTaskSettingsSet `
|
||||||
-ExecutionTimeLimit (New-TimeSpan -Minutes $LimitMinutes) `
|
-ExecutionTimeLimit (New-TimeSpan -Minutes $LimitMinutes) `
|
||||||
@@ -34,6 +34,7 @@ function Register-StockTask {
|
|||||||
-DontStopIfGoingOnBatteries `
|
-DontStopIfGoingOnBatteries `
|
||||||
-RunOnlyIfNetworkAvailable:$false
|
-RunOnlyIfNetworkAvailable:$false
|
||||||
$Settings.DisallowStartIfOnBatteries = $false
|
$Settings.DisallowStartIfOnBatteries = $false
|
||||||
|
$Settings.Hidden = $true
|
||||||
|
|
||||||
Register-ScheduledTask `
|
Register-ScheduledTask `
|
||||||
-TaskName $Name `
|
-TaskName $Name `
|
||||||
@@ -49,7 +50,7 @@ function Register-StockTask {
|
|||||||
|
|
||||||
function Register-WatchdogTask {
|
function Register-WatchdogTask {
|
||||||
$ScriptPath = Join-Path $Project "scripts\run_watchdog.ps1"
|
$ScriptPath = Join-Path $Project "scripts\run_watchdog.ps1"
|
||||||
$Command = 'schtasks /Create /TN "\StockBot\StockBot_Watchdog" /TR "\"powershell.exe\" -NonInteractive -ExecutionPolicy Bypass -File \"' + $ScriptPath + '\"" /SC WEEKLY /D MON,TUE,WED,THU,FRI /ST 09:00 /RI 5 /DU 06:05 /F'
|
$Command = 'schtasks /Create /TN "\StockBot\StockBot_Watchdog" /TR "\"powershell.exe\" -NoProfile -WindowStyle Hidden -NonInteractive -ExecutionPolicy Bypass -File \"' + $ScriptPath + '\"" /SC WEEKLY /D MON,TUE,WED,THU,FRI /ST 09:00 /RI 5 /DU 06:05 /F'
|
||||||
cmd.exe /c $Command | Out-Null
|
cmd.exe /c $Command | Out-Null
|
||||||
if ($LASTEXITCODE -ne 0) {
|
if ($LASTEXITCODE -ne 0) {
|
||||||
throw "StockBot_Watchdog registration failed"
|
throw "StockBot_Watchdog registration failed"
|
||||||
@@ -60,6 +61,7 @@ function Register-WatchdogTask {
|
|||||||
$Task.Settings.WakeToRun = $true
|
$Task.Settings.WakeToRun = $true
|
||||||
$Task.Settings.DisallowStartIfOnBatteries = $false
|
$Task.Settings.DisallowStartIfOnBatteries = $false
|
||||||
$Task.Settings.StopIfGoingOnBatteries = $false
|
$Task.Settings.StopIfGoingOnBatteries = $false
|
||||||
|
$Task.Settings.Hidden = $true
|
||||||
Set-ScheduledTask -TaskName "StockBot_Watchdog" -TaskPath $TaskPath -Settings $Task.Settings | Out-Null
|
Set-ScheduledTask -TaskName "StockBot_Watchdog" -TaskPath $TaskPath -Settings $Task.Settings | Out-Null
|
||||||
|
|
||||||
Write-Host "[OK] StockBot_Watchdog registered weekdays at 09:00-15:05 every 5 minutes" -ForegroundColor Green
|
Write-Host "[OK] StockBot_Watchdog registered weekdays at 09:00-15:05 every 5 minutes" -ForegroundColor Green
|
||||||
|
|||||||
@@ -11,6 +11,14 @@ PID_FILE = PROJECT / "logs" / "bot.pid"
|
|||||||
LOG_FILE = PROJECT / "logs" / "bot_stderr.log"
|
LOG_FILE = PROJECT / "logs" / "bot_stderr.log"
|
||||||
|
|
||||||
|
|
||||||
|
def _bot_python() -> str:
|
||||||
|
if os.name == "nt":
|
||||||
|
pythonw = Path(sys.executable).with_name("pythonw.exe")
|
||||||
|
if pythonw.exists():
|
||||||
|
return str(pythonw)
|
||||||
|
return sys.executable
|
||||||
|
|
||||||
|
|
||||||
def _taskkill(pid: int) -> None:
|
def _taskkill(pid: int) -> None:
|
||||||
subprocess.run(["taskkill", "/PID", str(pid), "/F"], capture_output=True, text=True)
|
subprocess.run(["taskkill", "/PID", str(pid), "/F"], capture_output=True, text=True)
|
||||||
|
|
||||||
@@ -69,7 +77,7 @@ def _start_bot() -> int:
|
|||||||
|
|
||||||
with open(LOG_FILE, "a", encoding="utf-8") as log:
|
with open(LOG_FILE, "a", encoding="utf-8") as log:
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
[sys.executable, "-u", "app/main.py"],
|
[_bot_python(), "-u", "app/main.py"],
|
||||||
cwd=PROJECT,
|
cwd=PROJECT,
|
||||||
creationflags=creationflags,
|
creationflags=creationflags,
|
||||||
stdout=log,
|
stdout=log,
|
||||||
|
|||||||
Reference in New Issue
Block a user