이동평균 거래 전략


생성 날짜: 2023-10-30 15:53:25 마지막으로 수정됨: 2023-10-30 15:53:25
복사: 3 클릭수: 611
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

이동평균 거래 전략

개요

이 전략은 평준선 시스템을 사용하여 현재 트렌드 방향을 판단하고, 트렌드 방향에 따라 더 많은 공백을 한다. 평준선이 상승하면 관측 신뢰도가 높고, 더 많은 공백을 한다. 평준선이 떨어지면 관측 신뢰도가 높고, 공백을 한다. 이 전략은 주로 평준선 시스템을 통해 시장의 방향을 판단하고, 트렌드 따르는 유형의 전략이다.

전략 원칙

  1. 일정 주기 (기본 400주기) 의 가중 이동 평균vwma를 평균선 지표로 계산한다.

  2. 평균선vwma가 상승했는지 판단하기 위해, 상승하면 uptrend를 볼 수 있고, 하락하면 downtrend을 볼 수 있습니다.

  3. 위 추세가 사실이라면 더 많이 하고, 하향 추세가 사실이라면 공백을 다.

  4. 각 K선에 대한 전략 수익률 bar_pnl와 구매 보유 수익률 bar_bh를 계산한다.

  5. 분기 및 연간 단점에 따라, 각 분기 및 연간 전략 수익률 quarter_pnl 및 연간 수익률 year_pnl 및 그에 따른 구매 보유 수익률 quarter_bh 및 year_bh를 계산하십시오.

  6. 이 표는 매년 각 분기마다 전략 수익률과 구매 보유 수익률을 보여줍니다.

전략적 강점 분석

이 전략은 주로 시장의 추세 방향에 대한 평평선 판단에 의존하며 다음과 같은 장점이 있습니다:

  1. 작동이 간단하고, 평균적인 지표로 시장의 움직임을 판단하고, 쉽게 이해할 수 있다.

  2. 회수 제어 능력은 강하고, 트렌드 동작을 따라, 비 트렌드 시장의 손실을 효과적으로 제어할 수 있다.

  3. 구성 가능한 매개 변수가 적고, 주로 평균선주기를 조정하고, 테스트를 쉽게 최적화한다.

  4. 이 표를 통해 수익을 직관적으로 보여주는 것은 당연하다.

  5. 수익표에 구매 보유 수익을 추가하여 비교하여 전략적 인수 수익을 명확히 할 수 있습니다.

  6. 다른 정책과 결합하기 위해 테이블 위치를 유연하게 설정할 수 있습니다.

전략적 위험 분석

이 전략에는 몇 가지 위험도 있습니다.

  1. 대량 시장 위험, 장기간 지속되는 황소 시장에서 구매 전략에 비해 수익이 약간 낮을 수 있습니다. 평균 주기를 적절히 조정하여 최적화 할 수 있습니다.

  2. 위기 상황에서는 whipsaw 위험이 크다. 반복되는 거래를 줄이기 위해, 파기 전 최고점과 같은 필터링 조건을 추가하는 것을 고려할 수 있다.

  3. 평균선 시스템은 곡선에 적합하지 않으며, 트렌드 전환점을 놓칠 수 있다. 다른 유형의 평균선 지표를 실험할 수 있다.

  4. 손해제출 메커니즘을 고려하지 않고, 큰 철회 위험이 있습니다. 동적 손해를 설정하거나 위치를 줄이는 것을 고려할 수 있습니다.

  5. 표 최적화 측면에서, sharpe ratio, 최대 회수 등의 위험 지표를 추가하는 것을 고려할 수 있다.

전략 최적화 방향

이 전략은 다음과 같은 부분에서 최적화될 수 있습니다.

  1. 평균선 매개 변수를 최적화하고, 평균선 주기를 다른 시장 환경에 맞게 조정한다.

  2. 위프사우를 줄이기 위해 기 전의 고점과 같은 필터링 조건을 추가합니다.

  3. 다른 종류의 평균, 가중계 이동 평균, 이중 지수 이동 평균 등으로 시도하십시오.

  4. 손해 중지 메커니즘에 가입하여 동적 손해 중지 또는 지위를 낮추는 것을 고려할 수 있습니다.

  5. 셰어피스 비율, 최대 회수 등과 같은 지표들을 추가하여 셰어피스 내용을 풍부하게 한다.

  6. MACD, Bollinger Bands 등과 같은 다른 지표와 결합하여 추세를 판단하십시오.

  7. 포지션 관리를 최적화하고, 시장 상황에 따라 포지션을 동적으로 조정한다.

  8. 다양한 표준의 작동 효과를 테스트하여 최적의 적용 범위를 찾습니다.

요약하다

이 평행 거래 전략은 전체적으로 간단하고 직설적이며, 평행 판단을 통해 트렌드 조작, 회수 제어 능력이 강하며, 트렌드형 거래자에게 적합하다. 최적화 공간이 넓고, 평행 시스템, 손해 차단 장치, 포지션 관리 등의 측면에서 최적화 할 수 있어 전략이 복잡한 시장 환경에 더 적합하다. 표 디자인은 전략과 보유 수익을 비교하여 전략의 부가가치를 직관적으로 보여줍니다. 이 전략의 효과적인 프레임 워크와 표 표시 아이디어는 수량화 거래자에게는 약간의 견본 역할을합니다.

전략 소스 코드
/*backtest
start: 2022-10-23 00:00:00
end: 2023-10-29 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Dannnnnnny

//@version=4
strategy(title="Quarterly Returns in Strategies vs Buy & Hold", initial_capital= 1000, overlay=true,default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.1)
maLength= input(400)

wma= vwma(hl2,maLength)
uptrend= rising(wma, 5)
downtrend= falling(wma,5)

plot(wma)

if uptrend
    strategy.entry("Buy", strategy.long)
else
    strategy.close("Buy")//

///////////////////
// QUARTERLY TABLE //
enableQuarterlyTable = input(title="Enable Quarterly Return table", type=input.bool, defval=false)
enableCompareWithMarket = input(title="Compare with Market Benchmark", type=input.bool, defval=false)
table_position = input(title="Table Position", type=input.string, defval='bottom_right', options=['bottom_right','bottom_left','top_right', 'top_left'])
precision = 2
new_quarter = ceil(month(time)/3)  != ceil(month(time[1])/3)
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1
bar_bh = (close-close[1])/close[1]

cur_quarter_pnl = 0.0
cur_year_pnl  = 0.0
cur_quarter_bh = 0.0
cur_year_bh  = 0.0

// Current Quarterly P&L
cur_quarter_pnl := new_quarter ? 0.0 : 
                 (1 + cur_quarter_pnl[1]) * (1 + bar_pnl) - 1 
cur_quarter_bh := new_quarter ? 0.0 : 
                 (1 + cur_quarter_bh[1]) * (1 + bar_bh) - 1

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
cur_year_bh := new_year ? 0.0 : 
                 (1 + cur_year_bh[1]) * (1 + bar_bh) - 1

// Arrays to store Yearly and Quarterly P&Ls
var quarter_pnl  = array.new_float(0)
var quarter_time = array.new_int(0)
var quarter_bh  = array.new_float(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)
var year_bh  = array.new_float(0)

end_time = false

end_time:= time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory

if (not na(cur_quarter_pnl[1]) and (new_quarter or end_time))
    if (end_time[1])
        array.pop(quarter_pnl)
        array.pop(quarter_time)
        
    array.push(quarter_pnl , cur_quarter_pnl[1])
    array.push(quarter_time, time[1])
    array.push(quarter_bh , cur_quarter_bh[1])

if (not na(cur_year_pnl[1]) and (new_year or end_time))
    if (end_time[1])
        array.pop(year_pnl)
        array.pop(year_time)
        
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])
    array.push(year_bh , cur_year_bh[1])

// Quarterly P&L Table    
var quarterly_table = table(na)

getCellColor(pnl, bh)  => 
    if pnl > 0
        if bh < 0 or pnl > 2 * bh
            color.new(color.green, transp = 20)
        else if pnl > bh
            color.new(color.green, transp = 50)
        else
            color.new(color.green, transp = 80)
    else
        if bh > 0 or pnl < 2 * bh
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if (end_time and enableQuarterlyTable)
    quarterly_table := table.new(table_position, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(quarterly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(quarterly_table, 1,  0, "Q1",  bgcolor = #cccccc)
    table.cell(quarterly_table, 2,  0, "Q2",  bgcolor = #cccccc)
    table.cell(quarterly_table, 3,  0, "Q3",  bgcolor = #cccccc)
    table.cell(quarterly_table, 4,  0, "Q4",  bgcolor = #cccccc)
    table.cell(quarterly_table, 5,  0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(quarterly_table, 0,  yi + 1, tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi))
        table.cell(quarterly_table, 5, yi + 1, enableCompareWithMarket ? tostring(round(array.get(year_pnl, yi) * 100, precision)) + " (" + tostring(round(array.get(year_bh, yi) * 100, precision)) + ")" : tostring(round(array.get(year_pnl, yi) * 100, precision)), bgcolor = y_color, text_color=#bfbfbf)
        
    for mi = 0 to array.size(quarter_time) - 1
        m_row   = year(array.get(quarter_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = ceil(month(array.get(quarter_time, mi)) / 3)
        m_color = getCellColor(array.get(quarter_pnl, mi), array.get(quarter_bh, mi))
        
        table.cell(quarterly_table, m_col, m_row, enableCompareWithMarket ?  tostring(round(array.get(quarter_pnl, mi) * 100, precision)) + " (" + tostring(round(array.get(quarter_bh, mi) * 100,precision)) +")" : tostring(round(array.get(quarter_pnl, mi) * 100, precision)), bgcolor = m_color, text_color=#bfbfbf)