精华 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 进行 有偿 编写!(不贵!点击查看价格!)
相关文章
-
没有相关内容