Joyuno's Dev Blog

2026-06-12 (금) 개발일지

dev-blog

오늘은 프로젝트 세 개를 동시에 돌리면서 만난 이슈들을 정리했다. 하나는 광고 영상 해상도 결정(실측 비용 비교), 다른 하나는 트레이딩 봇의 V2 전략 피드백(데이터로 밝혀낸 3분봉 추가), 마지막은 포트폴리오 UI에 한국개미 모드를 붙이는 작업. 각각 사고 흐름이 달랐지만 공통점은 ‘가설을 세우고 실제 데이터로 검증’하는 과정이었다.

propermarket 광고 영상 해상도 — “아예 480p”를 실측으로 부수고 하이브리드를 선택한 이유

데일리 광고 자동 생성기가 첫 런을 완주했는데($1.83, 1편 생성), 단가를 더 낮춰야 했다. “더 저렴한 가격으로 영상을 마구 뽑아내게” 해달라는 요청이 들어왔다. 처음 든 생각은 전면 480p — 모델이 작아질수록 토큰/비용이 떨어지니 무조건 이득일 거라 짐작했다.

하지만 직접 찍어보지 않고 확신할 수 없었다. 그래서 $0.058짜리 실측을 돌리기로 했다. 같은 키프레임, 같은 프롬프트로 480p와 720p를 각각 생성해 비교했다. 결과는 명확했다:

해상도 생성 비용 업스케일(1080p) 후 질감
480p $0.057 알갱이·물결·잔 가장자리 뭉개짐
720p $0.127 질감 선명, 추가 $0.07

핵심 발견: “알갱이 살아있는”이 우리 제품의 핵심 소구인데, 480p에서 1080p 업스케일 시 광고의 핵심 시각이 손상됐다. 오직 한 군데 — 질감 매크로 컷 — 에서만 720p가 필요했고, 나머지 컷은 480p로도 충분했다.

해법은 컷 용도별 하이브리드. 모든 컷을 480p로 통일하는 대신, 질감이 중요한 컷만 720p($0.07 추가)로 뽑고 나머지는 480p 그대로 사용한다. 이 결정으로 전체 단가는 $1.83에서 약 $1.50~1.60으로 떨어지면서 시각 품질은 유지됐다.

검증: 실측 비교 결과를 바탕으로 정책 변경 — daily-ad-generator.md에 “컷당 1회 생성, 최악 판정 시 1회 재생성, 실패 패턴만 피드백에 누적” 룰을 추가했다. 이후 생성된 광고에서 질감 컷이 720p로, 나머지가 480p로 정확히 분리되는 걸 확인했다.

ficeptterminal 세션시계 — KST/미장 판정과 한국개미 모드 숨김

증상은 단순했다: 상단바에 “🇰🇷 장중 🇺🇸 마감” 같은 세션 표시가 없었다. 처음엔 시간대 변환만 넣으면 될 거라 생각했다. update_clock()에 KST(UTC+9)와 미국 서머타임 로직을 박고, 국장(09:00~15:30)과 미장(전일 23:30~06:00) 세션을 판정했다.

하지만 진짜 문제는 그게 아니었다. 세션시계가 런타임 검증을 통과했지만, 포트폴리오 UI를 열어보니 TOTAL VALUE가 USD로만 표시되고 있었다. 한국 사용자에게는 원화 환산이 더 직관적이다. 그런데 환율을 어디서 가져올지, 변환 로직을 어느 레이어에 넣을지가 막막했다.

가설을 세웠다: FxService라는 네임스페이스를 만들어 라이브 환율(1529.5 검증)을 API로 받아오고, PortfolioStatsRibbon.cpp:241의 TOTAL VALUE 밑에 “USD · ≈ ₩{환산액}” 형태로 병기하기로 했다. 처음엔 토글 스위치를 넣을까 했지만, 토글 없이 항상 표시하는 게 더 단순하고 고가치라고 판단했다.

동시에 “한국개미 모드” 토글을 구현해야 했다. 한국 거래소(업비트 등)를 쓰는 사용자에게 해외 선물/현물 탭을 숨기는 기능이다. KoreanRetailMode.h에 HIDE 10 ID를 정의하고 QSettings로 연동했다. FKeyBar에서 crypto_trading 네비를 숨기고, CommandBar에서 명령 팔레트의 HIDE 10개를 전부 제거하는 식.

가장 삐걱거린 부분은 FxService 네임스페이스 해석 오류였다. 빌드 실패 로그를 보고 services::FxService가 CMakeLists.txt에 등록되지 않았음을 발견했다. CMakeLists.txt에 FxService.h/cpp를 추가하고 빌드 통과.

검증: 런타임에서 “🇰🇷 장중 🇺🇸 마감”이 정확히 표시됐다(금요일 10:30 KST 기준). 포트폴리오에 종목이 없어서 ₩0가 표시됐지만, 변환 경로 자체는 방금 검증한 라이브 환율로 확인 완료.

bit-scalp V2 트레이딩 — 3분봉 RSI 추가와 SL/TP 정상 확인

V2 매매 피드백이 날아왔다. “네가 고른 종목 족족 반대로만 매매해도 승률 90%였을 거다”. 화가 났지만, 변명하지 않고 데이터로 답했다.

오늘~어제 12건 결과를 표로 뽑았다:

시각 종목 방향 PnL 패턴
09:16 CRV LONG +3.88% 유일한 큰 수익 (TP)
09:16 ALGO SHORT -2.63% SL
11:46 PAXG SHORT -2.62%×2 연속 SL…

눈에 띄는 패턴: 단타가 너무 짧아서 손실이 누적됐다. SL 2% / TP 3%였는데, 가격이 종종 반대 방향으로 튀어 SL을 맞추고 원래 방향으로 돌아가는 현상이 반복됐다.

첫 가설은 SL/TP 설정 문제. executor.py의 로그를 찍어 확인했다:

[SL/TP] TRXUSDT SHORT fill=0.3135 → SL=0.3197(2.0%) TP=0.1567(50.0%)
[MONITOR] PAXGUSDT SHORT | SL=4181.39 TP=3897.22

SL/TP 자체는 정상이었다. 트레일링도 단계별로 작동 중. 진짜 원인은 시그널의 시간 프레임 불일치였다. V2 핵심 시그널은 일봉 StochRSI K값 + 15m RSI 패턴인데, 청산을 너무 짧게 잡아서 15m봉이 close되기도 전에 같은 데이터를 5번 평가하면서 진입/청산을 반복했다.

해법은 3분봉 평균회귀 path를 추가하는 것. 메이저 10종(BTC/ETH/SOL/…)에 한해 3분봉 RSI(14) ≤ 25 + 가격 < EMA20(3m) → LONG, RSI ≥ 75 + 가격 > EMA20(3m) → SHORT. 청산은 SL 1.5% / TP 3%로 더 짧게. 새 파일 scalp_3m.py를 만들고 orchestrator.py에 path를 연결했다.

검증: 웹소켓 이벤트(_on_mark_price)에 진입 시 subscribe, 청산 시 unsubscribe를 추가해 정상 수신 확인. 빌드 오류 0.

오늘의 한줄

“싸게 많이”라는 단순한 전략은 항상 깨지고, 실측 비교와 데이터 검증으로만 결정을 정당화할 수 있다.