리소스 로딩... 로딩...

FMZ Quant의 PINE 언어 소개 자습서

저자:FMZ~리디아, 창작: 2022-09-23 15:23:34, 업데이트: 2024-02-27 16:47:41

.3, 한계=3)

만약 바스테이트가 아니라면, 이시스토리를 닫고 < 오픈 전략 취소 전략 취소 (long2) 전략 취소 (long3) isStop:= true


---------------------------

6. ```strategy.cancel_all```

The ```strategy.cancel_all``` function is similar to the ```strategy.cancel``` function. It can cancel/stop all pre-listed commands. The ```when``` parameter can be specified.

Parameters:

- ```when```: Execution conditions.

```pine
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

strategy("strategy.cancel Demo", pyramiding=3)

var isStop = false 
if isStop 
    runtime.error("stop")

strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0.3, limit=3)

if not barstate.ishistory and close < open 
    strategy.cancel_all()
    isStop := true 

  1. strategy.order

기능 및 매개 변수 설정strategy.order기능은 거의strategy.entry그 차이점은strategy.order기능에 영향을 미치지 않습니다.pyramiding변수 설정strategy함수, 그리고 주문 수 제한이 없습니다.

매개 변수

  • id: 그것은 참조를 위해 거래 위치에 이름을 부여하는 것으로 이해 할 수 있습니다. id는 취소, 변경 주문 및 폐쇄 포지션을 참조 할 수 있습니다.
  • direction: 주문 방향이 길다면 (구입) 내장 변수를 입력합니다.strategy.long, 그리고 당신이 짧은 (판매) 가 가고 싶다면, 변수를 입력strategy.short.
  • qty: 주문 금액을 지정합니다. 이 매개 변수가 통과되지 않으면 기본 주문 금액이 사용됩니다.
  • when: 실행 조건, 당신은 이 매개 변수를 지정할 수 있습니다.
  • limit: 주문 한계 가격을 지정합니다.
  • stop: 스톱 로스 가격.

우리는 이 기능을 사용할 것입니다strategy.order주문 수에 제한이 없습니다.strategy.exit조건적 출구 함수는 그리드 거래와 유사한 스크립트를 구성합니다. 예제는 매우 간단하고 학습 목적으로만 사용됩니다.

/*backtest
start: 2021-03-01 00:00:00
end: 2022-08-30 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["ZPrecision",0,358374]]
*/

varip beginPrice = -1

if not barstate.ishistory
    if beginPrice == -1 or (math.abs(close - beginPrice) > 1000 and strategy.opentrades == 0) 
        beginPrice := close
    
    for i = 0 to 20
        strategy.order("buy"+i, strategy.long, 0.01, limit=beginPrice-i*200, when=(beginPrice-i*200)<close)
        strategy.exit("coverBuy"+i, "buy"+i, qty=0.01, profit=200)
        
        strategy.order("sell"+i, strategy.short, 0.01, limit=beginPrice+i*200, when=(beginPrice+i*200)>close)
        strategy.exit("coverSell"+i, "sell"+i, qty=0.01, profit=200)

전략 예제

이 튜토리얼에 있는 전략 예제들은 전략 설계 아이디어를 안내하기 위한 교육 목적으로만 제공되며, 거래 지침이나 조언을 위한 것이 아닙니다. 실제 거래에 대한 교육 전략을 사용하지 마십시오.

슈퍼 트렌드 지표 전략

strategy("supertrend", overlay=true)

[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))

plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr)
plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr)

if direction < 0
    if supertrend > supertrend[2]
        strategy.entry("entry long", strategy.long)
    else if strategy.position_size < 0
        strategy.close_all()
else if direction > 0
    if supertrend < supertrend[3]
        strategy.entry("entry short", strategy.short)
    else if strategy.position_size > 0
        strategy.close_all()

파인 언어를 사용하여 트렌드 전략을 작성하는 것은 매우 쉽습니다. 여기서 우리는 슈퍼 트렌드 지표로 간단한 트렌드 다음 전략을 설계합니다. 이 전략 소스 코드를 함께 분석해보겠습니다.

먼저, 전략 코드는 몇 가지 간단한 설정으로 시작합니다.strategy기능:strategy("supertrend", overlay=true)``, which just sets a strategy title "supertrend". The겹치기parameter is set to사실, so that the drawn indicator lines and other content are displayed on the main chart. The first thing we need to look at when designing a Pine strategy or learning a Pine strategy script is the strategy interface parameter design. Let's look at the source code of the ''supertrend indicator strategy'', which has the입력 `` ` 함수는 이전 강의에서 배웠어요

[슈퍼트렌드, 방향] = ta.슈퍼트렌드 (입수), 팩터 (faktor) ]input.int(10, atr 기간))

input함수 호출은 파라미터로 직접ta.supertrend슈퍼트렌드 지표를 계산하는 지표 기능

  • input ((5, faktor)
  • input.int(10, atr 기간)

기본적으로 이 함수는 아래와 같이 파이어 언어 전략 화면에 두 개의 매개 변수 컨트롤을 설정합니다.

img

우리가 볼 수 있듯이, 컨트롤의 기본 값은input기능 및input함수들의 일련 (여기에는input.int이 두 가지 함수로, 우리는 다음의 매개 변수를 설정할 수 있습니다.ta.supertrend전략 화면에서 기능.supertrend함수는 가격 데이터를 계산합니다supertrend그리고 방향 데이터direction그러면 우리는plot차트를 그리는 기능, 차트를 그리는 때, 그것은 슈퍼트렌드 지표의 방향에 기초하고, 현재 방향만 그려지는 것을 참고하십시오.direction-1, 현재 시장 추세는 상승합니다.direction현재 시장 추세는 하락하고 있습니다.plot기능은 판정을 할 때 차트를 그리는direction0보다 크거나 작습니다.

다음엔if... else if논리는 거래 신호의 판단입니다.direction < 0현재 시장이 상승 단계에 있다는 것을 의미합니다.supertrend슈퍼 트렌드 인디케이터의 가격은 두 개의 이전 BAR에서 슈퍼 트렌드 인디케이터의 가격보다 높습니다.supertrend[2], remember that the historical operator refers to the historical data of a variable), 그것은 긴 이동하기 위한 입구 신호로 사용될 것입니다. 기억하세요? 현재 위치가 있다면, 역 순서 기능을 호출하면 이전 위치를 먼저 닫고,supertrend > supertrend[2]이 조항이 이행되지 않는 한strategy.position_size < 0짧은 포지션을 유지하면strategy.close_all()모든 포지션을 닫는 기능 실행.

direction > 0하향 트렌드 단계에 있는 경우에도 동일합니다. 긴 지위가 있다면 모든 지위가 닫히고,supertrend < supertrend[3]이 신호가 충족되면 짧은 신호가 발사됩니다.[3]슈퍼 트렌드 인디케이터의 가격 데이터를 이전 번호의 세 번째 BAR에 참조하십시오. 전략 작가가 의도 할 수 있습니다. 결국, 계약 거래 시장과 같은 일부 시장에서 짧은 위험이 긴 위험보다 약간 더 높습니다.

에 대해ta.supertrend인디케이터, 현재 트렌드가 상승하거나 하락하는지를 판단하는 방법에 관심이 있습니까?

사실 이 지표는 파이어 언어의 사용자 정의 함수 형태로 구현될 수도 있습니다.

pine_supertrend(factor, atrPeriod) =>
	src = hl2
	atr = ta.atr(atrPeriod)
	upperBand = src + factor * atr
	lowerBand = src - factor * atr
	prevLowerBand = nz(lowerBand[1])
	prevUpperBand = nz(upperBand[1])

	lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
	upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
	int direction = na
	float superTrend = na
	prevSuperTrend = superTrend[1]
	if na(atr[1])
		direction := 1
	else if prevSuperTrend == prevUpperBand
		direction := close > upperBand ? -1 : 1
	else
		direction := close < lowerBand ? 1 : -1
	superTrend := direction == -1 ? lowerBand : upperBand
	[superTrend, direction]

이 사용자 정의 함수는 내장 함수와 정확히 같은 알고리즘입니다ta.supertrend, 그리고 물론 계산된 지표 데이터도 정확히 동일합니다. 이 사용자 정의 함수 알고리즘에서 볼 수 있듯이, Pine의 내장 슈퍼 트렌드 지표는hl2내장 변수 (최고 가격과 최저 가격이 더되고 2로 나뉘어, 즉 최고 가격과 최저 가격의 평균) 를 계산하고, 그 다음 ATR 지표 (변동성) 는 파라미터 atrPeriod를 기반으로 특정 기간 동안 계산됩니다.

업데이트lowerBand그리고upperBand코드의 세차 표현식에 따라.

    lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
    upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand

lowerBand: lowerBand, 상승 추세가 변했는지 확인하는 데 사용됩니다. upperBand: upperBand, 하락 추세가 변했는지 확인하는 데 사용됩니다. lowerBand와 upperBand는 항상 계산되며, 이 사용자 정의 함수의 끝에서 현재 트렌드 방향만 결정됩니다.

    else if prevSuperTrend == prevUpperBand
        direction := close > upperBand ? -1 : 1
    else
        direction := close < lowerBand ? 1 : -1

여기서는 슈퍼 트렌드의 마지막 BAR의 가격 값이prevUpperBand, 즉 상단파, 그것은 전류가 하향 추세를 나타냅니다.close를 초과upperBand가격 브레이크오프, 트렌드는 이 시점에서 전환되어 상승 추세로 전환된 것으로 간주됩니다. 방향 변수direction-1 (상향) 로 설정됩니다. 그렇지 않으면 여전히 1 (하향 추세) 로 설정됩니다. 그래서 슈퍼 트렌드 전략에서 볼 수 있습니다.if direction < 0신호 조건이 길게 가도록 트리거될 때direction > 0, 신호 조건이 단축되는 것을 유발합니다.

    superTrend := direction == -1 ? lowerBand : upperBand
    [superTrend, direction]

마지막으로, 특정 슈퍼 트렌드 지표 가격 데이터와 방향 데이터는 방향 선택에 따라 반환됩니다.

동적 균형 전략

/*backtest
start: 2021-03-01 00:00:00
end: 2022-09-08 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["v_input_1",4374],["v_input_2",3],["v_input_3",300],["ZPrecision",0,358374]]
*/

varip balance = input(50000, "balance")
varip stocks = input(0, "stocks")

maxDiffValue = input(1000, "maxDiffValue")


if balance - close * stocks > maxDiffValue and not barstate.ishistory
    // more balance , open long 
    tradeAmount = (balance - close * stocks) / 2 / close
    strategy.order("long", strategy.long, tradeAmount)
    balance := balance - tradeAmount * close
    stocks := stocks + tradeAmount
    runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)

else if close * stocks - balance > maxDiffValue and not barstate.ishistory
    // more stocks , open short 
    tradeAmount = (close * stocks - balance) / 2 / close
    strategy.order("short", strategy.short, tradeAmount)
    balance := balance + tradeAmount * close
    stocks := stocks - tradeAmount
    runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)

plot(balance, title="balance value(quoteCurrency)", color=color.red)
plot(stocks*close, title="stocks value(quoteCurrency)", color=color.blue)

img

img

파이어 언어 전략 설계 예제 몇 가지로 계속하자, 이번에는 동적 균형 전략을 배울 것입니다. 동적 균형 전략은 항상 양을 균형BaseCurrency그리고QuoteCurrency. 어떤 자산의 상대적 가격이 증가하든, 계좌에 보유한 가치가 증가하고 자산이 판매됩니다. 자산의 상대적 가격이 감소하면, 계좌에 보유한 가치가 감소하고 자산이 구입됩니다. 이것은 동적 균형 전략으로 알려져 있습니다. 사실, 동적 균형 전략은 변동 시장에서 잘 작동하는 일종의 그리드 전략입니다. 그러나 트렌드 시장에서, 그것은 돈을 잃는 것을 계속할 것입니다. 우리는 손실을 천천히 수익으로 줄이기 위해 가격이 돌아 오기를 기다려야하지만, 동적 균형 전략은 항상 시장의 변동 추세를 포착 할 수 있다는 장점이 있습니다.

이 전략의 백테스트 차트에서 보여지는 단점은 일반적인 가격 추세 상승 (또는 하락) 단계 동안 전략이 큰 부동 손실을 가지고 있다는 것입니다. 따라서이 전략은 스포트 전략에 적합하지만 미래에 대한 위험을 제어해야합니다.

전략 코드 디자인을 살펴봅시다.

단순화된 디자인을 사용해서balance(즉, QuoteCurrency 자산의 수) 및stocks(즉, 기본 통화 자산의 수) 전략의 균형 정보. 우리는 계정에서 실제 자산의 수를 읽지 않습니다, 우리는 단순히 적절한 구매 및 판매를 계산하기 위해 시뮬레이션 금액을 사용합니다.maxDiffValue, 즉 평준화 수행의 판단 기준입니다. 현재 가격에서는BaseCurrency그리고QuoteCurrency초과maxDiffValue이산화 재산의 재균형을 위해 높은 가격으로 자산을 판매하고 낮은 가격으로 자산을 구매하는 평형화 과정이 이루어지는지 여부

전략 거래 신호 트리거는 실시간 BAR 단계에 있어야 합니다.not barstate.ishistory구매할 때balance값은stocks현재 가격 계산에 기초한 값입니다. 반대로 판매 작전이 수행됩니다.balance그리고stocks변수가 업데이트되고 다음 균형 트리거를 기다립니다.

위 전략 백테스트의 정보는 전략 백테스트의 시작 시점에 종의 가격을 포함합니다. 가격은 1458입니다. 그래서 매개 변수를 설정합니다.balanceto: 4374 (1458*3) 의도적으로 매개 변수를 설정stocks3. 자산이 평형 상태에서 시작하도록 합니다.

트래킹 중지 손실 및 이익을 취득하는 슈퍼 트렌드 전략

이전 강의에서 우리는strategy.exit포지션 출구 함수, 우리는 추적 중지와 수익을 취함수를 설명하는 예를 가지고 있지 않습니다. 이 전략 설계 예제에서, 우리는strategy.exit슈퍼 트렌드 전략을 최적화하는 기능입니다.

먼저 Stop-Loss 및 Take-Profit 매개 변수를 살펴봅시다.strategy.exit기능:

  1. 매개 변수trail_price: 트래킹 스톱 로스 및 스톱 로스 클로즈 오더 (가격에 의해 지정된 위치) 를 배치하는 논리적 동작을 유발하는 위치.
  2. 매개 변수trail_offset: 트래킹 스톱 로스 및 트레이크 노프트 액션 실행 후 매입된 폐쇄된 포지션의 최고 (장시) 또는 최저 (단시) 가격과의 거리는
  3. 매개 변수trail_points예를 들어:trail_price매개 변수, 다만 그것은 지정된 위치로 수익 포인트를 취합니다.

이해하기가 쉽지 않나요? 상관없습니다. 이해하기 위해 전략 백테스팅 시나리오를 살펴보죠.

/*backtest
start: 2022-09-23 00:00:00
end: 2022-09-23 08:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/

strategy("test", overlay = true)

varip a = na
varip highPrice = na
varip isTrade = false 
varip offset = 30

if not barstate.ishistory and not isTrade
    strategy.entry("test 1", strategy.long, 1)
    strategy.exit("exit 1", "test 1", 1, trail_price=close+offset, trail_offset=offset)
    a := close + offset
    runtime.log("the price per point is:", syminfo.mintick, ", current close:", close)
    isTrade := true 

if close > a and not barstate.ishistory
    highPrice := na(highPrice) ? close : highPrice
    highPrice := close > highPrice ? close : highPrice

plot(a, "trail_price trigger line")    
plot(strategy.position_size>0 ? highPrice : na, "current highest price")
plot(strategy.position_size>0 ? highPrice-syminfo.mintick*offset : na, "moving stop trigger line")

img

img

img

전략이 실행되기 시작하면 즉각적인 긴 입출입, 그리고 즉시 배치strategy.exit출구 명령 (트래킹 스톱-로스 및 트레이프-프로프트 매개 변수를 지정), 시장 변화의 가격이 트레일_프라이스 트리거 라인 이상으로 상승했을 때, 트레일 스톱-로스 및 트레이프-프로프트 논리, 스톱-로스 및 트레이프-프로프트 라인 (파란색) 의 구현은 가장 높은 가격 동적 조정, 파란색 라인 포지션은 포지션을 닫는 스톱-로스 및 트레이프-프로프트 트리거를 따르기 시작했고, 마지막으로 시장 가격이 포지션 폐쇄를 유발하는 파란색 라인 아래에 떨어지면. 차트에 그려진 라인과 결합하면 매우 이해하기 쉽습니다.

이 기능을 사용하여 슈퍼 트렌딩 전략을 최적화합니다.strategy.exit외출계획 명령은 전략 출입 명령에 이 후속 스톱 로스 및 영업 영업 특징을 추가합니다.

if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
    trail_price := strategy.position_size > 0 ? close + offset : close - offset
    strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
    runtime.log("the price per point is:", syminfo.mintick, ", current close:", close, ",trail_price:", trail_price)
    state := 2 
    tradeBarIndex := bar_index

전체 전략 코드:

/*backtest
start: 2022-05-01 00:00:00
end: 2022-09-27 00:00:00
period: 1d
basePeriod: 5m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/

varip trail_price = na
varip offset = input(50, "offset")
varip tradeBarIndex = 0
// 0 : idle , 1 current_open , 2 current_close
varip state = 0  

findOrderIdx(idx) =>
    ret = -1 
    if strategy.opentrades == 0 
        ret
    else 
        for i = 0 to strategy.opentrades - 1 
            if strategy.opentrades.entry_id(i) == idx
                ret := i 
                break
        ret

if strategy.position_size == 0 
    trail_price := na 
    state := 0

[superTrendPrice, dir] = ta.supertrend(input(2, "atr coefficient"), input(20, "atr period"))

if ((dir[1] < 0 and dir[2] > 0) or (superTrendPrice[1] > superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
    strategy.entry("open", strategy.long, 1)
    state := 1
else if ((dir[1] > 0 and dir[2] < 0) or (superTrendPrice[1] < superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
    strategy.entry("open", strategy.short, 1)
    state := 1


// Reverse signal, close all positions
if strategy.position_size > 0 and dir[2] < 0 and dir[1] > 0
    strategy.cancel_all()
    strategy.close_all()
    runtime.log("trend reversal, long positions all closed")
else if strategy.position_size < 0 and dir[2] > 0 and dir[1] < 0
    strategy.cancel_all()
    strategy.close_all()
    runtime.log("trend reversal, short positions all closed")


if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
    trail_price := strategy.position_size > 0 ? close + offset : close - offset
    strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
    runtime.log("the price per point is:", syminfo.mintick, ", current close:", close, ", trail_price:", trail_price)
    state := 2 
    tradeBarIndex := bar_index


plot(superTrendPrice, "superTrendPrice", color=dir>0 ? color.red : color.green, overlay=true)

더 많은