동적 전략 분석 도구

저자:차오장, 날짜: 2023-10-13 15:54:35
태그:

전반적인 설명

이 전략의 주요 아이디어는 실시간 거래를 시뮬레이션하고, 주간 거래 데이터를 수집하고, 전략의 성과를 보다 직관적으로 검토할 수 있도록 통계를 표로 제시하는 것입니다. 전략의 이익과 손실을 빠르게 평가하고, 열악한 성과 기간을 식별하고, 그에 따라 전략을 최적화하는 데 도움이 될 수 있습니다.

전략 논리

  1. 계산 기간의 시작 및 종료 시간을 설정합니다.

  2. 통계치의 정확성과 각 그룹의 주 수를 설정합니다.

  3. 입구와 출구에 대한 RSI 전략을 시뮬레이션합니다.

  4. 통계 테이블에 변수를 정의합니다.

  5. 현재 기간에 대한 결과를 계산합니다.

  6. 기간 변경 및 거래가 활성화되면 이 기간의 시간 및 결과를 기록합니다.

  7. 만약 마지막 바이고 거래가 활성화되면 현재 기간의 시간과 결과를 기록합니다.

  8. 기간이 변경되고 거래가 비활성화되면 이전 기간의 시간과 결과를 기록합니다.

  9. 가장 높고 가장 낮은 기간 결과를 찾아보세요.

  10. 통계 표를 돌려주세요.

  • 먼저 통계기간의 총 수를 계산합니다

  • 각 기간을 반복, 헤더, 시간 및 결과를 렌더링

  • 각 그룹에 대한 결과를 종합적으로 계산

  • 색상 코드 긍정적 및 부정적 결과

이점 분석

  • 빠른 전략 평가를 위해 실시간으로 주간 결과를 관찰 할 수 있습니다.

  • 명확한 통찰력을 위한 직관적인 결과 발표

  • 전략 조정을 위해 낮은 성과 기간을 식별하는 데 도움이 됩니다.

  • 장기 전략의 누적 이득을 추적하기 편리합니다.

  • 다른 기간에 걸쳐 거래 스타일을 비교할 수 있습니다.

  • 다양한 필요를 충족시키기 위해 사용자 정의 할 수있는 정확성 및 그룹

  • 간단하고 명확한 코드, 이해하기 쉽고 확장

위험 분석

  • 이 전략은 RSI를 기반으로 합니다.

  • 거래 비용은 실제 결과에 상당한 영향을 줄 수 있습니다.

  • 백테스트 데이터는 실제 시장 상황을 반영하지 않을 수 있습니다.

  • 백테스트에서 채무불이행자본은 실제 계좌 크기와 일치하지 않을 수 있습니다.

  • 통계에 기초한 매개 변수를 맹목적으로 조정하여 과장 조정을 피하십시오.

트렌드에 대한 더 많은 지표를 통합하고 기본 RSI 전략을 개선하기 위해 입출구를 최적화 할 수 있습니다. 라이브 거래에서 실제 거래 비용을 사용하십시오. 백테스트에서 자본 크기에 무작위성을 추가하십시오. 통계에 기반한 과도한 조정 대신 회의감을 유지하십시오.

최적화 방향

  • 하락률을 제한하기 위해 스톱 로스를 추가하는 것을 고려하십시오.

  • 과잉 구매 및 과잉 판매 수준과 같은 RSI 매개 변수를 최적화

  • 다른 거래 주파수를 시도해 보세요.

  • 추세와 타이밍에 대한 더 많은 지표를 포함

  • 이윤 추출 논리를 추가

  • 통계 매개 변수 설정을 최적화

  • 여러 재산을 추적할 수 있도록 확장

스톱은 리스크/리워드를 더 잘 관리할 수 있다. RSI 튜닝은 승률을 향상시킨다. 더 많은 지표와 주파수가 전략을 견고하게 한다. 통계적 튜닝은 중요한 데이터를 강조한다. 여러 자산으로 확장하면 완전한 시각을 얻을 수 있다.

요약

목표는 직관적인 통계 시각화를 위해 주기적인 결과를 수집하여 시간에 따라 성능을 빠르게 판단하는 것입니다. 이것은 전략을 최적화하기위한 데이터를 제공합니다. 강점에는 실시간 주간 결과, 명확성 및 확장성이 포함됩니다. 통계 출력과 과도한 의존과 곡선 적합성에 주의하십시오. 변경의 기초가 아닌 통찰력을 위해 핵심 전략 논리와 함께 합리적으로 사용하십시오. 전반적으로 성능을 평가하는 편리한 방법이며 최적화에 중요합니다.


/*backtest
start: 2023-09-12 00:00:00
end: 2023-10-12 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// strategy('Strategy weekly results as numbers v1', overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=25, commission_type=strategy.commission.percent, commission_value=0.04)

after = input(title='Trade after', defval=timestamp('01 Jan 2019 00:00 UTC'), tooltip="Strategy will be executed after this timestamp. The statistic table will include only periods after this date.")
before = input(title='Trade before', defval=timestamp('31 Dec 2024 23:59 UTC'), tooltip="Strategy will be executes before this timestamp. The statistic table will include only periods before this date.")

statisticPrecision = input.int(title='Statistic precision', group='Statistic visualisation', defval=1, tooltip="Defines how many digits should be rendered in every statistic cell.")
statisticGroupSize = input.int(title='Statistic group size', group='Statistic visualisation', defval=12, tooltip="Defines how many cells should be in one group inside the statistic table.")

// determinet whether the starategy should be traded between the period
isTradeEnabled = true


// *******************************************************************************************
// Core strategy simulation logic
// *******************************************************************************************
// calculate rsi strategy emulation data
rsiEmulationData = ta.rsi(close, 7)
rsiEmulationCrossover = ta.crossover(rsiEmulationData, 70)
rsiEmulationCrossunder = ta.crossunder(rsiEmulationData, 30)

// entry loogic based on the rsi calculations
if (isTradeEnabled and rsiEmulationCrossover)
    strategy.entry('Long', strategy.long)
if (isTradeEnabled and rsiEmulationCrossunder)
    strategy.entry('Short', strategy.short)


// *******************************************************************************************
// Weekly statistics table
// *******************************************************************************************
// define statistic variables
var statisticTable = table(na)
var statisticPeriodTime = array.new_int(0)
var statisticPeriodResult = array.new_float(0)
var statisticIsLatestCalculated = bool(na)
var statisticResultHighest = float(na)
var statisticResultLowest = float(na)
var statisticColorGray = color.new(color.gray, transp = 60)
var statisticColorGreen = color.new(color.green, transp = 60)
var statisticColorRed = color.new(color.red, transp = 60)

// claculate current period result
barResult = not na(strategy.equity[1])
             ? (strategy.equity / strategy.equity[1] - 1) : 0
isPeriodChanged = not na(time[1]) and weekofyear(time) != weekofyear(time[1])
currentPeriodResult = 0.0
currentPeriodResult := not na(currentPeriodResult[1]) and not isPeriodChanged
                       ? ((1 + currentPeriodResult[1]) * (1 + barResult) - 1) : 0.0

// initialise highest and lowest results variables
statisticResultHighest := na(statisticResultHighest) ? currentPeriodResult : statisticResultHighest
statisticResultLowest := na(statisticResultLowest) ? currentPeriodResult : statisticResultLowest

// search for highest and lowest results
statisticResultHighest := currentPeriodResult > statisticResultHighest ? currentPeriodResult : statisticResultHighest
statisticResultLowest := currentPeriodResult < statisticResultLowest ? currentPeriodResult : statisticResultLowest

// new week while trade is active
if isPeriodChanged and isTradeEnabled
    timeCalculated = time - 1000 * 60 * 60 * 24 * 7
    resultCalculated = currentPeriodResult[1]
    statisticIsLatestCalculated := false

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// latest bar while trade is active
if barstate.islast and isTradeEnabled
    timeCalculated = time - 1000 * 60 * 60 * 24 * (dayofweek(time) - 2)
    resultCalculated = currentPeriodResult

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// new week after trade disabled
if isPeriodChanged and not isTradeEnabled and not na(statisticIsLatestCalculated) and not statisticIsLatestCalculated
    timeCalculated = time - 1000 * 60 * 60 * 24 * (dayofweek(time) + 5)
    resultCalculated = currentPeriodResult[1]
    statisticIsLatestCalculated := true

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// render statistics table
if barstate.islast
    statisticLength = array.size(statisticPeriodResult)
    statisticTableSteps = math.floor(statisticLength / statisticGroupSize) + (statisticLength % statisticGroupSize != 0 ? 1 : 0)
    statisticTable := table.new(position.bottom_right, columns = statisticGroupSize + 2, rows = statisticTableSteps + 1, border_width = 1)

    // render headers
    for i = 0 to (statisticGroupSize - 1)
        statisticHeaderContent = str.tostring(i + 1)
        table.cell(statisticTable, 1 + i, 0, statisticHeaderContent, bgcolor = statisticColorGray)

    // render time points
    for i = 0 to (statisticTableSteps - 1)
        statisticPointContent = str.format("{0,date,medium}", array.get(statisticPeriodTime, i * statisticGroupSize))
        table.cell(statisticTable, 0, 1 + i, statisticPointContent, bgcolor = statisticColorGray)

    // render the result
    statisticResultCummulative = 0.0
    for i = 0 to (array.size(statisticPeriodTime) - 1)
        statisticColumn = 1 + i % statisticGroupSize
        statisticRow = 1 + math.floor(i / statisticGroupSize)

        statisticResult = array.get(statisticPeriodResult, i)
        statisticResultCummulative := (i % statisticGroupSize == 0) ? 0.0 : statisticResultCummulative
        statisticResultCummulative := (1 + statisticResultCummulative) * (1 + statisticResult) - 1

        statisticResultColor = statisticResult > 0 ? statisticColorGreen : statisticColorRed
        table.cell(statisticTable, statisticColumn, statisticRow, str.tostring(math.round(statisticResult * 100, statisticPrecision)), bgcolor = statisticResultColor)

        // if it is the last item of the row or data array
        isStatisticLastOfTheRow = ((i + 1) % statisticGroupSize) == 0
        isStatisticLastOfTheData = i == (statisticLength - 1)
        if (isStatisticLastOfTheRow or isStatisticLastOfTheData)
            resultsTableCummulativeCellColor = statisticResultCummulative > 0 ? statisticColorGreen : statisticColorRed
            resultsTableCummulativeCellContent = str.tostring(math.round(statisticResultCummulative * 100, statisticPrecision))
            table.cell(statisticTable, 1 + statisticGroupSize, statisticRow, resultsTableCummulativeCellContent, bgcolor = resultsTableCummulativeCellColor)

더 많은