커뮤니티

Kalman지표를 변화과정에서 반복인 오류가 발생합니다.

프로필 이미지
jhs0713
2025-08-04 17:31:12
237
글번호 192963
답변완료
Tradingview에 있는 "Kalman Trend Levels [BigBeluga]"의 수식을 ChatGPT로 변환을 시켰습니다. 기존 코딩은 // This work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International // https://creativecommons.org/licenses/by-nc-sa/4.0/ // &#169; BigBeluga //@version=5 indicator("Kalman Trend Levels [BigBeluga]", overlay = true, max_labels_count = 500, max_boxes_count = 500) // INPUTS ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――{ int short_len = input.int(50) int long_len = input.int(150) bool retest_sig = input.bool(false, "Retest Signals") bool candle_color = input.bool(true, "Candle Color") color upper_col = input.color(#13bd6e, "up", inline = "colors") color lower_col = input.color(#af0d4b, "dn", inline = "colors") // } // CALCULATIONS――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――{ float atr = ta.atr(200) *0.5 var lower_box = box(na) var upper_box = box(na) // Kalman filter function kalman_filter(src, length, R = 0.01, Q = 0.1) => // Initialize variables var float estimate = na var float error_est = 1.0 var float error_meas = R * (length) var float kalman_gain = 0.0 var float prediction = na // Initialize the estimate with the first value of the source if na(estimate) estimate := src[1] // Prediction step prediction := estimate kalman_gain := error_est / (error_est + error_meas) estimate := prediction + kalman_gain * (src - prediction) error_est := (1 - kalman_gain) * error_est + Q / (length) // Adjust process noise based on length estimate float short_kalman = kalman_filter(close, short_len) float long_kalman = kalman_filter(close, long_len) bool trend_up = short_kalman > long_kalman color trend_col = trend_up ? upper_col : lower_col color trend_col1 = short_kalman > short_kalman[2] ? upper_col : lower_col color candle_col = candle_color ? (trend_up and short_kalman > short_kalman[2] ? upper_col : not trend_up and short_kalman < short_kalman[2] ? lower_col : color.gray) : na // } // PLOT ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――{ if trend_up and not trend_up[1] label.new(bar_index, short_kalman, "&#129145;₩n" + str.tostring(math.round(close,1)), color = color(na), textcolor = upper_col, style = label.style_label_up, size = size.normal) lower_box := box.new(bar_index, low+atr, bar_index, low, border_color = na, bgcolor = color.new(upper_col, 60)) if not ta.change(trend_up) lower_box.set_right(bar_index) if trend_up[1] and not trend_up label.new(bar_index, short_kalman, str.tostring(math.round(close,1))+"₩n&#129155;", color = color(na), textcolor = lower_col, style = label.style_label_down, size = size.normal) upper_box := box.new(bar_index, high, bar_index, high-atr, border_color = na, bgcolor = color.new(lower_col, 60)) if not ta.change(trend_up) upper_box.set_right(bar_index) if retest_sig if high < upper_box.get_bottom() and high[1]>= upper_box.get_bottom() //or high < lower_box.get_bottom() and high[1]>= lower_box.get_bottom() label.new(bar_index-1, high[1], "x", color = color(na), textcolor = lower_col, style = label.style_label_down, size = size.normal) if low > lower_box.get_top() and low[1]<= lower_box.get_top() label.new(bar_index-1, low[1], "+", color = color(na), textcolor = upper_col, style = label.style_label_up, size = size.normal) p1 = plot(short_kalman, "Short Kalman", color = trend_col1) p2 = plot(long_kalman, "Long Kalman", linewidth = 2, color = trend_col) fill(p1, p2, short_kalman, long_kalman, na, color.new(trend_col, 80)) plotcandle(open, high, low, close, title='Title', color = candle_col, wickcolor=candle_col, bordercolor = candle_col) // } 이렇게 되어 있습니다. 그리고 변환을 시켰을 때 // 예스트레이더 지표식: Kalman Trend Levels [BigBeluga] 변환본 (YesLanguage) // 차트 편집창용 지표 스크립트입니다. 충분한 주석을 참고하세요. Inputs: ShortLen(50), // 단기 칼만 필터 기간 LongLen(150), // 장기 칼만 필터 기간 RetestSig(False), // 리테스트 시그널 표시 여부 CandleColor(True), // 캔들 컬러링 사용 여부 UpColor(RGB(19,189,110)), // 상승 트렌드 색상 (녹색 계열) DnColor(RGB(175,13,75)); // 하락 트렌드 색상 (빨강 계열) Vars: // 단기 칼만 필터 내부 변수 ShortEst(0), // 단기 추정치 ShortErrEst(1), // 단기 오차 추정치 ShortErrMeas(0), // 단기 측정 오차 ShortKGain(0), // 단기 칼만 이득 PredShort(0), // 단기 예측치 // 장기 칼만 필터 내부 변수 LongEst(0), // 장기 추정치 LongErrEst(1), // 장기 오차 추정치 LongErrMeas(0), // 장기 측정 오차 LongKGain(0), // 장기 칼만 이득 PredLong(0), // 장기 예측치 ATRVal(0), // ATR 값 (200 기간 * 0.5) // 박스 개체 ID 저장용 LowerBoxID(0), UpperBoxID(0), // 트렌드 상태 TrendUp(False), TrendCol(0), TrendCol1(0); // 측정 오차 초기화 (필터 길이에 비례) ShortErrMeas = 0.01 * ShortLen; LongErrMeas = 0.01 * LongLen; // ATR 계산: 200-period ATR의 절반 사용 ATRVal = ATR(200) * 0.5; // 첫 번째 바에서 초기 추정값 세팅 if CurrentBar = 1 then begin ShortEst = C; // 첫 봉의 종가로 초기화 LongEst = C; // 첫 봉의 종가로 초기화 end; // ===== 단기 칼만 필터 계산 ===== PredShort = ShortEst; // 예측 단계 ShortKGain = ShortErrEst / (ShortErrEst + ShortErrMeas); // 칼만 이득 ShortEst = PredShort + ShortKGain * (C - PredShort); // 추정치 보정 ShortErrEst = (1 - ShortKGain) * ShortErrEst + 0.1 / ShortLen; // 오차 추정치 갱신 // ===== 장기 칼만 필터 계산 ===== PredLong = LongEst; LongKGain = LongErrEst / (LongErrEst + LongErrMeas); LongEst = PredLong + LongKGain * (C - PredLong); LongErrEst = (1 - LongKGain) * LongErrEst + 0.1 / LongLen; // ===== 트렌드 판정 ===== TrendUp = ShortEst > LongEst; // 단기 > 장기 → 상승 TrendCol = Iff(TrendUp, UpColor, DnColor); // 트렌드 컬러 TrendCol1 = Iff(ShortEst > ShortEst[2], UpColor, DnColor); // 단기 추정 증감 색상 // ===== 차트 출력 ===== Plot1(ShortEst, "ShortKalman"); // 단기 칼만 필터 값 Plot2(LongEst, "LongKalman"); // 장기 칼만 필터 값 // 캔들 컬러링: PlotPaintBar 함수 사용 if CandleColor then PlotPaintBar( O, H, L, C, Iff(TrendUp and (ShortEst > ShortEst[2]), UpColor, Iff((not TrendUp) and (ShortEst < ShortEst[2]), DnColor, RGB(128,128,128))) // 그 외는 회색 ); // ===== 트렌드 전환 시 화살표 및 박스 표시 ===== // 상승 전환: 상승 화살표 및 하단 박스 if (TrendUp) and (not TrendUp[1]) then begin Text_New( Date, Time, ShortEst, "&#129145; " + NumToStr(C, 1) // 화살표 + 종가(소수점 1자리) ); LowerBoxID = Box_New( Date, Time, L, Date, Time, L + ATRVal ); Box_SetFill(LowerBoxID, UpColor); // 박스 내부 채움 색 Box_SetExtFill(LowerBoxID, True); // 차트 전체 영역으로 확장 end; // 하락 전환: 하락 화살표 및 상단 박스 if (not TrendUp) and (TrendUp[1]) then begin Text_New( Date, Time, ShortEst, NumToStr(C, 1) + " &#129155;" // 종가 + 하락 화살표 ); UpperBoxID = Box_New( Date, Time, H + ATRVal, Date, Time, H ); Box_SetFill(UpperBoxID, DnColor); Box_SetExtFill(UpperBoxID, True); end; // ===== 리테스트 시그널 (옵션) ===== if RetestSig then begin // 상승 박스 상단 돌파 리테스트 표시 if (H < Box_GetEndVal(UpperBoxID)) and (H[1] >= Box_GetEndVal(UpperBoxID)) then Text_New(Date, Time, H, "x"); // 하락 박스 하단 돌파 리테스트 표시 if (L > Box_GetEndVal(LowerBoxID)) and (L[1] <= Box_GetEndVal(LowerBoxID)) then Text_New(Date, Time, L, "+"); end; 몇가지 단순 오류를 고쳤지만, 반복적인 수정을 하니 내용을 편집해서 결론을 내는 것을 확인했습니다. 이런 수정이 가능할까요?
지표
답변 2
프로필 이미지

예스스탁 예스스탁 답변

2025-08-05 13:09:35

input : short_len(50); input : long_len(150); input : retest_sig(false); input : candle_color(true); input : upper_col(Green); input : lower_col(Maroon); var : alpha(0),AR(0),A(0); var : R(0.01),Q(0.1); var : short_estimate(Nan),short_error_est(1.0),short_error_meas(R * (short_len)); var : short_kalman_gain(0),short_prediction(Nan),short_kalman(0); var : Long_estimate(Nan),Long_error_est(1.0),Long_error_meas(R * (Long_len)); var : Long_kalman_gain(0),Long_prediction(Nan),Long_kalman(0); var : trend_up(False); var : trend_col(0),trend_col1(0),candle_col(0); var : tx1(0),tx2(0),box1(0),box2(0); alpha = 1 / 200 ; A = iff(IsNan(A[1]) == true , ma(TrueRange, 200) , alpha * TrueRange + (1 - alpha) * iff(IsNan(A[1]) == true,0,A[1])); AR = A*0.5; if isnan(short_estimate) == true Then short_estimate = C[1]; short_prediction = short_estimate; short_kalman_gain = short_error_est / (short_error_est + short_error_meas); short_estimate = short_prediction + short_kalman_gain * (C - short_prediction); short_error_est = (1 - short_kalman_gain) * short_error_est + Q / (short_len); short_kalman = short_estimate; if isnan(Long_estimate) == true Then Long_estimate = C[1]; Long_prediction = Long_estimate; Long_kalman_gain = Long_error_est / (Long_error_est + Long_error_meas); Long_estimate = Long_prediction + Long_kalman_gain * (C - Long_prediction); Long_error_est = (1 - Long_kalman_gain) * Long_error_est + Q / (Long_len); Long_kalman = Long_estimate; trend_up = short_kalman > long_kalman; trend_col = iff(trend_up , upper_col , lower_col); trend_col1 = iff(short_kalman > short_kalman[2] , upper_col , lower_col); candle_col = iff(candle_color , IFf(trend_up == true and short_kalman > short_kalman[2] , upper_col , iff(trend_up == False and short_kalman < short_kalman[2] , lower_col , gray)) , Black); if Crossup(short_kalman,long_kalman) Then { tx1 = text_new(sDate,sTime,min(L,long_kalman),"▲"); tx2 = text_new(sDate,sTime,min(L,long_kalman),NewLine+NumToStr(C,2)); Text_SetStyle(tx1,2,0); Text_SetStyle(tx2,2,0); Text_SetColor(tx1,trend_col); Text_SetColor(tx2,trend_col); var1 = Low+AR; var2 = Low; box1 = Box_New(sDate,sTime,var1,NextBarSdate,NextBarStime,var2); Box_SetColor(box1,trend_col); Box_SetFill(box1,true); } Else Box_SetEnd(box1,sDate,stime,var2); if CrossDown(short_kalman,long_kalman) Then { tx1 = text_new(sDate,sTime,max(H,long_kalman),"▼"); tx2 = text_new(sDate,sTime,max(H,long_kalman),NumToStr(C,2)+NewLine); Text_SetStyle(tx1,2,1); Text_SetStyle(tx2,2,1); Text_SetColor(tx1,trend_col); Text_SetColor(tx2,trend_col); var3 = high; var4 = high-A; box2 = Box_New(sDate,sTime,var3,NextBarSdate,NextBarStime,var4); Box_SetColor(box2,trend_col); Box_SetFill(box2,true); } Else Box_SetEnd(box2,sDate,stime,var4); plot1(short_kalman, "Short Kalman", trend_col1); plot2(long_kalman, "Long Kalman", trend_col); > jhs0713 님이 쓴 글입니다. > 제목 : Kalman지표를 변화과정에서 반복인 오류가 발생합니다. > Tradingview에 있는 "Kalman Trend Levels [BigBeluga]"의 수식을 ChatGPT로 변환을 시켰습니다. 기존 코딩은 // This work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International // https://creativecommons.org/licenses/by-nc-sa/4.0/ // &#169; BigBeluga //@version=5 indicator("Kalman Trend Levels [BigBeluga]", overlay = true, max_labels_count = 500, max_boxes_count = 500) // INPUTS ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――{ int short_len = input.int(50) int long_len = input.int(150) bool retest_sig = input.bool(false, "Retest Signals") bool candle_color = input.bool(true, "Candle Color") color upper_col = input.color(#13bd6e, "up", inline = "colors") color lower_col = input.color(#af0d4b, "dn", inline = "colors") // } // CALCULATIONS――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――{ float atr = ta.atr(200) *0.5 var lower_box = box(na) var upper_box = box(na) // Kalman filter function kalman_filter(src, length, R = 0.01, Q = 0.1) => // Initialize variables var float estimate = na var float error_est = 1.0 var float error_meas = R * (length) var float kalman_gain = 0.0 var float prediction = na // Initialize the estimate with the first value of the source if na(estimate) estimate := src[1] // Prediction step prediction := estimate kalman_gain := error_est / (error_est + error_meas) estimate := prediction + kalman_gain * (src - prediction) error_est := (1 - kalman_gain) * error_est + Q / (length) // Adjust process noise based on length estimate float short_kalman = kalman_filter(close, short_len) float long_kalman = kalman_filter(close, long_len) bool trend_up = short_kalman > long_kalman color trend_col = trend_up ? upper_col : lower_col color trend_col1 = short_kalman > short_kalman[2] ? upper_col : lower_col color candle_col = candle_color ? (trend_up and short_kalman > short_kalman[2] ? upper_col : not trend_up and short_kalman < short_kalman[2] ? lower_col : color.gray) : na // } // PLOT ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――{ if trend_up and not trend_up[1] label.new(bar_index, short_kalman, "&#129145;₩n" + str.tostring(math.round(close,1)), color = color(na), textcolor = upper_col, style = label.style_label_up, size = size.normal) lower_box := box.new(bar_index, low+atr, bar_index, low, border_color = na, bgcolor = color.new(upper_col, 60)) if not ta.change(trend_up) lower_box.set_right(bar_index) if trend_up[1] and not trend_up label.new(bar_index, short_kalman, str.tostring(math.round(close,1))+"₩n&#129155;", color = color(na), textcolor = lower_col, style = label.style_label_down, size = size.normal) upper_box := box.new(bar_index, high, bar_index, high-atr, border_color = na, bgcolor = color.new(lower_col, 60)) if not ta.change(trend_up) upper_box.set_right(bar_index) if retest_sig if high < upper_box.get_bottom() and high[1]>= upper_box.get_bottom() //or high < lower_box.get_bottom() and high[1]>= lower_box.get_bottom() label.new(bar_index-1, high[1], "x", color = color(na), textcolor = lower_col, style = label.style_label_down, size = size.normal) if low > lower_box.get_top() and low[1]<= lower_box.get_top() label.new(bar_index-1, low[1], "+", color = color(na), textcolor = upper_col, style = label.style_label_up, size = size.normal) p1 = plot(short_kalman, "Short Kalman", color = trend_col1) p2 = plot(long_kalman, "Long Kalman", linewidth = 2, color = trend_col) fill(p1, p2, short_kalman, long_kalman, na, color.new(trend_col, 80)) plotcandle(open, high, low, close, title='Title', color = candle_col, wickcolor=candle_col, bordercolor = candle_col) // } 이렇게 되어 있습니다. 그리고 변환을 시켰을 때 // 예스트레이더 지표식: Kalman Trend Levels [BigBeluga] 변환본 (YesLanguage) // 차트 편집창용 지표 스크립트입니다. 충분한 주석을 참고하세요. Inputs: ShortLen(50), // 단기 칼만 필터 기간 LongLen(150), // 장기 칼만 필터 기간 RetestSig(False), // 리테스트 시그널 표시 여부 CandleColor(True), // 캔들 컬러링 사용 여부 UpColor(RGB(19,189,110)), // 상승 트렌드 색상 (녹색 계열) DnColor(RGB(175,13,75)); // 하락 트렌드 색상 (빨강 계열) Vars: // 단기 칼만 필터 내부 변수 ShortEst(0), // 단기 추정치 ShortErrEst(1), // 단기 오차 추정치 ShortErrMeas(0), // 단기 측정 오차 ShortKGain(0), // 단기 칼만 이득 PredShort(0), // 단기 예측치 // 장기 칼만 필터 내부 변수 LongEst(0), // 장기 추정치 LongErrEst(1), // 장기 오차 추정치 LongErrMeas(0), // 장기 측정 오차 LongKGain(0), // 장기 칼만 이득 PredLong(0), // 장기 예측치 ATRVal(0), // ATR 값 (200 기간 * 0.5) // 박스 개체 ID 저장용 LowerBoxID(0), UpperBoxID(0), // 트렌드 상태 TrendUp(False), TrendCol(0), TrendCol1(0); // 측정 오차 초기화 (필터 길이에 비례) ShortErrMeas = 0.01 * ShortLen; LongErrMeas = 0.01 * LongLen; // ATR 계산: 200-period ATR의 절반 사용 ATRVal = ATR(200) * 0.5; // 첫 번째 바에서 초기 추정값 세팅 if CurrentBar = 1 then begin ShortEst = C; // 첫 봉의 종가로 초기화 LongEst = C; // 첫 봉의 종가로 초기화 end; // ===== 단기 칼만 필터 계산 ===== PredShort = ShortEst; // 예측 단계 ShortKGain = ShortErrEst / (ShortErrEst + ShortErrMeas); // 칼만 이득 ShortEst = PredShort + ShortKGain * (C - PredShort); // 추정치 보정 ShortErrEst = (1 - ShortKGain) * ShortErrEst + 0.1 / ShortLen; // 오차 추정치 갱신 // ===== 장기 칼만 필터 계산 ===== PredLong = LongEst; LongKGain = LongErrEst / (LongErrEst + LongErrMeas); LongEst = PredLong + LongKGain * (C - PredLong); LongErrEst = (1 - LongKGain) * LongErrEst + 0.1 / LongLen; // ===== 트렌드 판정 ===== TrendUp = ShortEst > LongEst; // 단기 > 장기 → 상승 TrendCol = Iff(TrendUp, UpColor, DnColor); // 트렌드 컬러 TrendCol1 = Iff(ShortEst > ShortEst[2], UpColor, DnColor); // 단기 추정 증감 색상 // ===== 차트 출력 ===== Plot1(ShortEst, "ShortKalman"); // 단기 칼만 필터 값 Plot2(LongEst, "LongKalman"); // 장기 칼만 필터 값 // 캔들 컬러링: PlotPaintBar 함수 사용 if CandleColor then PlotPaintBar( O, H, L, C, Iff(TrendUp and (ShortEst > ShortEst[2]), UpColor, Iff((not TrendUp) and (ShortEst < ShortEst[2]), DnColor, RGB(128,128,128))) // 그 외는 회색 ); // ===== 트렌드 전환 시 화살표 및 박스 표시 ===== // 상승 전환: 상승 화살표 및 하단 박스 if (TrendUp) and (not TrendUp[1]) then begin Text_New( Date, Time, ShortEst, "&#129145; " + NumToStr(C, 1) // 화살표 + 종가(소수점 1자리) ); LowerBoxID = Box_New( Date, Time, L, Date, Time, L + ATRVal ); Box_SetFill(LowerBoxID, UpColor); // 박스 내부 채움 색 Box_SetExtFill(LowerBoxID, True); // 차트 전체 영역으로 확장 end; // 하락 전환: 하락 화살표 및 상단 박스 if (not TrendUp) and (TrendUp[1]) then begin Text_New( Date, Time, ShortEst, NumToStr(C, 1) + " &#129155;" // 종가 + 하락 화살표 ); UpperBoxID = Box_New( Date, Time, H + ATRVal, Date, Time, H ); Box_SetFill(UpperBoxID, DnColor); Box_SetExtFill(UpperBoxID, True); end; // ===== 리테스트 시그널 (옵션) ===== if RetestSig then begin // 상승 박스 상단 돌파 리테스트 표시 if (H < Box_GetEndVal(UpperBoxID)) and (H[1] >= Box_GetEndVal(UpperBoxID)) then Text_New(Date, Time, H, "x"); // 하락 박스 하단 돌파 리테스트 표시 if (L > Box_GetEndVal(LowerBoxID)) and (L[1] <= Box_GetEndVal(LowerBoxID)) then Text_New(Date, Time, L, "+"); end; 몇가지 단순 오류를 고쳤지만, 반복적인 수정을 하니 내용을 편집해서 결론을 내는 것을 확인했습니다. 이런 수정이 가능할까요?
프로필 이미지

jhs0713

2025-08-05 13:53:19

감사합니다.