精華 OpenEntry和PosTrade系列關鍵字 [MC]
-
MC用戶求助:
OpenEntry和PosTrade系列關鍵字
?(原創:Alex)
<!-- [if !supportLists]-->一、<!--[endif]-->圖表部位
圖表部位就是標記在圖表上的倉位信息,包括進出場時間、日期、bar編號、名稱、價格、方向、手數、盈虧、次數(進場筆數)、委托單類別等倉位信息。而這些倉位信息都需要通過關鍵字來獲取,以便于策略的調用,下面將系統的闡述圖表部位關鍵字的用法及區別。
<!-- [if !supportLists]-->1、? <!--[endif]-->關鍵字marketposition
關鍵字marketposition用于返回圖表部位的狀態,而圖表部位只有三種狀態,分別是-1、0、1(marketposition只能返回這三個數字),這三個數字分別表示空頭持倉、無持倉、多頭持倉。
在公式編譯器中,關鍵字marketposition的用法敘述如下:
MarketPosition(PosBack)
參數說明:PosBack—數值表達式,用來指定部位:
<!-- [if !supportLists]-->0—? <!--[endif]-->未平倉部位;
<!-- [if !supportLists]-->1—? <!--[endif]-->上一個平倉部位(最后一個平倉部位);
<!-- [if !supportLists]-->2—? <!--[endif]-->上第二個平倉部位,依次類推。
若PosBack未指定,則預設為未平倉部位。
公式編譯器中使用PosBack(用來指定部位)的參數還有很多關鍵字,意思都是一致的,詳細的見下面的解釋。
<!-- [if !supportLists]-->2、? <!--[endif]-->未平倉部位和平倉部位
隨著進場與出場的交替進行,圖表部位的狀態也跟著從一個狀態切換到另一個狀態,而這種圖表部位狀態的改變會形成平倉部位和未平倉部位,總共可以分為5種情況:
<!-- [if !supportLists]-->?? <!--[endif]-->圖表部位的狀態從空頭持倉或者無持倉狀態轉換成多頭持倉狀態,再從多頭持倉狀態轉換成空頭持倉或者無持倉狀態,這一階段我們稱為多頭平倉部位(這一階段中允許有加減倉操作);
<!-- [if !supportLists]-->?? <!--[endif]-->圖表部位的狀態從多頭持倉或者無持倉狀態轉換成空頭持倉狀態,再從空頭持倉狀態轉換成空頭持倉或者無持倉狀態,這一階段我們稱為空頭平倉部位(這一階段中允許有加減倉操作);
<!-- [if !supportLists]-->?? <!--[endif]-->圖表部位的狀態從空頭持倉或者無持倉狀態轉換成多頭持倉狀態,但是還沒有轉換成其它狀態,這一階段我們稱為未平倉多頭部位(這一階段中允許有加減倉操作);
<!-- [if !supportLists]-->?? <!--[endif]-->圖表部位的狀態從多頭持倉或者無持倉狀態轉換成空頭持倉狀態,但是還沒有轉換成其它狀態,這一階段我們稱為未平倉空頭部位(這一階段中允許有加減倉操作);
<!-- [if !supportLists]-->?? <!--[endif]-->圖表部位的狀態從多頭持倉或者空頭持倉轉換成無持倉,但是還沒有轉換成其它狀態,這一階段我們稱為無持倉狀態。
多頭平倉部位和空頭平倉部位統稱為平倉部位,未平倉多頭部位和未平倉空頭部位統稱為未平倉部位。因為未平倉部位只有一個,而且隨著未平倉部位轉換成平倉部位,平倉部位會越來越多,而且有時候策略也需要調用平倉部位的倉位信息,這時我們有必要將平倉部位加以區分,稱最近的平倉部位為前一個平倉部位,第二近的平倉部位為前第二個平倉部位,依此類推,這里的遠近是以當根bar為基準的。
圖1. 未平倉部位和平倉部位
如圖1所示,為方便舉例,這里假設信號基于圖表上標記的“當根bar”位置進行計算,若信號在“當根bar”的位置執行marketposition、marketposition(1)、marketposition(2)關鍵字,按照我們上面所敘述的理論,它們分別返回1、-1、1,也就是圖表當前的狀態是多頭持倉,前一個平倉部位的圖表部位狀態是空頭持倉,前第二個平倉部位的圖表部位狀態是多頭持倉,當然我們還可以使用其它圖表部位關鍵字取相關的信息,以下面將要介紹的圖表部位關鍵字。
<!-- [if !supportLists]-->一、<!--[endif]-->OpenEntry系列關鍵字
OpenEntry系列關鍵字不能用于獲取平倉部位的倉位信息,只能獲取當前未平倉部位的倉位信息;并且獲取的未平倉部位的倉位信息具有實時性,這也是它最大的特點,體現在它是如何處理當前未平倉部位中的進場次序的;說的有點抽象,那么在繼續閱讀下面的介紹之前,先思考一下如下問題:
<!-- [if !supportLists]-->?? <!--[endif]-->在2018-1-11號9:45買入10手的螺紋(進場名稱是”name”),接著在當天下午14:00買入7手的螺紋(進場名稱是”style”),那么請問OpenEntry系列關鍵字認為的第一筆進場的時間和第二筆進場的時間分別是?
<!-- [if !supportLists]-->?? <!--[endif]-->接著上面的情境,在2018-1-12號10:00將進場”name”10手平倉,那么請問OpenEntry系列關鍵字認為的第一筆進場的時間和第二筆進場的時間分別是?
表1. OpenEntry系列關鍵字
OpenEntry關鍵字
用法簡介
OpenEntriesCount
返回目前部位的進場筆數
OpenEntryTime(N)
返回當前未平倉部位中第N+1筆進場的時間
OpenEntryPrice(N)
返回當前未平倉部位中第N+1筆進場的委托價格
OpenEntryContracts(N)
返回當前未平倉部位中第N+1筆進場的委托手數
OpenEntryDate(N)
返回當前未平倉部位中第N+1筆進場的委托日期
OpenEntryComission(N)
返回當前未平倉部位的第N+1筆進場手續費金額
OpenEntryProfit(N)
返回當前未平倉部位中第N+1筆進場的委托盈利
OpenEntryProfitPerContract(N)
返回當前未平倉部位中第N+1筆進場的每手盈利
OpenEntryMaxProfit(N)
返回當前未平倉部位中第N+1筆進場的最大盈利
OpenEntryMaxProfitPerContract(N)
返回當前未平倉部位中第N+1筆進場的最大每手盈利
OpenEntryMinProfit(N)
返回當前未平倉部位中第N+1筆進場的最小盈利
OpenEntryMinProfitPerContract(N)
返回當前未平倉部位中第N+1筆進場的最小每手盈利
OpenEntry系列關鍵字的使用需要有一個參數N(從0開始計算),這個N表示當前未平倉部位第N+1筆進場,而“第N+1筆進場”是如何定義的,這個會涉及到OpenEntry系列關鍵字如何認為當前未平倉部位中的進場次序;一句話就是,OpenEntry系列關鍵字將當前未平倉部位中所有未平倉的進場按照進場的時間先后進行排序,從0開始依次加1,當策略運行過程中,之前未平倉的進場被平倉了,那么這個進場次序會重新按照“將當前未平倉部位中所有未平倉的進場按照進場的時間先后進行排序,從0開始依次加1”進行排序;例如,2018-1-11號,當天依次分別在9:35、9:40、9:45、9:50進場,進場名稱分別為”A”、“B”、“C”、“D”,此時它們都未被平倉(OpenEntriesCount返回4),進場次序分別為0、1、2、3,下午13:45對進場名稱”B”平倉,平倉之后當前未平倉部位的進場”A”、“C”、“D”的次序分別是0、1、2(OpenEntriesCount返回3),下午14:00對進場名稱”C”減倉,減倉之后的次序并不影響,當前未平倉的進場”A”、“C”、“D”的次序依然分別是0、1、2(OpenEntriesCount返回3)。
在重新排序的過程中,并不會改變進場的時間、日期、手數、盈利等信息,改變的只是OpenEntry系列關鍵字識別的進場次序,方便調用。
<!-- [if !supportLists]-->1、? <!--[endif]-->關鍵字小結
OpenEntriesCount這個關鍵字不需要參數,返回的是當前未平倉部位的進場筆數,具有實時性,當某筆進場被完全平倉之后,當前未平倉部位的進場筆數就會減少1,反之,當有新的進場時,該關鍵字就會增加1
OpenEntryTime(N)、OpenEntryPrice(N)、OpenEntryContracts(N)、OpenEntryDate(N)、OpenEntryComission(N)這些關鍵字上面表格已經作了簡單的介紹,下面通過一個情境案例來闡述一下,這樣更直觀:
<!-- [if !supportLists]-->?? <!--[endif]-->2018-01-29日10:05分買入10手,價格為3712,螺紋合約,手續費是每手3元,此時OpenEntryTime(0)、OpenEntryPrice(0)、OpenEntryContracts(0)、OpenEntryDate(0)、OpenEntryComission(0)分別返回1005、3712、10、1180129、30
<!-- [if !supportLists]-->?? <!--[endif]-->接著上面的,在2018-01-29日11:05分買入6手,價格為3730,此時OpenEntryTime(1)、OpenEntryPrice(1)、OpenEntryContracts(1)、OpenEntryDate(1)、OpenEntryComission(1)分別返回1105、3730、6、1180129、18
<!-- [if !supportLists]-->?? <!--[endif]-->接著上面的,在2018-1-29日13:55分將第一筆進場全部平倉,此時OpenEntryTime(0)、OpenEntryPrice(0)、OpenEntryContracts(0)、OpenEntryDate(0)、OpenEntryComission(0)分別返回1105、3730、6、1180129、18
<!-- [if !supportLists]-->?? <!--[endif]-->接著上面的,在2018-01-29日14:25分將第一筆進場平倉3手,此時OpenEntryTime(0)、OpenEntryPrice(0)、OpenEntryContracts(0)、OpenEntryDate(0)、OpenEntryComission(0)分別返回1105、3730、3、1180129、9
OpenEntryProfit(N)、OpenEntryProfitPerContract(N)、OpenEntryMaxProfit(N)、OpenEntryMaxProfitPerContract(N)、OpenEntryMinProfit(N)、OpenEntryMinProfitPerContract(N)這些盈利的關鍵字,這些關鍵字我們也通過下面一個情境案例來闡述一下:
<!-- [if !supportLists]-->?? <!--[endif]-->在bar編號為10的bar上買入10手螺紋合約,價格是3712,手續費是每手3元,整點價值是10,當根bar的收盤價是3713,最高價3716,最低價3711,此時OpenEntryProfit(0)、OpenEntryProfitPerContract(0)、OpenEntryMaxProfit(0)、OpenEntryMaxProfitPerContract(0)、OpenEntryMinProfit(0)、OpenEntryMinProfitPerContract(0)分別返回((3713-3712)*10-3)*10(即((收盤價-進場價)*整點價值-每手手續費)*手數)、(3713-3712)*10-3、((3716-3712)*10-3)*10、(3716-3712)*10-3、((3711-3712)*10-3)*10、(3711-3712)*10-3(需要扣除策略屬性中的手續費和滑價金額)
<!-- [if !supportLists]-->?? <!--[endif]-->接著上面,當信號基于編號為20的bar上計算時,從該筆進場以來到當根bar收盤出現的最高價3720,出現的最低價3710,當根 bar的收盤價3716,此時OpenEntryProfit(0)、OpenEntryProfitPerContract(0)、OpenEntryMaxProfit(0)、OpenEntryMaxProfitPerContract(0)、OpenEntryMinProfit(0)、OpenEntryMinProfitPerContract(0)分別返回((3716-3712)*10-3)*10、(3716-3712)*10-3、((3720-3712)*10-3)*10、(3720-3712)*10-3、((3710-3712)*10-3)*10、(3710-3712)*10-3
<!-- [if !supportLists]-->?? <!--[endif]-->準確的來說,關鍵字OpenEntryMaxProfit(0)是OpenEntryProfit(0)從進場以來的最大值,而OpenEntryMinProfit(0)是OpenEntryProfit(0)從進場以來的最小值; OpenEntryProfitPerContract(0)是每手的盈利,而OpenEntryProfit(0)是OpenEntryProfitPerContract(0)與手數的乘積;OpenEntryMaxProfit(0)與OpenEntryMaxProfitPerContract(0)的關系及OpenEntryMinProfit(0)與OpenEntryMinProfitPerContract(0)的關系請參考OpenEntryProfit(0)和OpenEntryProfitPerContract(0)的關系。
<!-- [if !supportLists]-->三、<!--[endif]-->PosTrade系列關鍵字
PosTrade系列關鍵字功能很強大,即可以獲取平倉部位的倉位信息,也可以獲取未平倉部位的倉位信息,具有歷史性,這個特性不僅體現在它可以獲取平倉部位的倉位信息,更體現在它可以獲取指定進場的分批出場的信息,在繼續下面的閱讀之前,請回答以下幾個問題:
<!-- [if !supportLists]-->?? <!--[endif]-->在2018-1-11號10:00買入進場10手螺紋(進場名稱是”name”),10:45分鐘買入進場7手螺紋(進場名稱是”style”),此時PosTrade系列關鍵字認為當前未平倉部位有多少筆交易(即關鍵字PosTradeCount(0)返回多少)?
<!-- [if !supportLists]-->?? <!--[endif]-->接著上面的問題,同一天,在14:00將進場”name”減倉6手,此時PosTrade系列關鍵字認為當前未平倉部位有多少筆交易?
<!-- [if !supportLists]-->?? <!--[endif]-->接著上面的問題,在14:30分鐘將進場”style”平倉,此時PosTrade系列關鍵字認為當前未平倉部位有多少筆交易?
表2. PosTrade系列關鍵字
PosTrade系列關鍵字
用法簡介
PosTradeCount(Posback)
返回指定部位的總交易筆數
PosTradeEntryBar(Posback,N)
返回指定部位和第N+1筆交易的進場位置(bar的編號)
PosTradeEntryName(Posback,N)
返回指定部位和第N+1筆交易的進場委托名稱
PosTradeEntryPrice(Posback,N)
返回指定部位和第N+1筆交易的進場價格
PosTradeEntryDateTime(Posback,N)
返回指定部位和第N+1筆交易的進場儒略日
PosTradeEntryCategory(Posback,N)
返回指定部位和第N+1筆交易的進場委托單類型
PosTradeExitBar(Posback,N)
返回指定部位和第N+1筆交易的出場位置(bar的編號)
PosTradeExitName(Posback,N)
返回指定部位和第N+1筆交易的出場委托名稱
PosTradeExitPrice(Posback,N)
返回指定部位和第N+1筆交易的出場價格
PosTradeExitDateTime(Posback,N)
返回指定部位和第N+1筆交易的出場儒略日
PosTradeExitCategory(Posback,N)
返回指定部位和第N+1筆交易的出場委托單類型
PosTradeSize(Posback,N)
返回指定部位和第N+1筆交易的合約手數
PosTradeIsLong(Posback,N)
判斷指定部位和第N+1筆交易是否為多頭(空頭返回false,其余返回true)
PosTradeIsOpen(Posback,N)
判斷指定部位和第N+1筆交易是否未平倉(未平倉返回true,其余返回false)
PosTradeProfit(Posback,N)
返回指定部位和第N+1筆交易的盈利
PosTradeCommission(Posback,N)
返回指定部位和第N+1筆交易的手續費金額
PosTrade系列關鍵字基本都有兩個參數(除了關鍵字PosTradeCount只有一個參數),分別為Posback和N,Posback用于指定未平倉部位還是平倉部位,這個參數在這里不作介紹,因為平倉部位是由未平倉部位轉換的,即當未平倉部位的持倉被全部平倉之后,就轉換成平倉部位了;參數N用于表示第N+1筆交易(N從0開始),每一筆交易都對應進場和出場,也就是可以通過 PosTradeEntry類關鍵字(如PosTradeEntryName(0,0)獲取當前未平倉部位的第1筆交易的進場委托名稱)獲取第N+1筆交易的進場信息,通過PosTradeExit類關鍵字(如PosTradeExitName(0,0)獲取當前未平倉部位的第1筆交易的出場委托名稱)獲取第N+1筆交易的出場信息(若第N+1筆交易還沒有出場,出場信息返回0,那么只能取到第N+1筆交易的進場信息)。
PosTrade系列關鍵字最大的特點在于它可以獲取指定進場的分批出場的信息,下面以代碼和圖進行舉例說明一下。
//代碼if currentbar=30 then
???????? buy("name") 10 shares next bar at market;
if currentbar=40 then
???????? buy("style") 7 shares next bar at market;
if currentbar=50 then
???????? sell("s1") from entry("name") 6 shares next bar at market;
if currentbar=60 then
??? sell("s2") from entry("style") 7 shares next bar at market;
print("currentbar=",currentbar," ",postradecount(0)," ",postradeentrybar(0,0));
圖2. 分批出場
當currentbar=41時,當前只有兩筆交易,此時關鍵字PosTradeCount(0)返回未平倉部位的總筆數為2,兩筆交易的進場手數分別為10手和7手且都未出場,進場名稱分別為”name”和”style”,進場位置分別為31和41,我們可以通過進場關鍵字獲取這兩筆交易的進場信息,如PosTradeEntryBar(0,0)返回31,PosTradeEntryBar(0,1)返回41,但是PosTradeExitBar(0,0)和PosTradeExitBar(0,1)都返回0,因為這兩筆交易都沒有出場,PosTradeEntryCategory(0,0)返回4,表示市價單(若返回2,表示進場單的委托類型是限價單,當然還有其它的類型)。
當currentbar=51時,由于在currentbar=50時指定平倉”name”6手,所以PosTrade關鍵字將原本的第一筆交易分開成兩筆交易,已經平倉的6手還屬于第一筆交易,只是將剩下的未平倉4手作為第三筆交易,這樣PosTrade關鍵字就可以取到分批出場的倉位信息了,但是這里可能會有一個疑問:第三筆交易的進場位置是多少?這里需要強調一下,PosTrade關鍵字只是將原來的一筆交易根據是否平倉分開成兩筆交易,未平倉的部位放在最后面作為增加的一筆交易,而對于第三筆交易的進場位置當然還是31,第三筆交易和第一筆交易的進場位置、進場價格、進場名稱等進場信息都是一樣的,只是進場手數不一致,盈利和手續費會根據手數進行比例分配到第一筆交易和第三筆交易中;此時PosTradeCount(0)返回3,PosTradeEntryBar(0,0)和PosTradeEntryBar(0,2)都返回31,PosTradeExitBar(0,0)返回51,PosTradeExitBar(0,2)返回0,PosTradeExitName(0,0)返回”s1”
當currentbar=61時,由于在currentbar=60時指定平倉”style”7手,由于是全部平倉,所以不會將第二筆交易分成第二筆交易和第四筆交易(若這里只是平倉”style”3手,那么當前未平倉部位的總交易筆數會由3增加到4,而新增加的第四筆交易是由第二筆交易中的未平倉手數生成的),此時PosTradeCount(0)依然返回3,PosTradeExitBar(0,1)返回61,PosTradeExitName(0,1)返回”s2”
<!-- [if !supportLists]-->1、? <!--[endif]-->關鍵字小結
在小結這部分只介紹PosTradeSize(Posback,N)、PosTradeIsLong(Posback,N)、PosTradeIsOpen(Posback,N)、PosTradeProfit(Posback,N)和PosTradeCommission(Posback,N),其它的關鍵字,其它的關鍵字這里不再敘述,若有不清楚的地方,可以將上面的代碼并且通過print關鍵字輸出相關信息進行對比,這里仍然延續上面的例子。
當信號基于編號為41的bar進行計算時,關鍵字PosTradeSize(0,0)、PosTradeIsLong(0,0)、PosTradeIsOpen(0,0)分別返回10、true(因為是多頭)、true,當信號基于編號為51的bar進行計算時,關鍵字PosTradeSize(0,0)、PosTradeIsLong(0,0)、PosTradeIsOpen(0,0)分別返回6、true(因為是多頭)、false(因為已經平倉了)。
假設編號為31的bar以開盤價3712成交了10手螺紋合約(整點價值是10,并且策略屬性中手續費設置為每手3元),當根bar(即編號31的bar)的收盤價為3714,此時PosTradeProfit(0,0)返回第一筆交易的盈利為((3714-3712)*10-3)*10(計算公式為((收盤價-成交價)*整點價值-每手手續費)*手數),PosTradeCommission(0,0)返回手續費為3*10(即30元);當信號基于編號為51的bar進行計算時,當根bar的收盤價為3716,第一筆交易的出場成交價為3718,此時PosTradeProfit(0,0)返回第一筆交易的盈利為((3718-3712)*10-3*2)*6(計算公式為((出場成交價-進場成交價)*整點價值-每手手續費*2)*手數),PosTradeCommission(0,0)返回手續費為3*2*6(即每手手續費*2*手數,這里的2表示兩次)。
關鍵字PosTradeEntryDateTime(Posback,N)和PosTradeExitDateTime(Posback,N)返回的是儒略日的信息,通過關鍵字JulianToDate可以將儒略日轉換成EL日期(2018-01-29的EL格式為1180129,其它類推即可),所以JulianToDate (PosTradeEntryDateTime(0,0))和JulianToDate (PosTradeExitDateTime (0,0))返回的是第一筆交易的進場EL日期和出場EL日期;通過關鍵字datetime2eltime可以將儒略日轉換成EL時間(13:45的EL時間為1345,其它類推),所以datetime2eltime(PosTradeEntryDateTime(0,0))和datetime2eltime(PosTradeExitDateTime (0,0))返回的是第一筆交易的進場EL時間和出場EL時間;關鍵字datetime2eltime_s和datetime2eltime的用法一致,不同的只是返回的時間精度不一樣,前者精確到秒(例如,134500),后者精確到分(例如,1345)。
注意事項:
?1.??<!--[endif]-->獲取盈虧的關鍵字都會將策略屬性中的手續費和滑價金額計算在內,也就是會扣除手續費和滑價金額。
2. OpenEntry和PosTrade系列關鍵字不能用于回溯,也就是不能在關鍵字后面使用方括號[]來引用歷史數據,例如不能這樣使用openentrytime(0)[1]、postradeentrybar(0,0)[1];但是我們可以通過變量來回溯歷史數據,可以這樣使用:value1=postradeentrybar(0,0); value1[1];
3.?關鍵字OpenEntryComission和PosTradeCommission會根據策略屬性中設置的手續費計算交易的手續費金額,但是測試中發現,這兩個關鍵字也會根據策略屬性中的滑價金額計算交易的手續費金額,也就是說這兩個關鍵字返回的值是基于策略屬性中的手續費和滑價進行計算的費用金額。
?
-
MC回復討論一:
贊!
有思路,想編寫各種指標公式,程序化交易模型,選股公式,預警公式的朋友
可聯系技術人員 QQ: 511411198 進行 有償 編寫!(不貴!點擊查看價格!)
相關文章
-
沒有相關內容