- 如何检测一张订单是否已经被扫止损或止盈?
--> OrderCloseTime()函数返回的是订单的收盘时间。如果订单正在交易中而未平仓,此函数返回的是0,如果平仓,此值就会变成平仓当时的服务器时间,是一个很大的正整数。
//-----------------检测是否平仓-----------------+ string IsClosed(int tik) { OrderSelect(tik, SELECT_BY_TICKET); //--若为未平仓 if(OrderCloseTime()<1) return("未平") //--若为买单 被止盈 if(OrderType()==OP_BUY) { if(OrderClosePrice()>=OrderTakeProfit()) return("已被止盈"); } //--若为卖单 被止盈 if(OrderType()==OP_SELL) { if(OrderClosePrice()<=OrderTakeProfit()) return("已被止盈"); } //--其它为被止损 return("已被止损"); } //------------------------------------------------+
- OrderProfit()与OrderTakeProfit()不同
-->前者是返回订单赢利的,后者是返回订单止盈价位的。
- OrderCloseBy()的使用特点
-->仅用于方向相反的两张等量订单,一般用于锁单解锁。一大堆对冲单不能做到同时全部对冲,但可以考虑在下一个tick数据来到时,继续平仓。
- 如何从订单中返回自后一笔订单的订单号?
-->如果是历史订单,取最后一张历史订单的平仓时间;如果是还在交易中的,就取最后一张单的开仓时间。
- ModifyOrder()的用法
-->一般使用以下写法:
OrderModify(OrderTicket(),OrderOpenPrice(),0,PriceAverage,0,Blue),
这种写法不严谨,需要先检查被修改价格与现价是否相等,即检查NormailizeDouble(OrderStopLoss(),Digits)!=NormalizeDouble(Ask+Point*TrailingStop,Digits)),然后由于使用OrderModify()函数,系统经常自动生成很多点位,使用以下语句OrderModify(OrderTicket(),NormalizeDouble(OrderOpenPrice(),Digits),NormalizeDouble(Ask+Point*TrailingStop,Digit),NormalizeDouble(OrderTakeProfit(),Digits),0,Red)
较好。-->如果上述两处改动之后,还有问题,那可能是修改价格不合理,如太靠近现价。
- OrderHistoryTotal()
-->对一个新账户使用OrderSelect(OrderHistoryTotal()-2,SELECT_BY_POS,MODE_HISTORY),由于新账户此值是0,select返回失败,也就是负值。OrderHistoryTotal()本身是个数(start()也是如此),第一个历史单的序号是0,第二个是1...所以OrderHistoryTotal()-1是距离现在最近的出场单的序号。
- comment参数的特殊作用
-->这参数本意是用于记录这个订单的描述信息,程序只能在订单入场的时候设定它。同时系统会在这个订单发生止损 止赢或者拆单的时候自动修改这里的内容。
既然订单发生止损 止赢或者拆单的时候自动修改这里的内容。
那我可以在下单的时候给comment赋值”on”,当订单生成后我可以用OrderComment()函数实时获取它的comment值如果不等于”on”那就说明订单已经止损或止赢了。string OrderComment() //返回定单的注释。 int ticket=12345678; if ( OrderSelect( ticket, SELECT_BY_TICKET ) ) { if( OrderCloseTime() != 0 && OrderProfit() < 0 ) { Print(StringConcatenate("Order #", ticket, " closed by stoploss!"); } }
-->这种方法就是判断订单的盈利是否小于0来判断的,但是有个问题,就是如果是移动止损,虽然止损了但是有可能是盈利的,这样的就没法判断出来了。-->用OrderComment 函数,每次止损或者止盈后,系统自动给订单加入一个注释,如果是止损就是s/l,判断字符串里包含这个字符串就行了。同理,只赢的就是t/p。
- 有函数能实时地获取订单被止损止赢的信息吗?
比如,对于主动平仓,我可以:
int cc2 =OrderClose(...);
if (cc2>0)...... 知道已平了仓,但对于止损止赢的被动平仓呢?-->被平仓的订单 其Comment的属性会被系统自动更改为[ST] 止赢是[TP] 用这个去过滤就知道了!
- RefreshRates()的作用
-->一般用于手动或EA下单失败后,调用一下,重新要价。
- MODE_STOPLEVEL 停止水平点
-->止损位置与入场价格之间的最小点数差距
- 如何在n根柱后关闭订单?
if (TimeCurrent() - OrderOpenTime()>600) { OrderDelete(order_ticket); return(0); }复制代码不知对不对?
-->1、获得持仓单的入场时间
-->2、用iBarShift函数算出入场时对应的K线序号
-->3、比较这个序号是否大于你说的K线个数
- 三种复盘模型
-->每一个即时价位:是你平台上下载到的最精确的价格来模拟,比如有1分钟的,就按1分钟的测试;
-->控制点:是你测试1小时图的话,就按半小时图k线选12个点来测试-->仅用开盘价:
- 开多仓的条件和平空仓的条件一样,那么怎样实现开多仓的同时平空仓呢?
我用了开仓和平仓指令,结果开了的仓,马上又被平了,我该怎么控制平仓时候是平多仓,还是平空仓呢?
-->注意程序逻辑结构的设计,按以下逻辑设计即可实现先平仓,后反向开仓的目的:
-->Start开始后,先判断持仓情况,
-->如果空仓状态: 则判断多空单的条件是否满足,如果满足则入场。
-->如果持仓状态: 则判断出场条件是否满足如果满足则出场。-->记住:上述操作后都使用return返回,则下次价格到来的时候就会立刻执行下一步的出场动作。
- return的作用
-->return意思是结束当前函数的执行。-->return(0)则表示不仅结束当前函数,同时返回数值0给调用当前函数的上一级过程中的指定变量。
- 为了尽最大程度消化滑点因素,怎样严格定义订单发送价格?
比如以本周期收盘价格加上[多头]或减去[空头]几个点,在下个周期开始后发送。-->可以,你要先判断当前价格与你的预想价格的位置关系,然后使用 上挂单 或者下挂单 的方式发送订单指令就行了。
- 画箭头问题
-->如果是用数组方式画的箭头,是无法改变大小的。
-->而用Object方式画箭头只适合与运行开始后的动态画出新箭头,不能追溯历史。(Object中有些比较大的箭头)。
- 解读以下代码
int counted_bars =IndicatorCounted(); if(counted_bars <0) return(-1); if(counted_bars >0) counted_bars--; int limit =Bars -IndicatorCounted();上面一整段就是为了计算出limit的数,即当前需要计算的K线个数,否则的话,EA又把历史所有K线给计算一遍,增加了硬件负担。具体实现过程是,用IndicatorCounted()获得已计算K线数,;然后检查是否小于0?然后自减一操作,用图表上所有的K线数量(Bars)减去已计算K线数,获得还需要计算的K线数(limit),从右往左数,一般limit的值为0或1。即表示当前价格到来后没有发生变化的K线个数。
为什么要列举一个 if(counted_bars<0) ,难道counted_bars有可能小于0吗?return是返回一个东西给调用当前函数的变量,这里的return(-1)是否理解为返回-1这个值给counted_bars呢?
if(counted_bars<0)这种用法是很严谨的指标编写方法。小于零的情况会有,比如当你打开着一个商品的K线图,然后你换了一个服务器,而这个服务器上并没有这个商品。这时候就是小于零的情况。
关于return 它是返回数值给 调用return所在函数 的变量。 这里的return是在系统函数start里面,所以这里的返回-1不会有任何实际变化, 主要实现的是退出start()的当前这次运算过程。
- 内存占用很大?
-->首先占用CPU大一定是循环的部分过多, 有可能的原因是你的循环是每次都是“从头到尾”的方式 还有就是死循环 或者叫连续出现仓位操作错误。
- 如何取特定时间的特定指标的数值?
1、首先循环计算特定指标的所有历史数据
2、使用iBarShift函数根据指定时间或者那个时间段对应这个时间的K线序列号。3、根据1已经计算出来的指标数组和2计算得到的序列号,或者指定的指标的数值
- 如何处理“假叉”和“粘合”?
double Buy1_1 = iMA(NULL, PERIOD_H1, 5, 0, MODE_SMA, PRICE_CLOSE, Current + 0); double Buy1_2 = iMA(NULL, PERIOD_H1, 13, 0, MODE_SMA, PRICE_CLOSE, Current + 0); if (Buy1_1 > Buy1_2 ) Order = SIGNAL_BUY;之所以有“假叉”和“粘合”,原因不在于程序,而在于我们的肉眼。程序判断交叉哪怕是0.0001的超越都认为发生了交叉。所以在此基础上,我们可以在程序中增加一个判断就是交叉后并距离交叉位置有一定宽度后再视为“有效”。
改后一句:
if ((Buy1_1 - Buy1_2)>=5*Point ) Order = SIGNAL_BUY;
也可:判断条件的时候使用上一根K线的收盘价做计算,而不要用当前未完成的K线收盘价做计算就可以了。
- 跨周期引用指标值,在15分钟图上看小时K线上的的该指标:
-->引用指标1线值[i]= iCustom(NULL, PERIOD_H1, "MY指标", 参数1, 参数2, 参数3, 0, iBarShift(NULL, PERIOD_H1, iTime(NULL, 0, i)));
-->引用指标2线值[i]= iCustom(NULL, PERIOD_H1, "MY指标", 参数1, 参数2, 参数3, 1, iBarShift(NULL, PERIOD_H1, iTime(NULL, 0, i)));
发表评论