KPS 트레이딩툴 — 브라우저어댑터.한선
개요
서브5-전략엔진-v4.한선(commands.psv 산출) → 크라우니AI 브라우저 제어서버(:9847, WKWebView가 Tradovate 웹트레이더 조작) HTTP 명령 시퀀스로 변환하는 어댑터. 전부 한선씨. 웹훅어댑터.한선의 멱등/재시도/화이트리스트 관용구 재사용.무엇을 했는지
제어호출상태읽기계좌전환수량설정주문발행체결확인주문취소청산
명령처리 팬아웃 배치처리 전부 구현.
- HTTP = 체계()+curl(바디 -d @file, URL은 127.0.0.1 고정+포트 숫자만).
- 안전 기본값 DRY_RUN=1 — 실제 클릭 명령(/click_text, 계좌전환 클릭 포함) 대신
/tmp/kps/브라우저_드라이런.psv에 "보낼 요청"만 기록. DRY_RUN=0일 때만 실제 발행.
- PROOF_MODE=1이면 COPY 계열 명령을 팬아웃 단계에서 스킵(리더 단독).
검증 결과
① 컴파일 경고 0 (./hanseonc_high 브라우저어댑터.한선 → 14092 큐브 생성, 에러 없음)
② 읽기 전용 실측(클릭 없음, /health·/eval만 호출):
- 2026-07-31 정정: /eval은 결함이 아니다. JS 본문이 함수 본문으로 평가되므로 명시적
return이 필수({"js":"1+1"} → 빈 result, {"js":"return 1+1;"} → "2"). 최초 보고의
"무응답" 기술은 오진 — 정정한다.
- 상태읽기()를 return-JS + BA_평가()(JS를 /tmp/kps/js/ba_eval.js 파일 경유로 조립,
이스케이프·셸주입 동시 회피)로 재구현 후 실호출 결과:
position=0 bid=28567.50 ask=28568.00 symbol=MNQU6 account=LUBCWYJ6110007
(5필드 전부 채워짐, 원문 응답: `{"result":"{\"position\":\"0\",\"bid\":\"28567.50\",...}",
"type":"object","ok":true}` — eval이 object 반환 시 서버가 JSON.stringify해 문자열로
감싸 넣는 이중 인코딩 구조 실측 확인, 상태읽기()의 언이스케이프 로직과 일치).
③ 드라이런 종단: ENTER 1건 + COPY 4건 → 5계좌 시퀀스(계좌전환→수량설정→주문발행→체결확인→
미체결시취소) 순서·지연(250/500/750/1000ms) 정확히 기록됨. 로그 전문은
/tmp/kps/브라우저_드라이런.psv /tmp/kps/브라우저어댑터.psv 참조.
④ PROOF_MODE=1 확인: COPY 4건 전부 PROOF_MODE_SKIP_COPY로 스킵, 드라이런 로그 COPY 0건.
⑤ 절대 금지 준수: 세션 전체에서 DRY_RUN=0 미실행, /click_text 실호출 없음(코드상으로도
DRY_RUN=1 분기에서 조기 반환 후 실제 curl 호출 자체를 안 함), 계좌 전환 실클릭 없음.관련 파일
/Users/ef/CrownyDoc/projects/kps-trading-tool/브라우저어댑터.한선(신규)- 참고:
서브5-전략엔진-v4.한선,웹훅어댑터.한선(같은 디렉토리) - 로그:
/tmp/kps/브라우저어댑터.psv(액션 로그),/tmp/kps/브라우저_드라이런.psv(드라이런 기록)
DRY_RUN=0 전환 시 필요한 사전 점검 (체크리스트)
input.form-control셀렉터가 다중 인풋(계좌 수량 vs 다른 필드) 중 정확히 수량 입력을
계좌전환확인 로직이account가 정확히 계좌ID 문자열과 일치하는지 대소문자/공백까지
상태읽기()는 data-testid 속성값을 그대로 씀 — 5계좌 ID 표기와 일치 확인 필요).
- 체결확인 폴링(1초 간격, 기본 30초)이 실제 체결 지연 분포(20~300초)에 맞는지 — ENTER마다
- 사장님 명시 승인 + 소액/최소수량으로 1회 라이브 스모크 후 확대.
/tmp/kps/webhook_creds.txt류처럼 이 어댑터도 크레덴셜 파일 불필요(제어서버가 이미
(/eval 관련 항목은 정정으로 제거됨 — 결함이 아니라 return 누락이었음, 위 ② 참고.)
잔여 이슈
BA_JSON필드추출은 평면(중첩 없는) JSON 객체 기준 견고화 완료(키 뒤 공백, 문자열 외 값도
2026-07-31 추가 정정 — 실주문 왕복 실측(메인 세션, 계좌 LUBCQWN3960003·MNQU6 1계약,
Buy Bid→체결→Exit at Mkt & Cxl→청산 성공, equity 49,958.10→49,963.80)에서 나온 결함 3종 반영- /click_text 이중발사 금지: 1회 호출이
element.click()+ 합성 MouseEvent를 동시 발사해
주문발행·청산·주문취소는
전부 /eval 단일 element.click()으로 교체(BA_주문버튼클릭JS/청산 js). 계좌전환은
이미 /eval 단일클릭이라 해당 없었음(재확인만).
- 비표준 공백 함정: "Exit at Mkt & Cxl" 정확일치(
trim()===)가 실측 실패 — 정규식
/Exit at Mkt/ + children.length===0으로 교체. Buy Bid/Sell Ask/Buy Mkt/Sell Mkt는
정확일치가 실측 정상이라 그대로 유지. 전역 .panic-button(전계좌 영향)은 사용 금지 명시.
- 주문 확인 다이얼로그 분기 추가:
주문발행()에서 클릭 후 400ms 대기 → 확인버튼
- 미니계약 차단 게이트 신설(
BA_미니차단): 심볼이 "MNQ"로 시작하지 않으면주문발행()
BA_SKIP_RUN=1 BA_MINI_TEST=1 ./crownyc run 로 재현 가능.
- 체결확인 폴링(1초/기본 30초 타임아웃)은 실측(3초 내 즉시체결 케이스 확인)과 부합해 변경 없음.
2026-07-31 마지막 조각 — 실증실행기.한선 신규 (라이브 실증 실행 루프)
경로: /Users/ef/CrownyDoc/projects/kps-trading-tool/실증실행기.한선
사장님이 실증(DRY_RUN=0) 진행을 승인했으나, 실계좌엔 events.psv 시세 공급원이 없어 서브5-전략엔진-v4.한선(M8 규칙엔진)을 구동할 신호가 없었다. 이 파일이 제어서버(:9847)에서 직접 호가를 폴링→지표계산(RSI/ATR/추세/연속손실, 전부 정수)→M8 규칙평가→ 브라우저어댑터.한선(상태읽기/수량설정/주문발행/체결확인/청산/미니차단)으로 실행까지 구동한다.
구조상 결정: 서브5-전략엔진-v4.한선은 top-level에 무가드 자체시험(E2E시험()/실증리허설())이
있어 가져오기 시 즉시 실행되는 함정 파일(가져오기=top-level 실행 VM함정) — 직접 가져오기하지
않고 M8_ 규칙엔진 로직(값비교/규칙직렬화/규칙파싱/규칙초기화/규칙평가/거래기록/규칙발화통계/
사상판정/규칙고도화/쿨다운판정/일목표판정/저장/불러오기)을 v4와 동일하게 인라인 복제했다
(v4도 module8을 동일 방식으로 복제한 프로젝트 관례). rules.psv 포맷은 v4와 동일해 상호호환.
브라우저어댑터.한선은 top-level에 BA_SKIP_RUN 가드가 있어 안전하게 가져오기로 재사용.
검증
① 컴파일 경고 0 (38147 큐브) ② 지표 단위시험(EX_INDICATOR_TEST=1): 6/6 PASS(RSI 전상승=100/전하락=0, ATR 등차100 정확,
추세 상승/하락 부호, 연속손실=3)
③ 하드게이트 단위시험(EX_GATE_TEST=1): 9/9 PASS(±6000센트, 거래캡5, 비MNQ 차단, MNQU6 허용,
중단플래그 생성감지·삭제확인 — 시험 후 플래그 파일 정상 삭제됨)
④ DRY_RUN=1 라이브 리허설(EX_MAX_ITERS=20 BA_SKIP_RUN=1 DRY_RUN=1): 20회(약 100초) 실제
9847 폴링 — mid가 2842687→2841262 등으로 실측 변동, ATR>50 발화 2회(R3 게이트) →
시그널=1(롱) 2회 발생 → 수량설정/주문발행/체결확인/주문취소 전부 드라이런 로그로만 기록
(/tmp/kps/브라우저_드라이런.psv), 실주문 0건, 실클릭 0건.실증 실행 명령줄(메인 세션이 DRY_RUN=0으로 돌릴 때)
cd /Users/ef/CrownyOS/crownyc
./hanseonc_high /Users/ef/CrownyDoc/projects/kps-trading-tool/실증실행기.한선 > /tmp/ex.toau
BA_SKIP_RUN=1 DRY_RUN=0 ./crownyc run /tmp/ex.toau
BA_SKIP_RUN=1은 가져오기된 브라우저어댑터.한선의 배치처리 자동실행을 막기 위해 필수.- 긴급정지:
touch /tmp/kps/실증중단.flag(다음 반복에서 즉시 청산 후 종료, ~5초 이내 반응). - 종료 후 리포트:
/tmp/kps/실증리포트_라이브.txt, 상세로그:/tmp/kps/실증실행기.log.
미해결
- 청산 시 체결가는 재조회한 bid/ask 중간값으로 근사(실제 체결가와 슬리피지 차이 가능,
- R3(ATR상한게이트)가 방향과 무관하게 가중치를 더하는 v4 원설계를 그대로 인라인 복제했음 —
- 진입 목표/손절(±8pt/-6pt)은 사장님 규격(일목표 ±$60÷5거래 근사)에서 역산한 값 — 실거래
2026-07-31 다음 단계 — 다계좌동시.한선 신규 (5계좌 동시 진입/진출 도구)
경로: /Users/ef/CrownyDoc/projects/kps-trading-tool/다계좌동시.한선
실증실행기.한선 단일계좌 라운드트립 성공(5거래 체결, 계좌 49,963.80→50,005.30, 규칙 R2/R3 티 승격 확인) 이후 사장님이 지시한 다음 단계 — 5계좌를 한 사이클에서 함께 진입/진출시키고, 지연 진입·지연 청산을 확정 규칙대로 보정/강제하는 도구.
구조상 결정: 브라우저어댑터.한선만 가져오기(top-level BA_SKIP_RUN 가드 존재, 안전).
실증실행기.한선은 가져오기하지 않음 — 그 파일도 브라우저어댑터.한선을 가져오기하므로
직접 가져오기 시 이중 가져오기(파일간 함수명충돌 하드에러 위험)가 됨. 대신 같은 관용구
(센트 정수 파싱, 체계 test -f 플래그 감지)만 동일 패턴으로 재구현.
함정 발견: 시도가 hanseonc_high 예약키워드(TRY, 예외처리 시도/오류)라 변수명으로 쓰면
"변수명 기대, '시도' 발견" 컴파일 에러 — 시도횟수로 변경해 해결. 가드레일의 예약어 목록
(가져오기/메서드/레지스터/선택/전이/신호)에 없는 신규 사례라 여기 기록.
검증
① 컴파일 경고 0 (33640 큐브) ② 가격차판정 단위시험(DA_PRICE_GATE_TEST=1): 5/5 PASS — 차이 0/500(경계,포함)/501(초과)/
-500(경계,포함)/-600(초과) 전부 기대대로 재진입(1)/스킵(-1) 판정
③ DRY_RUN=1 종단 리허설(BA_SKIP_RUN=1 DRY_RUN=1 DA_DIR=롱): 5계좌 전체
동시진입→진입검증→미진입보정→동시진출→진출검증 전 흐름 실측(실제 9847 상태읽기 호출,
/tmp/kps/다계좌.psv 45줄+/tmp/kps/브라우저_드라이런.psv 45줄 기록). DRY_RUN 스텁상
체결확인이 항상 0을 반환하므로(기존 어댑터 설계) 5계좌 전부 "미체결"로 기록되고 이어서
미진입보정이 5계좌 전부 평가 후 스킵 처리 — 오케스트레이션 흐름 자체는 처음부터 끝까지
정상 실행됨. 실주문/실클릭 0건.
④ 모의 시나리오 단위시험(DA_SCENARIO_TEST=1): 6/6 PASS. 실계좌 5개를 동시에 조작할
방법이 없어(WKWebView 1개 인스턴스) 순수 판정/알림 로직을 결정론적으로 검증:
- 미진입 2계좌: 계좌A(현재가차이 300) → 재진입 판정, 계좌B(차이 800) → 스킵 판정
- 미진출 1계좌: 재시도 소진 가정 → DA_잔존알림()이 ALERT 로그 + /tmp/kps/포지션잔존.flag
생성 확인, 잔존 없음 케이스는 알림 없음 확인, 시험 후 플래그 파일 정리 확인
⑤ 세션 전체에서 DRY_RUN=0 미실행, 실제 Buy/Sell/Exit/계좌전환 클릭 없음(계좌전환 자체는
/eval 단일클릭이라 DRY_RUN=1일 때 애초에 호출 안 됨 — 로그만 기록).실행 명령줄
cd /Users/ef/CrownyOS/crownyc
./hanseonc_high /Users/ef/CrownyDoc/projects/kps-trading-tool/다계좌동시.한선 > /tmp/da.toau
BA_SKIP_RUN=1 DRY_RUN=0 DA_DIR=롱 ./crownyc run /tmp/da.toau # 실증(메인 세션 전용)
BA_SKIP_RUN=1 DRY_RUN=1 DA_DIR=롱 ./crownyc run /tmp/da.toau # 드라이런 리허설(항상 안전)
DA_DIR: "롱" 또는 "숏"(기본 롱).DA_QTY류 세부 파라미터는 파일 상단 파라미터 블록에서 직접 조정.- 잔존 확인:
/tmp/kps/포지션잔존.flag파일 존재 여부 = 미진출강제 3회 재시도 후에도 청산
미해결
- 진입가 기록은 체결 후 재조회한 mid가(bid+ask 중간값) 근사 — 실제 체결가와 소폭 차이 가능.
- 미진입보정의 "평균진입가"는 최초 사이클에서 성공 계좌가 하나도 없으면 0이 되어(빈 성공목록)
- 계좌 5개 동시 실측(실제 병렬 포지션 보유 상태에서의 검증/보정/강제 전체 경로)은 이번 실주문
2026-07-31 필수 수리 — 손익 계산을 실현손익(계좌패널) 델타 기준으로 교체
실증 5거래에서 엔진계산(+$53.98) vs 계좌실현(+$47.20) 괴리, 5계좌 즉시왕복에서 계좌당 -$6.30~-$10.30 손실(스프레드+수수료 실비)이 재조회mid근사 계산에 전부 누락되던 문제 수리.
수정 대상
실증실행기.한선:EX_괄호음수파싱·실현손익읽기(계좌ID)신규.EX_청산실행이 mid근사 대신
EX_장부배열_유효(고도화 입력)에서 제외. 목표/손절을 8pt/6pt → 12pt/8pt로 상향
(왕복비용 $6~10 위에서 작동하도록, 상단 파라미터 주석에 근거 명시).
다계좌동시.한선: 동일DA_괄호음수파싱·DA_실현손익읽기도입.동시진입/미진입보정이
DA_진입기준맵에 스냅샷, 사이클() 종료 시 DA_사이클손익집계()가
계좌별 델타를 재조회해 합산 로그+출력.
- Tradovate Accounts 패널은 계좌 전환 없이 전 계좌를 한 화면에 나열 — 실측으로 확인,
계좌전환() 호출이 필요 없음(성능·리스크 이점).검증
① 컴파일 경고 0(양쪽 파일 모두) ② 괄호 음수 파서 단위시험 — 양쪽 파일 각 4/4 PASS:$34.90→3490, ($10.30)→-1030,
$0.00→0, ($6.30)→-630
③ 읽기전용 실호출 5계좌 실파싱(실증실행기.한선에서 실측, 당시 세션 로그인 상태) — 정확히
일치: QWN 성공=1 센트=3490($34.90) / WYJ 성공=1 센트=-1030(($10.30)) / HNS 성공=1
센트=-930(($9.30)) / SZW 성공=1 센트=-630(($6.30)) / JEM 성공=1 센트=-630(($6.30))
④ DRY_RUN=1 회귀 — 양쪽 파일 정상 실행. 다계좌동시.한선 재검증 시점엔 Tradovate 세션이
로그인 화면으로 전환돼 있어(브라우저 상태 변화, 코드 결함 아님 — 직전 ③에서 로그인
상태였을 때는 정상 파싱 확인됨) 5계좌 전부 "성공=0"이었으나, 이때 폴백 경로가 정확히
설계대로 동작함을 확인: 스냅샷 실패 시 경고 로그 남기고 해당 계좌를 손익집계에서 제외,
합계는 "유효계좌=0/5"로 정직하게 보고(크래시 없음, 조용한 오염 없음).실행 명령줄 (변경 없음, 기존과 동일)
cd /Users/ef/CrownyOS/crownyc
./hanseonc_high /Users/ef/CrownyDoc/projects/kps-trading-tool/실증실행기.한선 > /tmp/ex.toau
./hanseonc_high /Users/ef/CrownyDoc/projects/kps-trading-tool/다계좌동시.한선 > /tmp/da.toau
BA_SKIP_RUN=1 DRY_RUN=0 ./crownyc run /tmp/ex.toau # 실증(메인 세션 전용)
BA_SKIP_RUN=1 DRY_RUN=0 DA_DIR=롱 ./crownyc run /tmp/da.toau
미해결
- 실행 중 Tradovate 세션이 로그아웃되면(타임아웃 등) 실현손익 조회가 전부 실패로 폴백되는데,
- 다계좌동시.한선의 실측 5계좌 파싱은 이번 세션 중 브라우저 로그인 상태 변화로 재확인이
2026-07-31 멀티창 실전 배선 — 30계좌 구조 준비 + LifeUp 5계좌 2/2/1 테스트
경로: 브라우저어댑터.한선(인스턴스화), /tmp/kps/계좌구성.psv(신규 설정파일), 관제기.한선(실배선)
작업 A — 브라우저어댑터.한선 인스턴스화
BA_제어포트를CTL_PORT환경변수로 받음(기본 9847),BA_초기화됨가드로 1회만 설정.BA_계좌목록을 인스턴스 설정파일에서 로드하는BA_인스턴스계좌로드()신규. 파일 없거나
- 경로 충돌 발견·회피: 요청 원문 경로
/tmp/kps/인스턴스.psv는 이미 관제기.한선의
/tmp/kps/계좌구성.psv로 분리해 둘 다 온전.작업 B — 인스턴스 설정 생성
/tmp/kps/계좌구성.psv: 9847|LifeUp|LUBCQWN3960003,LUBCWYJ6110007|MA3|활성 /
9848|LifeUp|LUBCHNS6060005,LUBCSZW2200004|MA3|활성 / 9849|LifeUp|LUBCJEM4770006|MA3|활성
+ APEX(9853~)/Lucid 확장 주석(9850~9852 점유 불가 명시).작업 C — 관제기.한선 실배선
가져오기 "다계좌동시.한선"추가(동일 브라우저어댑터.한선 경로는 컴파일러가 dedupe —
KJ_인스턴스명령()의 "위임 로그만" 스텁 제거 →KJ_인스턴스로전환(포트)로 BA_제어포트·
동시진입()/동시진출()(다계좌동시.한선 재사용)을
실제로 호출. 3중 게이트 유지: KJ_거부해야하나()(DRY_RUN=0인데 KJ_LIVE 미설정만 완전
차단) + 어댑터 내부 DRY_RUN 재확인(2중) + BA_미니차단(선행 검사, 불변).
KJ_실행허가() 함수 자체는 시맨틱 불변 유지(기존 단위시험이 직접 호출하므로 회귀 보호).
- 버그 발견·수정(기존 코드): 심볼을 위치인자
KJ_필드(필드들,2)로 읽던 기존 코드가
SYMBOL= 키드 필드 탐색으로 수정.
관제팬아웃()에 계좌 단위 집계(계좌진입성공/실패,계좌진출성공/실패) 추가.
검증
① 3파일 컴파일 경고 0 ② 기존 자체시험 회귀: 관제기 12/12, 브라우저어댑터 미니차단 3/3, 다계좌동시 파서 4/4+가격차판정5/5+시나리오6/6 전부 유지 ③ DRY_RUN=1 3인스턴스 종단 리허설(KJ_MULTI_REHEARSAL=1): 5계좌(2+2+1)가 포트별로 정확히
배분되어 ENTER 시퀀스 실행 — INST_LIFEUP(9847) 계좌2, INST_APEX(9848) 계좌2,
INST_LUCID(9849) 계좌1 — /tmp/kps/관제.psv·/tmp/kps/다계좌.psv에 계좌별 실측 기록.
전 계좌 "미체결"로 귀결된 건 DRY_RUN 스텁 설계상 항상 그런 것(체결확인()이 DRY_RUN에서
폴링 없이 항상 0 반환 — 이전 실증실행기/다계좌동시 단독 리허설과 동일 패턴, 신규 결함
아님)이지 새 결함이 아님.
④ 읽기전용 3포트 헬스(KJ_HEALTH=1): 9848·9849는 "티(로그인정상)", 9847은 "옴(전환중)" —
실측: 9847 탭이 현재 inter-m.com(오디오 제품 페이지)을 보여주고 있음(tabs:2, Tradovate가
다른 탭에 남아있을 가능성). 코드 결함이 아니라 브라우저 실제 상태 — 네비게이션 금지
지시에 따라 손대지 않음, 사장님 확인 필요 항목으로 보고.
⑤ 인스턴스 설정 파싱 단위시험(KJ_INSTANCE_CFG_TEST=1): 5/5 PASS — 9847=2계좌,
9848=2계좌, 9849=1계좌, 3포트 합산 5계좌, 미등록 포트 폴백 확인.메인이 실행할 실주문 명령줄
cd /Users/ef/CrownyOS/crownyc
./hanseonc_high /Users/ef/CrownyDoc/projects/kps-trading-tool/관제기.한선 > /tmp/kj.toau
BA_SKIP_RUN=1 DA_SKIP_RUN=1 DRY_RUN=0 KJ_LIVE=1 KJ_MULTI_REHEARSAL=1 ./crownyc run /tmp/kj.toau
DRY_RUN=0과KJ_LIVE=1을 둘 다 명시해야 실주문(3중 게이트 중 ①②)이 열림. 하나라도
KJ_거부해야하나()가 fail-closed로 차단.
- 실행 전 반드시 포트9847의 Tradovate 탭 상태 확인(현재 다른 사이트 표시 중 — 그 상태로
미해결
- 포트9847이 Tradovate가 아닌 페이지를 보여주는 문제(브라우저 상태, 코드 아님) — 확인/복구는
동시진입()이 DRY_RUN에서 항상 "미체결"로 귀결되는 기존 설계(체결확인 스텁) 때문에,
- 관제기.한선의 30계좌(APEX20+Lucid5) 확장은 이번엔 "구조 준비"만(계좌구성.psv 주석 +