- 登入
- 註冊
每一套量化交易的軟體或平台都有其需要注意的事項,有時候我們在使用 TradingView 的策略腳本或是指標的時候會發現重新整理之後訊號或是進出場點會不一樣。
這種重新讀取圖表資料後指標或是策略進出場點不一致的現象我們就稱為重繪(Repainting)。
官方將重繪定義為:導致歷史與即時計算或繪圖表現不同的腳本行為。
重繪其實很常發生,有多種因素可能導致重繪。根據TradingView官方的統計,超過 95% 的現有指標都表現出某種形式的重繪行為。
例如,MACD 和 RSI 等常用指標在歷史柱上顯示已確認的值,但會在即時、未經確認的圖表柱上波動,直到收盤。因此,它們在歷史狀態和實時狀態下的行為有所不同。
更直觀的例子便是成交量,成交量隨時隨地都在變化,並非所有重繪都是無用或具有誤導性的,重繪也不是BUG,此類行為也不會阻止交易者使用具有此類行為的指標。
簡單來說,在K線價格還沒有收盤之前,指標的時會隨著市場價格及時變動,這就是最常見的一種重繪樣態。
只是這種類型的重繪是正常無害的,我們真正要避免的是在策略上使用這種無法回溯浮動的指標值。
常見的K棒歷史數據不包括價格在intra-bar變動的記錄,K棒僅記錄了開、高、低、收 (OHLC)四個點位。這導致腳本有時在歷史數據和即時數據上有不同的工作方式,其中只知道開盤價,並且在即時K棒關閉之前,K棒裡的高、低價格會移動很多次;在K棒關閉後,相關價格才會確定。
若策略使用calc_on_every_tick=true,策略將在即時運行時會在每次tick進來時即時更新時運算,不過該策略在回測時卻只會在K棒收盤時才計算。
這將會導致策略在回測與即時運作時產生極大的誤差。
發生這種情況時,回測結果也會失效,因為它們不能即時代表策略的行為。
一般來說策略腳本應該要盡量避免使用此語法。
request.security () 函數在歷史回測和實時運行上的行為不同。
在歷史回測上,它僅從其請求的上下文中傳回”已確認”的值,而在即時行情運算上,它可以傳回”未確認”的值。
如果request.security()傳回的值在沒有確認的情況下在即時即時行情上波動,則腳本將在重新啟動執行時重新繪製它們。
某些腳本使用request.security() 來請求低於主圖時間範圍的資料。雖然當專門設計用於處理較低時間範圍內的K棒函數在時間範圍內發送時是有效的。
但當這種類型的使用者定義函數需要檢測柱內的第一個柱時(大多數情況都是如此),該技術將僅適用於歷史K棒。這是因為即時資料的K棒尚未排序。
其影響是此類腳本無法即時重現其在歷史K棒上的行為。
例如,任何產生警報的邏輯都會有缺陷,並且需要不斷刷新才能將經過的即時柱重新計算為歷史K棒。
//@version=5
indicator("Lower timeframe security demo", overlay = true)
//@variable The valid timeframe closest to 1/4 the size of the chart timeframe.
string lowerTimeframe = timeframe.from_seconds(int(timeframe.in_seconds() / 4))
//@variable The `close` value on the `lowerTimeframe`. Represents the first intrabar value on each chart bar.
float firstLTFClose = request.security(syminfo.tickerid, lowerTimeframe, close, lookahead = barmerge.lookahead_on)
//@variable The `close` value on the `lowerTimeframe`. Represents the last intrabar value on each chart bar.
float lastLTFClose = request.security(syminfo.tickerid, lowerTimeframe, close)
// Plot the values.
plot(firstLTFClose, "First intrabar close", color.teal, 3)
plot(lastLTFClose, "Last intrabar close", color.purple, 3)
// Highlight the background on realtime bars.
bgcolor(barstate.isrealtime ? color.new(color.orange, 70) : na, title = "Realtime background highlight")
使用內建的timenow語法會呼叫目前時間。但使用此變數的腳本無法顯示一致的歷史和即時行為,因此它們必須重新繪製。
一般來說腳本會從圖表的第一根K棒上執行,然後按順序在每個K棒上運算。但如果第一個K棒發生變化,則腳本有可能會發生重繪。
以下因素會影響圖表上看到的K棒數量及其起點:
TradingView的不同方案對於K棒的顯示限制:
K棒起點是使用以下規則確定的,這些規則取決於圖表的時間範圍:
隨著時間的推移,這些因素會導致圖表的歷史記錄在不同的時間點開始。這通常會對腳本計算產生影響,因為早期柱中計算結果的變化可能會波及資料集中的所有其他柱。
例如,使用 ta.valuewhen()、 ta.barssince() 或 ta.ema() 等函數將產生隨早期歷史而變化的結果。
歷史和即時K棒是使用交易所/經紀商提供的兩種不同的資料來源建立的。當即時數據過去時,交易所/經紀商有時會對K棒價格進行較小的調整,然後將其寫入其歷史資料。
當刷新圖表或在那些已過去的即時K棒上重新執行腳本時,將使用歷史數據構建和計算它們,其中將包含那些通常較小的價格修正。歷史資料也可能因其他原因而被修改,例如股票分割。
在TradingView上,策略可以應用於任何類型的圖表,包括非標準圖表,例如平均K線(Heikin Ashi, HA)、磚形圖(Renko)、卡吉圖(Kagi)、點數圖(Point and Figure)、和範圍圖(Range)。
由於非標準圖表在價格水平上具有內在的綜合性質,因此在這些圖表上計算出的回測結果通常不會產生代表真實市場狀況的結果。如Pine用戶手冊中所述,使用圖表的OHLC值填充策略定單。例如,在磚形圖上運行的策略將使用Renko磚的價格水平,而不是實際市場價格。我們的幫助中心的頁面裡介紹了其功能和計算。在任何給定時刻,Renko磚水平均與實際市場價格斷開連接,將使用其自己的價格執行訂單,因此不會產生可靠的策略結果。這是因為即時box的形成與記錄的歷史數據不同。
pine script內建函數很多有Repainting的問題,request.security函數就是一個,所以在用時要小心!!
但以上這個程式碼也是有解法,就是將request.security內的close改成=>close[1],使用前一根已經確定收盤的K棒,這樣就不會有Repainting的問題了。
就是在寫策略時,切記要再判斷式內多加一個條件函數「barstate.isconfirmed」,這樣就能輕鬆避免重繪問題囉!
直接在Strategy內,把「process_orders_on_close」開啟。
並非 所有重繪行為 都是錯誤,需要不惜一切代價避免的。在許多情況下,某些形式的重繪可能正是腳本所需要的。
重要的是要知道什麼時候的重繪行為並不是我們想要的。為了避免不可接受的重繪,了解工具的工作原理或如何設計工具就會非常重要。
最後附上TradingView官方對於重繪的說明文件,供大家參考。
👉免費註冊TradingView並領取最高70%與15美元的折扣