안녕하세요! 10편에서 갭 조건을 충족한 종목이 "진입완료(초록)"로 바뀌는 것까지 만들었죠. 그런데 진짜 궁금한 건 "그때 샀으면 지금 얼마 벌었/잃었을까?"잖아요. 오늘은 실제 주문은 한 줄도 넣지 않고, 샀다고 가정해서 수익률·트레일링·손절을 자동 계산하는 가상매수 엔진을 만듭니다. 아래 비어 있던 "시뮬레이션 결과" 표가 드디어 채워져요!

"언제 사고, 얼마 벌고, 언제 파는가"는 화면(UI)과 상관없는 순수 계산 로직입니다. 그래서 폼에 섞지 않고 SimEngine이라는 별도 클래스로 분리했어요. 이렇게 해두면 나중에 규칙을 바꾸거나 백테스트에 그대로 재사용하기 좋습니다. 폼은 시세만 넘겨주고, 결과만 받아 그리면 돼요.
종목이 진입완료가 된 그 순간의 현재가를 진입가로 기록합니다. 매수금액은 종목당 50만원으로 정해두고, 그걸 진입가로 나눠 수량을 구해요. 딱 한 번만 사도록 이미 산 종목은 건너뜁니다.
public void TryEnter(string code, string name, long price)
{
if (price <= 0 || _map.ContainsKey(code)) return; // 이미 샀으면 무시
_map[code] = new SimState {
Code = code, Name = name, EntryPrice = price,
Shares = BuyAmount / price, // 50만원 ÷ 진입가 = 수량
Status = SimStatus.Holding };
}
10편에서 만든 실시간 시세가 들어올 때마다, 보유 중인 종목의 수익률과 예상손익을 다시 계산합니다. 수익률은 (현재가−진입가)/진입가, 예상손익은 거기에 수량을 곱한 값이에요. 그리고 최고 수익률(고점)도 계속 기록해 둡니다. 이 고점이 다음 단계 트레일링의 기준이 되거든요.
s.ProfitPercent = (price - s.EntryPrice) / (double)s.EntryPrice * 100.0;
s.ExpectedPnL = (price - s.EntryPrice) * s.Shares;
if (s.ProfitPercent > s.PeakProfit) s.PeakProfit = s.ProfitPercent; // 고점 갱신
여기가 엔진의 심장입니다. 보유 종목의 운명은 세 갈래예요.
말로는 복잡하지만 코드는 짧습니다. 핵심은 고점(PeakProfit)을 기준으로 얼마나 밀렸는지로 청산을 판단하는 거예요. 예를 들어 +8%까지 올랐다가 +6%로 밀리면(고점 대비 2%p) 익절합니다. 무작정 +3%에서 파는 게 아니라, 더 오르면 따라 올라가며 이익을 키우는 거죠.
// 1) 수익 못 낸 채 -2% 이하 → 손절
if (!s.Armed && s.ProfitPercent <= HardStop) { s.Status = SimStatus.StopLossDone; s.Closed = true; return; }
// 2) +3% 한 번 찍으면 트레일링 가동
if (s.PeakProfit >= TrailingStart) s.Armed = true;
if (s.Armed)
{
s.Status = SimStatus.Trailing;
// 고점 대비 2%p 밀리면 익절
if (s.ProfitPercent <= s.PeakProfit - TrailBand) { s.Status = SimStatus.ProfitDone; s.Closed = true; }
}
else s.Status = SimStatus.Holding;
한 번 손절완료/익절완료가 되면 Closed 플래그로 잠가서, 이후 시세가 와도 다시 거래하지 않습니다. 가상이지만 "한 번 청산하면 끝"이라는 실제 매매 규칙을 그대로 지키는 거예요.
이제 10편의 시세 처리(OnQuote)에 딱 세 줄만 더하면 됩니다. 진입완료면 가상 매수하고, 시세를 엔진에 넘기고, 시뮬 표를 다시 그려요.
if (st.Status == EntryStatus.Entered) _sim.TryEnter(code, st.Name, price);
_sim.OnPrice(code, price);
RefreshSimGrid();
시뮬 표는 수익률·예상손익을 한국 관습대로 칠합니다(플러스 빨강, 마이너스 파랑). 상태도 색으로 구분해요. 보유중은 무색, 트레일링은 노랑, 익절완료는 초록, 손절완료는 빨강. 표만 봐도 지금 포트폴리오가 어떤 상황인지 한눈에 들어옵니다.
마무리하며
이제 진입완료된 종목이 자동으로 "가상 매수"되고, 시세가 움직일 때마다 수익률이 갱신되며, +3%부터 트레일링이 따라붙고 −2%면 손절됩니다. 실제 돈은 한 푼도 안 들이고 내 전략의 성적표를 실시간으로 보는 거죠! (진입 시점을 09:10 이후로만 제한하고 싶으면 TryEnter 앞에 시간 조건 한 줄만 더하면 됩니다.) 다음 12편에서는 상단 KOSPI/KOSDAQ 지수를 실시간으로 띄우고, 우측 시황 요약(선정·진입·수익·손절·가상손익·수익률)을 이 시뮬 결과로부터 집계해 채웁니다!
| 키움 OpenAPI로 종목 스캐너 만들기 13 — 강세 섹터 & 섹터별 현황 (완결) (0) | 2026.06.22 |
|---|---|
| 키움 OpenAPI로 종목 스캐너 만들기 12 — KOSPI/KOSDAQ 지수 & 시황 요약 (0) | 2026.06.21 |
| 키움 OpenAPI로 종목 스캐너 만들기 10 — 실시간 시세 필터링 (0) | 2026.06.19 |
| 제목키움 OpenAPI로 종목 스캐너 만들기 9 — 로그인 & 조건검색 (편입·편출) (0) | 2026.06.18 |
| 키움 OpenAPI로 종목 스캐너 만들기 8 — 데이터 추상화 (0) | 2026.06.17 |
댓글 영역