커뮤니티

K-means 클러스터링(K-means clustering)

프로필 이미지
dedoyes
2025-10-26 21:42:58
123
글번호 227318
답변완료

5일(기본입력값) 고가 돌파매수 저가 이탈매도 지표식을

AI(클러스터링) 방식으로 동적으로 선택하도록 설계한 예스트레이더용 구현 템플릿을 AI 질문했더니

아래처럼 제공했습니다만 예스랭귀지에 사용 부적합인지라

iM증권 예스트레이더에 부합하는 코드로 변환을 부탁드립니다.


// === 입력값 ===

input minN = 3

input maxN = 10

input stepN = 1

input perfMemory = 10 // 지수평활(미사용 시 단순평가)

input fromCluster = "Best" // "Best" / "Average" / "Worst"

input maxIter = 100

input maxBars = 1000 // 과거 평가용 봉 수

input defaultN = 5 // 안전 기본값

// === 후보 N 목록 생성 ===

var array<int> candN = array.new()

for n = minN to maxN step stepN

array.push(candN, n)

endfor

// === 각 후보의 퍼포먼스 계산 (단순 누적 수익) ===

var array<float> perfList = array.new()

var array<int> factorList = array.new()

// 현재 BAR_COUNT(플랫폼에 따라 이름 다를 수 있음)

barsToEvaluate = min(barcount(), maxBars)

// for each candidate N, 시뮬레이션

for idx = 0 to array.size(candN)-1

N = array.get(candN, idx)

cash = 0.0

position = 0 // 0=flat, 1=long

entry_price = 0.0

// 시간 흐름: 오래된 -> 최신 (플랫폼 루프 방법에 따라 조정)

// 여기서는 i는 과거 offset (barsToEvaluate downto 1)

for offset = barsToEvaluate down to 1

// 전봉 기준 N기간 최고/최저 (함수명: HHV / LLV 또는 highest/lowest 로 바꿔서 사용)

hh = HHV(high, N, offset) // = offset번째 시점에서의 N기간 최고 (함수명 확인 필요)

ll = LLV(low, N, offset)

// 현재 바의 종가 (offset 시점)

c = ref(close, offset)

// 진입: 종가가 전봉 기준 N기간 최고 돌파 (전략 규칙)

if position == 0 and c > hh

position = 1

entry_price = c

endif

// 청산: 포지션 중 저가 이탈

if position == 1 and c < ll

profit = c - entry_price

cash = cash + profit

position = 0

entry_price = 0.0

endif

endfor

// 시뮬레이션 종료 시 미청산 포지션 정리(평가 목적)

if position == 1

last_close = close // 최신 종가

cash = cash + (last_close - entry_price)

endif

array.push(perfList, cash)

array.push(factorList, N)

endfor

// === 퍼포먼스 값에서 초기 centroid 계산 (25/50/75 percentile) ===

// 플랫폼에 percentile 함수가 없다면 간단 정렬 후 인덱스로 대체 가능

perf_sorted = array.copy(perfList)

array.sort(perf_sorted) // 오름차순

sizeP = array.size(perf_sorted)

p25_idx = max(0, floor(0.25 * (sizeP - 1)))

p50_idx = max(0, floor(0.50 * (sizeP - 1)))

p75_idx = max(0, floor(0.75 * (sizeP - 1)))

centroids = array.new()

array.push(centroids, array.get(perf_sorted, p25_idx))

array.push(centroids, array.get(perf_sorted, p50_idx))

array.push(centroids, array.get(perf_sorted, p75_idx))

// === K-means 1D 반복 ===

for iter = 1 to maxIter

// 초기화

clusters_perf = array.from(array.new(), array.new(), array.new())

clusters_factor = array.from(array.new(), array.new(), array.new())

// 할당 단계

for i = 0 to array.size(perfList)-1

val = array.get(perfList, i)

// 거리 계산

d0 = abs(val - array.get(centroids, 0))

d1 = abs(val - array.get(centroids, 1))

d2 = abs(val - array.get(centroids, 2))

// 가장 작은 거리 인덱스 선택

idx_min = 0

if d1 < d0

idx_min = 1

if d2 < d1

idx_min = 2

endif

else

if d2 < d0

idx_min = 2

endif

endif

// 클러스터에 추가

array.push(array.get(clusters_perf, idx_min), val)

array.push(array.get(clusters_factor, idx_min), array.get(factorList, i))

endfor

// 중심 재계산

new_centroids = array.new()

for k = 0 to 2

cperf = array.get(clusters_perf, k)

if array.size(cperf) > 0

sumv = 0.0

for j = 0 to array.size(cperf)-1

sumv = sumv + array.get(cperf, j)

endfor

avgv = sumv / array.size(cperf)

array.push(new_centroids, avgv)

else

// 빈 클러스터는 기존 centroid 유지

array.push(new_centroids, array.get(centroids, k))

endif

endfor

// 수렴 체크 (모두 같다면 종료)

if array.get(new_centroids,0) == array.get(centroids,0) and

array.get(new_centroids,1) == array.get(centroids,1) and

array.get(new_centroids,2) == array.get(centroids,2)

break

endif

centroids := new_centroids

endfor

// === 선택 클러스터 매핑 ('Worst'=0, 'Average'=1, 'Best'=2) ===

selIdx = 2

if fromCluster == "Worst" then selIdx = 0 endif

if fromCluster == "Average" then selIdx = 1 endif

// 선택 클러스터의 평균 N 계산 (없으면 기본값)

chosenN = defaultN

sel_factors = array.get(clusters_factor, selIdx)

if array.size(sel_factors) > 0

ssum = 0

for i = 0 to array.size(sel_factors)-1

ssum = ssum + array.get(sel_factors, i)

endfor

chosenN = round(ssum / array.size(sel_factors))

endif

// === 실시간 시그널: chosenN 사용 ===

// 최신 N기간 최고/최저 계산 (함수명 HHV/LLV 사용)

curr_hh = HHV(high, chosenN)

curr_ll = LLV(low, chosenN)

buySignal = close > curr_hh

sellSignal = close < curr_ll

// 출력(화면 및 알림용)

plot_int("ChosenN", chosenN)

plot_bool("Buy", buySignal)

plot_bool("Sell", sellSignal)

// 실제 주문/포지션 관리는 전략 엔진 규칙에 맞춰 작성


지표
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2025-10-27 17:06:23

안녕하세요. 예스스탁입니다. 올려주신 내용은 전반적인 내용 파악이 어려워 변환해 드리기 어렵습니다. 도움을 드리지 못해 죄송합니다. 즐거운 하루되세요