本人新做了EA,但我想要它在赢利时加仓,但不知为何,它总是平掉一个仓位,才能进另外的仓位,不能同时持有两个以上的头寸,请前辈位麻烦看看哪里出了问题。谢谢 代码如下: //+------------------------------------------------------------------+ //| Moving Average.mq4 | //| Copyright ?2005, MetaQuotes Software Corp. | //| http://www.metaquotes.net/ | //+------------------------------------------------------------------+ #define MAGICMA 20110309 extern double Lots = 1; extern double MaximumRisk = 0.02; extern double DecreaseFactor = 3; //+------------------------------------------------------------------+ //| Calculate open positions | //+------------------------------------------------------------------+ int CalculateCurrentOrders(string symbol) { int buys=0,sells=0; //---- for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA) { if(OrderType()==OP_BUY) buys++; if(OrderType()==OP_SELL) sells++; } } //---- return orders volume if(buys>0) return(buys); else return(sells); } //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double LotsOptimized() { double lot=Lots; int orders=HistoryTotal(); // history orders total int losses=0; // number of losses orders without a break //---- select lot size lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/500.0,1); Print(MarketInfo(Symbol(), MODE_LOTSIZE)); Print(MarketInfo(Symbol(), MODE_MINLOT)); Print(MarketInfo(Symbol(), MODE_LOTSTEP)); Print(MarketInfo(Symbol(), MODE_MAXLOT)); //---- calculate number of losses orders without a break if(DecreaseFactor>0) { for(int i=orders-1;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; } if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; //---- if(OrderProfit()>0) break; if(OrderProfit()<0) losses++; } if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1); //this is an smart technical design,but losses stands lossing profit,not money may cause problems. //modify them follow as:accountfreemargin()-orderprofit() } //---- return lot size if(lot<1) lot=1; return(lot); } //+------------------------------------------------------------------+ //| Check for open order conditions | //+------------------------------------------------------------------+ void CheckForOpen() { double m1,m3,m4,ticket1,ticket2; int res; //---- go trading only for first tiks of new bar if(Volume[0]>1) return; //---- get Moving Average m1=iMA(NULL,0,55,0,MODE_SMA,PRICE_CLOSE,0); m3=iMA(NULL,0,55,0,MODE_SMA,PRICE_CLOSE,3); m4=iMA(NULL,0,55,0,MODE_SMA,PRICE_CLOSE,5); //---- sell conditions if (m1<m3-0.0003) {ticket1=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,5,Ask+105*Point,0,"SELL#1",MAGICMA,0,Red); return; } if (m1<m4-0.0004) {ticket2=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,5,Ask+105*Point,0,"SELL#2",MAGICMA,0,Green); return; } //---- buy conditions if ( m1>m3+0.0003) { ticket1=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,5,Bid-105*Point,0,"BUY#1",MAGICMA,0,Blue); return; } if (m1>m4+0.0004) { ticket2=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,5,Bid-105*Point,0,"BUY#2",MAGICMA,0,Yellow); return;} //---- } //+------------------------------------------------------------------+ //| Check for close order conditions | //+------------------------------------------------------------------+ void CheckForClose() { double m1,m3,m4; //---- go trading only for first tiks of new bar if(Volume[0]>1) return; //---- get Moving Average m1=iMA(NULL,0,55,0,MODE_SMA,PRICE_CLOSE,0); m3=iMA(NULL,0,55,0,MODE_SMA,PRICE_CLOSE,3); m4=iMA(NULL,0,55,0,MODE_SMA,PRICE_CLOSE,5); //---- for(int i=0;i<OrdersTotal();i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue; //---- check order type if(OrderType()==OP_BUY) { if(m1<m3-0.0002) {OrderClose(OrderTicket(),OrderLots(),Bid,3,Orange); break; } if(m1<m4-0.0003) { OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); break; } } if(OrderType()==OP_SELL) { if(m1>m3+0.0002) {OrderClose(OrderTicket(),OrderLots(),Ask,3,Tan); break; } if(m1>m4+0.0003) {OrderClose(OrderTicket(),OrderLots(),Ask,3,White); break; } } } //---- } //+------------------------------------------------------------------+ //| Start function | //+------------------------------------------------------------------+ void start() { //---- check for history and trading if(Bars<55 || IsTradeAllowed()==false) return; //---- calculate open orders by current symbol if(CalculateCurrentOrders(Symbol())==0) CheckForOpen(); else CheckForClose(); //---- } //+------------------------------------------------------------------+
CheckForOpen()和CheckForClose()并排执行。CheckForOpen()内部计算要加仓的数量及是否盈利。 CheckForOpen() CheckForClose() 这是我EA的加仓语句,在checkforopen里,做个例子。 if( AddPositionSignal == 1) //加仓信号 { if(BuyOrderCount > 0 && BuyOrderCount <= AddPositionCount && Ask > LastOrderOpenPrice + AddPositionPips * myPoint) //有多头仓位,及多头仓位数不超过加仓的次数AddPositionCount ,如只能加仓2次。现价大于上次开仓价格LastOrderOpenPrice 多少点数后才执行加仓。 { Lot = OptimalLots(Symbol(), PerTradePercent,StopLoss); if(Lot + OrdersBuyLots > MaxTradeLots) Lot = NormalizeDouble(MaxLotsTotal - OrdersSellLots,LotsDecimal); if(Lot < MarketInfo(Symbol(),MODE_MINLOT)) { Print("Lots > MaxTradeLots"); return(0); } tiket = OpenPosition(OP_BUY,Symbol(), Lot,ST(),TP(), UserComment+ "SUB", Magic);
if(CalculateCurrentOrders(Symbol())==0) CheckForOpen(); else CheckForClose(); 这不明摆着么?如果没有单子,才检查信号,如果,有单子,才去检查关单条件 朋友还是先看看手册把基本的编程结构控制看一下吧
这个条件有问题if(Ask>OrderOpenPrice()+300*Point) 你执行开仓语句时,有没有循环执行orderselect语句,如果没有,那么你的orderopenprice()就不是一个体现出真正开仓价的数值,所以才会重复执行(错误的openprice)。 仓位的最后开盘价,需要提前得到,才能在上面的语句中使用。
原来一楼貌似是完整的代码?。。。半夜上网老眼昏花,看来我是老了,坐在电脑前面太多了 不过如果你把一楼的改过了,那又是另外一回事了。 看来你只是自己编程编乱套了,自己慢慢理清嘛,建议能PRINT的地方都PRINT一下数值,来DEBUG 或者 能COMMENT到界面显示也COMMENT一下,然后用VISUAL MODE 认真检查
我写了如下代码: void CheckForOpen() { double m1,m3,a,ticket1,ticket2,b; int res; if(Volume[0]>1) return; a=iADX(NULL,0,55,4,MODE_MAIN,0); m1=iMA(NULL,0,144,0,MODE_SMA,PRICE_CLOSE,0); m3=iMA(NULL,0,144,0,MODE_SMA,PRICE_CLOSE,1); if (a>15) { //---- sell conditions if (m1<m3-0.00005) { ticket1=OrderSend(Symbol(),OP_SELL,1,Bid,5,Ask+1050*Point,0,"SELL#1",MAGICMA,0,Red);return;} //---- buy conditions if ( m1>m3+0.00005) { ticket1=OrderSend(Symbol(),OP_BUY,1,Ask,5,Bid-1050*Point,0,"BUY#1",MAGICMA,0,Blue);return; } add(); } } void add() { bool res = false; int total = OrdersTotal(),ticket2; for(int i=0; i<OrdersTotal(); i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderMagicNumber()==MAGICMA && OrderSymbol()==Symbol()) { if(OrderType()==OP_BUY) { if(OrderProfit()>300*Point)//Ask>OrderOpenPrice()+300*Point { ticket2=OrderSend(Symbol(),OP_BUY,1,Ask,5,Bid-1050*Point,0,"BUY#2",MAGICMA,0,Yellow);// return; } } if(OrderType()==OP_SELL) { if(OrderProfit()>300*Point)//Bid<OrderOpenPrice()-300*Point { ticket2=OrderSend(Symbol(),OP_SELL,1,Bid,5,Ask+1050*Point,0,"SELL#2",MAGICMA,0,White);//return; } } } } } 发现第一开仓条件(m1<m3-0.00005)在CalculateCurrentOrders(Symbol())<2(我用这个控制总仓位数)下仍然执行两次,而add()不能在正确价位执行,而且关仓也不符合我的关仓条件。帮忙再看看 新手问题一大堆
看不太懂。 CalculateCurrentOrders(Symbol())<2本来就是可以执行两次,0和1都执行,这个正确。 OrderProfit()的单位是美元吧(美分帐户另当别论), 300*Point这个却是点数,两者的单位并不一致.
是哪里看不懂呢?我是把加仓单独做一个函数,然后放到开仓函数里运行的 我是想使第一进场条件只执行一行,然后加仓条件如果达到的话,加仓一次。但在CalculateCurrentOrders(Symbol())<2 第一进场条件经常连续运行2次,加仓的却偶尔会反复开仓关仓 但多数时候不执行。 另外一个问题是后来加了TS()也只能在平掉一仓后才能开始起作用,而不能只要符合条件就起作用。这两个问题可能根源都在开仓函数的控制上出了问题。但我始终没找到解决办法,很是郁闷! 那个orderprofit()的条件 我发现与Bid<OrderOpenPrice()-300*Point 在运行时会得到同样的结果。这个也不太明白原因。
又看了一眼你的程序 最好把所有处理订单模块化,这样你写起来检查起来思路都会很清晰,貌似官网也有处理订单的LIB? 我一般都会有CHECKORDERS, CHECK OPEN BUY CLOSE ALL BUY BREAKEVEN ALL BUY 等函数,而且我所有其他EA要使用的时候都可以直接COPY PASTE, 函数一般只有一个参数 那就是MAGICNO,开单的函数,会多2两个参数,STOPLOSS TAKEPROFIT(因为SLIPPAGE那些一般设全局变量)。写EA一定要用上MAGICNO,不然以后要是跑多EA你就麻烦了,或者跟手动单混在一起。 如果你的程序全,有空我帮你看看,,,最近太忙
谢谢前辈提醒。帮忙看看下面的代码: if(DecreaseFactor>0) { for(int i=orders-1;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; } if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; if(OrderProfit()>0) break; if(OrderProfit()<0) losses++; } if(losses>=1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,2); for(int j=0;j<orders;j++) { if(OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; } if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; if(OrderProfit()<0) break; if(OrderProfit()>0) wins++; } if(wins>=5) lot=NormalizeDouble(lot-lot*(wins-5)/DecreaseFactor,2); } 我是想这段代码控制 仓位 上面一半是亏损是减仓,下面的一半是连盈5单后减仓,但现在只有亏损减仓起作用,连盈减仓的不起作用。前辈帮忙看看是什么问题 一个函数里用这样两个循环应该没问题吧。
for(int i=orders-1;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; } if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; if(OrderProfit()>=0) { wins++; } else { losses++; } } if(losses>=1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,2); if(wins>=5) lot=NormalizeDouble(lot-lot*(wins-5)/DecreaseFactor,2); 这样不就有效率点? 问题可能出现在你select 的方式 i j变量一个从大变到小,一个从小变到大
当成交单子的历史多了,肯定存在又符合第一种情况(亏损)又同时符合第二种情况(连赢)的情况,所以无法区分到底是亏损呢还是连赢呢,或者是选计算亏损,然后在亏损的结果上再计算连赢?? 另外,你代码计算连赢的方法也不对(仅是计算所有赢利的单子数量,并不存在连续的概念)
我的代码是计算连盈的 确实是select的计算顺序有问题,目前已解决。 上次前辈说看不懂我贴出来的加仓代码,不太明白哪里看不懂。目前代码起作用,但只能算有效加仓一次。我不确定是不是 Ask>OrderOpenPrice()+300*Point 这一句有问题,这里的orderopenprice()只是第一进场单的,而不是前辈所说的“上一次开仓价” 不懂如何获取“上一次开仓价”,应该不会用select再从加仓单里来一遍吧。 另外还有两个低级的问题:1,如何获取大量的历史K线数据,目前我只找到半年的 更早的似乎历史数据库里也没有,有什么渠道更获取更全的数据呢? 2,我现在用不同IB的平台测试同一EA,同样标的,时段,保证金,居然得到完全不一样的结果,成交单子价格、时点不同。这个不知是何原因 3,复盘模型 有3个选项, 如果实盘,那是默认的哪个模型。不同模型对测试结果有何不同影响。 我自己也不断找相关资料,前辈指点一下就更好了。