用這么易學(xué)易用的Pine語(yǔ)言如果還不會(huì)寫策略的話,那我就...
TradingView上的開源策略數(shù)量多到爆炸,這么多優(yōu)秀的策略、思路、指標(biāo)不能實(shí)盤真是太可惜了??吹竭@一點(diǎn),作為致力于把量化交易技術(shù)普及給眾多交易者的FMZ自然不能抑制這種解決需求的沖動(dòng)!
這個(gè)需求絕對(duì)不能忍!
于是,在編程開發(fā)的代碼世界里跋山涉水、走過萬(wàn)水千山,歷經(jīng)9*9=81坑,熬過無數(shù)個(gè)不眠的夜晚,墻角堆砌起了小山一般的紅??展拮又?。終于FMZ支持兼容了Pine語(yǔ)言,各種TradingView的Pine腳本都可以拿來用了。
說到Pine語(yǔ)言,小編我也是最近才自學(xué)。不過說實(shí)話作為量化交易的Pine語(yǔ)言真的是簡(jiǎn)單易用,易學(xué)。
什么?不信?看我洋洋灑灑給你寫個(gè)網(wǎng)格策略~
FMZ的實(shí)盤、回測(cè)工具、眾多的功能再加上Pine語(yǔ)言的簡(jiǎn)單易用,可算如虎添翼!算上參數(shù)設(shè)置、回測(cè)配置代碼,總共代碼也沒超過50行。入門的同學(xué)再也不用為了寫個(gè)網(wǎng)格頭疼到炸了。。。
當(dāng)然啦,這個(gè)策略是個(gè)網(wǎng)格策略,網(wǎng)格策略也有硬傷,也不是包贏的印鈔機(jī),關(guān)鍵看用法、參數(shù)。這點(diǎn)就不贅述了,我們更多來關(guān)注如何輕松的寫策略,實(shí)現(xiàn)自己的交易邏輯,自己寫策略交易賺錢,不求人的感覺太爽了??!
代碼講解
我來給各位看官講解講解,代碼簡(jiǎn)單易懂,用這么易學(xué)易用的Pine語(yǔ)言如果還不會(huì)寫策略的話,那我就..........................................詳細(xì)的給您講講!
開頭的/*backtest
和*/
包裹住的內(nèi)容是FMZ的回測(cè)配置代碼,這個(gè)是FMZ的功能,并非Pine語(yǔ)言的內(nèi)容。當(dāng)然,您可以不寫這部分內(nèi)容,回測(cè)的時(shí)候就需要手動(dòng)點(diǎn)擊參數(shù)控件來設(shè)置回測(cè)配置和參數(shù)了。
接下來的代碼:
strategy(overlay=true)
: 用來設(shè)置腳本的一些選項(xiàng),overlay=true,就是給參數(shù)overlay
賦值true,讓畫圖時(shí),畫在圖表的主圖上(K線圖就是主圖,可以這么簡(jiǎn)單理解)。varip beginPrice = 0
: 用關(guān)鍵字varip聲明了一個(gè)變量beginPrice初始賦值為0,這個(gè)值是用作網(wǎng)格的初始價(jià)格。var spacing = input.float(-1, title="間距價(jià)格")
: 設(shè)置一個(gè)策略參數(shù),參數(shù)名字叫“間距價(jià)格”,就是每個(gè)網(wǎng)格點(diǎn)的間距,設(shè)置100就是價(jià)格每過100,交易一次。var dir = input.string("long", title="方向", options = ["long", "short", "both"])
: 設(shè)置了一個(gè)策略參數(shù),名字叫“方向”,這個(gè)參數(shù)是一個(gè)帶下拉框的選項(xiàng),可以選擇long,short,both。分別表示網(wǎng)格只做多、只做空、多空都做。var amount = input.float(-1, title="下單量")
: 設(shè)置一個(gè)參數(shù),用來控制每次網(wǎng)格點(diǎn)交易時(shí)的交易量。var numbers = input.int(-1, title="網(wǎng)格數(shù)量")
: 網(wǎng)格點(diǎn)的數(shù)量,設(shè)置20就是一個(gè)方向20個(gè)網(wǎng)格點(diǎn)。var profit = input.int(-1, title="盈利價(jià)差") / syminfo.mintick
: 設(shè)置一個(gè)參數(shù),控制每個(gè)網(wǎng)格點(diǎn)的持倉(cāng)盈利到多少價(jià)差就平倉(cāng)。
接下來,看代碼:
意思就是如果spacing、amount、numbers、profit這些參數(shù)任何沒有設(shè)置的話,默認(rèn)是-1,就讓策略停止(沒設(shè)置參數(shù)不能瞎跑~哈哈!)
Go on !
這里的意思就是當(dāng)策略處于實(shí)時(shí)K線階段并且beginPrice == 0 時(shí),去給beginPrice修改值,改為當(dāng)前的最新價(jià)格??梢岳斫鉃椴呗哉竭\(yùn)行時(shí),初始當(dāng)前價(jià)格為網(wǎng)格的初始價(jià)格。因?yàn)槟_本是有歷史K線BAR階段的,策略在歷史BAR階段會(huì)執(zhí)行一遍邏輯,歷史BAR上去布置網(wǎng)格肯定是沒什么意義。
什么是歷史BAR階段?
簡(jiǎn)單舉個(gè)例子,比如當(dāng)前時(shí)刻A,策略開始運(yùn)行,策略拿到了一個(gè)有100個(gè)K線BAR的數(shù)據(jù),隨著時(shí)間肯定是100個(gè)BAR變成101個(gè),102個(gè).... N個(gè)。從A時(shí)刻開始運(yùn)行時(shí),第101個(gè)BAR就是實(shí)時(shí)K線階段了,這個(gè)時(shí)候是最新的實(shí)時(shí)數(shù)據(jù)了。那么從第1個(gè)BAR到第100個(gè)BAR,這些都是已經(jīng)過去的歷史行情了,但是策略也會(huì)在這些歷史行情上運(yùn)行一遍,所以這個(gè)階段就是歷史K線階段。
barstate.ishistory
這個(gè)是Pine語(yǔ)言的一個(gè)內(nèi)置變量,如果當(dāng)前的BAR是歷史階段的BAR,barstate.ishistory
就為true,如果不是歷史階段的BAR就為false。所以 not barstate.ishistory 為true時(shí),就是處于實(shí)時(shí)K線階段了。
接下來,我們創(chuàng)建了一個(gè)函數(shù)
這個(gè)函數(shù)的作用就是在當(dāng)前已經(jīng)開倉(cāng)的所有訂單中查找某個(gè)id是否存在,如果存在findTradeId函數(shù)調(diào)用時(shí)就返回存在的單子的ID(注意這個(gè)ID不是交易所的訂單ID,是策略給訂單起的名字或者理解為標(biāo)簽),如果不存在就返回字符串"notFound"。
接下來就開始網(wǎng)格布單了:
使用了for循環(huán),根據(jù)numbers參數(shù)的數(shù)值,確定循環(huán)次數(shù),即布置對(duì)應(yīng)個(gè)數(shù)的訂單。根據(jù)dir參數(shù),設(shè)置direction。使用findTradeId函數(shù)查找當(dāng)前網(wǎng)格位置的標(biāo)簽的訂單是否已經(jīng)開倉(cāng),只有沒有開倉(cāng)時(shí)才去下計(jì)劃單(開倉(cāng)了肯定就不能重復(fù)下了)。下單使用strategy.order函數(shù)指定limit參數(shù)做計(jì)劃單。下計(jì)劃單的同時(shí)下對(duì)應(yīng)的平倉(cāng)單。平倉(cāng)單使用strategy.exit函數(shù),指定profit參數(shù),指定利潤(rùn)點(diǎn)數(shù)。



看收益曲線就知道,網(wǎng)格也是有風(fēng)險(xiǎn)的,并非包贏,只不過在一個(gè)大尺度上拉大網(wǎng)格相對(duì)風(fēng)險(xiǎn)小了一點(diǎn)而已。
那么,用這么易學(xué)易用的Pine語(yǔ)言如果還不會(huì)寫策略的話,那我就...再出幾期教學(xué)...