분류
공개스크립트
VAA 전략 백테스트
페이지 정보
본문
//@version=4 study("Vigilant Asset Allocation", "VAA") // * * * 입력 * * * // // 사용할 공수 자산 입력 offenseSym1 = input("AMEX:SPY", "공격 자산1 (미국 주식)", input.symbol) offenseSym2 = input("AMEX:EFA", "공격 자산2 (선진국 주식)", input.symbol) offenseSym3 = input("AMEX:EEM", "공격 자산3 (신흥국 주식)", input.symbol) offenseSym4 = input("AMEX:AGG", "공격 자산4 (미국 총 채권)", input.symbol) defenseSym1 = input("AMEX:LQD", "수비 자산1 (미국 회사채)", input.symbol) defenseSym2 = input("NASDAQ:IEF", "수비 자산2 (미국 중기채)", input.symbol) defenseSym3 = input("NASDAQ:SHY", "수비 자산3 (미국 단기채)", input.symbol) // 월별 거래 비용 cost = input(0.0, "편도 거래 비용(%)", input.float) // 백테스트 기간 설정 startYear = input(1, "시작 년") startMonth = input(1, "시작 월") startDay = input(1, "시작 일") endYear = input(9999, "종료 년") endMonth = input(12, "종료 월") endDay = input(31, "종료 일") startPeriod = timestamp(startYear, startMonth, startDay, 0, 0) endPeriod = timestamp(endYear, endMonth, endDay, 0, 0) testPeriod = time >= startPeriod and time <= endPeriod // 함수 정의 시작 // 종가 가져오기 getClose(sym) => security(sym, timeframe.period, close, barmerge.gaps_off, barmerge.lookahead_on) // 수익률 계산 getYield(src, m) => (src/src[m]-1)*100 // 모멘텀 스코어 계산 getScore(src) => 12 * getYield(src, 1) + 4 * getYield(src, 3) + 2 * getYield(src, 6) + 1 * getYield(src, 12) // 함수 정의 끝 // * * * 연산 * * * // // 공격적인 자산 종가 spy = getClose(offenseSym1) efa = getClose(offenseSym2) eem = getClose(offenseSym3) agg = getClose(offenseSym4) // 수비적인 자산 종가 lqd = getClose(defenseSym1) ief = getClose(defenseSym2) shy = getClose(defenseSym3) // 공격적인 자산의 모멘텀 스코어 scoreSPY = getScore(spy) scoreEFA = getScore(efa) scoreEEM = getScore(eem) scoreAGG = getScore(agg) // 수비적인 자산의 모멘텀 스코어 scoreLQD = getScore(lqd) scoreIEF = getScore(ief) scoreSHY = getScore(shy) // 모든 종목의 모멘텀 스코어가 존재하는가? isValue = not(na(scoreSPY[1]) or na(scoreEFA[1]) or na(scoreEEM[1]) or na(scoreAGG[1]) or na(scoreLQD[1]) or na(scoreIEF[1]) or na(scoreSHY[1])) // 공격 모드 판별 offenseCondition = not(min(scoreSPY, scoreEFA, scoreEEM, scoreAGG) < 0) // 공격형 자산 중 최고 모멘텀 스코어 scoreOffense = max(scoreSPY, scoreEFA, scoreEEM, scoreAGG) // 수비형 자산 중 최고 모멘텀 스코어 scoreDefense = max(scoreLQD, scoreIEF, scoreSHY) // 공수 자산의 최근 한달간의 수익률(누적 수익률을 구하기 위함) yieldSPY = getYield(spy, 1) yieldEFA = getYield(efa, 1) yieldEEM = getYield(eem, 1) yieldAGG = getYield(agg, 1) yieldLQD = getYield(lqd, 1) yieldIEF = getYield(ief, 1) yieldSHY = getYield(shy, 1) // 투자 종목별 색상 colorScore = offenseCondition ? ((scoreOffense == scoreSPY) ? color.red : (scoreOffense == scoreEFA) ? color.orange : (scoreOffense == scoreEEM) ? color.yellow : (scoreOffense == scoreAGG) ? color.green : na) : ((scoreDefense == scoreLQD) ? color.blue : (scoreDefense == scoreIEF) ? color.navy : (scoreDefense == scoreSHY) ? color.purple : na) // 월말 투자 종목 nextInvestment = offenseCondition ? ((scoreOffense == scoreSPY) ? "미국" : (scoreOffense == scoreEFA) ? "선진국" : (scoreOffense == scoreEEM) ? "신흥국" : (scoreOffense == scoreAGG) ? "미 총채권" : "") : ((scoreDefense == scoreLQD) ? "미 회사채" : (scoreDefense == scoreIEF) ? "미 중기채" : (scoreDefense == scoreSHY) ? "미 단기채" : "") // 전월과 보유 종목이 같으면 거래 비용 없음 realCost = cost + (nextInvestment[1] == nextInvestment ? 0 : cost) + (nextInvestment[1] == nextInvestment[2] ? - cost : 0) // 공수 전환으로 인해 선택된 자산의 월별 수익률 monthYield = (offenseCondition[1] ? ((scoreOffense[1] == scoreSPY[1]) ? yieldSPY : (scoreOffense[1] == scoreEFA[1]) ? yieldEFA : (scoreOffense[1] == scoreEEM[1]) ? yieldEEM : (scoreOffense[1] == scoreAGG[1]) ? yieldAGG : 0) : ((scoreDefense[1] == scoreLQD[1]) ? yieldLQD : (scoreDefense[1] == scoreIEF[1]) ? yieldIEF : (scoreDefense[1] == scoreSHY[1]) ? yieldSHY : 0)) - realCost // 월별 수익률 누적 결과 var yield = 0.0 yield := testPeriod ? (((1+yield/100) * (1+monthYield/100)) - 1) * 100 : 0.0 // 백테스트 기간에만 봉 갯수 세기 var barCount = 0 barCount := barCount + (testPeriod ? 1 : 0) // 연 복리 계산 cagr = (pow(1+yield/100, 1/((barCount)/12))-1)*100 // 최고 수익률 계산 var maxYield = 0.0 maxYield := max(maxYield, yield) // 손실폭 계산 var drawdown = 0.0 drawdown := (((1+yield/100)/(1+maxYield/100)) - 1) * 100 // 최대 손실폭 계산 var mdd = 0.0 mdd := min(mdd, drawdown) // * * * 출력 * * * // // 1. 공격 자산의 모멘텀 스코어 plot(scoreSPY, "미국", color.red, 1, plot.style_stepline) plot(scoreEFA, "선진국", color.orange, 1, plot.style_stepline) plot(scoreEEM, "신흥국", color.yellow, 1, plot.style_stepline) plot(scoreAGG, "미 총채권", color.green, 1, plot.style_stepline) // 2. 수비 자산의 모멘텀 스코어 plot(scoreLQD, "미 회사채", color.blue, 1, plot.style_stepline) plot(scoreIEF, "미 중기채", color.navy, 1, plot.style_stepline) plot(scoreSHY, "미 단기채", color.purple, 1, plot.style_stepline) // 3. 월별 수익률 & 월말 투자 종목 plot(testPeriod and isValue ? monthYield : na, "월별 수익률(%)", colorScore[1], 1, plot.style_columns) var labelNext = label.new(bar_index, 0, style = label.style_label_upper_left) label.set_xy(labelNext, bar_index, 0) label.set_color(labelNext, colorScore) label.set_text(labelNext, tostring(month) + "월말 투자 종목 : " + nextInvestment) // 4. 수익률 plot(testPeriod and isValue ? yield : na, "수익률(%)", color.purple) // 5. 연 복리 plot(testPeriod and isValue ? cagr : na, "연 복리(%)", color.green) // 6. 손실폭과 최대 손실폭 plot(testPeriod and isValue ? drawdown : na, "손실폭(%)", color.red) plot(testPeriod and isValue ? mdd : na, "최대 손실폭(%)", color.orange)