資源の読み込みに... 荷物...

FMZ Quant のPINE 言語紹介チュートリアル

作者: リン・ハーンFMZ~リディア, 作成日:2022-09-23 15:23:34, 更新日:2024-02-27 16:47:41

.3 限界=3)

シャットダウン < オープン ストラテジー キャンセル ストラテジー キャンセル ストラテジー キャンセル 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: オーダーの方向が長ければ (buy) 組み込み変数で送信する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 theinput `` ` 機能は前回のコースで学びました

[スーパートレンド,方向性] = ta.スーパートレンド (入力) 5,因数 (因数)input.int(第10回,第4回)

についてinputパラメータとして直接ta.supertrend超トレンド指標を計算するための指標機能.その中には:

  • input ((5, 因数)
  • input.int(第10回,第4回)

デフォルトでは,この関数では,下記のように Pine 言語の戦略画面に 2 つのパラメータ制御を設定します.

img

制御上のデフォルト値は,最初のパラメータですinput機能とinput機能の連続 (ここではinput.intこの2つの関数で,この2つの関数のパラメータを設定できます.ta.supertrend戦略画面に表示されます.supertrend値のデータを計算するsupertrendそして方向データdirectionそして,我々は,plotグラフを描くとき,それはスーパートレンドインジケーターの方向に基づいており,現在の方向のみが描かれていることに注意してください.direction-1,現在の市場傾向は上昇し,direction市場傾向は下落しています.plot判断を図を描くときdirection0より大きいか小さいか

次の日if... else if論理は,取引信号の判断です.direction < 0この時点で,価格データが正しい場合,現在の市場は上昇段階にあることを意味します.supertrend超トレンド指標の価格が前2つの 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]前回の数字の3番目のBARにスーパートレンド指標の価格データを参照する? それは戦略の著者の意図かもしれません. 結局のところ,契約取引市場などのいくつかの市場で,短期リスクは長期リスクよりもわずかに大きいです.

についてta.supertrend現在のトレンドが上下なのかどう判断するか 興味のある方?

実際,この指標はPine言語でカスタム関数として実装することもできます.

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に基づいて特定の期間で計算されます.その後,上下線は hl2とATRを使用して構築されます.

アップデートlowerBandそしてupperBandこのコードの三重表現に従って

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

lowerBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: lowerBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: upperBand: up

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

超トレンド上の最後のBARの価格値は,prevUpperBandこの点では,電流は下向きの傾向にあることを意味します.close値を超えるとupperBandこの時点でトレンドが変化し,上昇傾向に変換されたと考えられます.direction超トレンド戦略は,超トレンド戦略で,超トレンド戦略を設定します.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(すなわち,CiteCurrency資産の数) とstocks戦略のバランス情報.我々はアカウントの実際の資産数を読みません,我々は単に適切な購入と販売を計算するためにシミュレーション金額を使用します.その後,このダイナミックバランス戦略によって引き出されるグリッドに影響する主要なパラメータは,maxDiffValue均衡を図る判断基準である.BaseCurrencyそしてQuoteCurrency超えているmaxDiffValue資産を高価格で売却し,低価格で購入して資産を再バランスさせる.

リアルタイム BAR ステージでなければならないので,戦略取引条件の判断が設定されている場合not barstate.ishistory購入する時balance値がstocks価格計算をベースにした値です.逆に,販売操作が行われます.balanceそしてstocks変数が更新され,次のバランストリガーを待つ.

戦略のバックテストの開始時に種の価格,価格が1458ですので,私はパラメータを設定しますbalanceto: 4374 (1458*3) 意図的にパラメータを設定stocks3 資産がバランス状態で始められるようにする

ストップ・ロストとテイク・プロフィートを追跡するスーパートレンド戦略

このコースでは,strategy.exitこの戦略設計の例では,我々は,この関数を使用します. この関数では,この関数を使用します.strategy.exit超トレンド戦略を最適化する機能です

ストップ・ロストとテイク・プロフィートの追跡パラメータを見てみましょう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.exitexit order (tracking stop-loss と take-profit パラメータを指定),市場変化の価格が trail_price トリガーラインを超えると,トライリングストップ-ロスとテイク-プロフィート論理の実装,ストップ-ロスとテイク-プロフィートライン (青) が最も高い価格ダイナミック調整に従うようになり,青いラインポジションはストップ-ロスとテイク-プロフィートのトリガーでポジションを閉じ,最終的に市場の価格がポジションの閉鎖を誘発する青いラインを下回るとき.チャートに描かれたラインと組み合わせると,理解が非常に簡単です.

超トレンド戦略を最適化するためにこの機能を使用します.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)

もっと