2EMAのクロスEAを作成したのですが、アドバイスが必要です。

 

こんにちは。

私はmql 4の初心者で、簡単な2EMAクロスアドバイザを作りました。デモ口座 でテストしましたが、実際の口座で使うのは少し怖いです。

1時間足で小ロットでテストするのは時間がかかりすぎるし、数分足でテストするのはコストがかかるので、私のブローカーの最小ロットは約7米ドルです。

だから、私はあなたがそれを見てみると、私が作ったかもしれないいくつかの明白な間違いを指摘することができればありがたいのですが。

このアドバイザーは、非常に不安定なBitcoin/USD市場(価格は1日に+-30%変動することがあります)で取引することになっており、したがってストップロスとテイクプロフィットはピップではなく、ビッドまたはアスクのパーセンテージになります。

変数とか。

#property copyright "me"
#property link      "killnosock.net"
extern int SlowEma = 21;
extern int FastEma = 10;
extern int MaxRisk = 100;// % of Depo to be traded per order
extern int  TakeProfit=100;
extern int  StopLoss=100;
extern int Slippage = 10;

int LastBars = 0;

int init(){return(0);}
int deinit() {return(0);}

この関数は、注文ごとに使用できるロットサイズを、預金残高の割合に応じて決定します(int Risk)。

double GetLot(int Risk)
{double Free    =AccountFreeMargin();
 double One_Lot =MarketInfo(Symbol(),MODE_MARGINREQUIRED);
 double Min_Lot =MarketInfo(Symbol(),MODE_MINLOT);
 double Max_Lot =MarketInfo(Symbol(),MODE_MAXLOT);
 double Step    =MarketInfo(Symbol(),MODE_LOTSTEP);
 double Lot     =MathFloor(Free*Risk/100/One_Lot/Step)*Step;
 if(Lot<Min_Lot) Lot=Min_Lot;
 if(Lot>Max_Lot) Lot=Max_Lot;
 if(Lot*One_Lot>Free) {
 Alert(" free= ", AccountFreeMargin()," for one lot= ", MarketInfo(Symbol(),MODE_MARGINREQUIRED)," lot= ", Lot);
 return(0.0);}
return(Lot);}

これは新規注文を出す関数で、Cmdは買いか売り。

int NewOrder(int Cmd,double Lot)
{double TP=0; //takeprofit
 double SL=0; //stoploss
 double PR=0; //price
 color clr = CLR_NONE;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=Ask + Ask*TakeProfit/100;
    if(StopLoss>0) SL=Ask - Ask*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Green;}
 if(Cmd==OP_SELL)
   {PR=Bid;
    if(TakeProfit>0) TP=Bid - Bid*TakeProfit/100;
    if(StopLoss>0) SL=Bid + Bid*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Red;}
 int tic=OrderSend(Symbol(),Cmd,Lot,PR,Slippage,SL,TP,"",0,0,clr);
 if(tic<0) Print("Open order error: ",GetLastError());
return(tic);}

ここでは、1つの注文を閉じたり、すべての注文を閉じたりします。

//CloseOrder
void CloseOrder()
{double PR=0;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(OrderType()==OP_BUY)  PR=Bid;
 if(OrderType()==OP_SELL) PR=Ask;
 if(!OrderClose(OrderTicket(),OrderLots(),PR,Slippage,CLR_NONE))
   Print("Order close error: ",GetLastError());
return;}
//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      CloseOrder();
     }
return;}

この関数は、高速EMAと低速EMAの差(高速EMA - 低速EMA)を計算するために使用されます。

double EmaDiff(int shift)
   {
      double difference;
      difference = iMA(Symbol(),0,FastEma,0,MODE_EMA,PRICE_CLOSE,shift)
                 - iMA(Symbol(),0,SlowEma,0,MODE_EMA,PRICE_CLOSE,shift);
      return(difference);
   }

そして、ここからが本体です。

int start()
  {
double Lot;
    // check if new bar opened
    if (LastBars == Bars) return(0);
    else LastBars = Bars;
      {         
         if ((EmaDiff(1) > 0) && (EmaDiff(2) < 0))
            {
               CloseAllOrders();
               Lot = GetLot(MaxRisk);
               NewOrder(OP_BUY,Lot);
            }
            
         if ((EmaDiff(2) > 0) && (EmaDiff(1) < 0))
            {
               CloseAllOrders();
               Lot = GetLot(MaxRisk);
               NewOrder(OP_SELL,Lot);
            }                    
      }
   return(0);
  }

私はトレーリングストップを追加し、EmaDiffをゼロにするのではなく、slowとfast EMAが互いに非常に接近し、すべてのバーで交差したときに切り刻まれないように、いくつかの小さなwalueと比較することを検討しようと思っています。

 
 //CloseOrder
void CloseOrder()
{double PR=0;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(OrderType()==OP_BUY)  PR=Bid;
 if(OrderType()==OP_SELL) PR=Ask;
 if(!OrderClose(OrderTicket(),OrderLots(),PR,Slippage,CLR_NONE))
   Print("Order close error: ",GetLastError());
return;}



//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      CloseOrder();
     }
return;}

シンボルもチェック しないし、マジックナンバーもチェックしない......。

となると、異なるEAを載せてライブで使うのはどうなるのでしょうか?

 
deVries:

シンボルもチェックしないし、マジックナンバーもチェックしない......。

となると、異なるEAを載せてライブで使うのはどうなるのでしょうか?


1つの口座で2つのEAを動かすということでしょうか?
 
prupru:

1つの口座から2つのEAを稼働させるということでしょうか?
2つのEA、または1つのEAと手動で配置された取引 ... ... または単に手動で配置された取引。
 
prupru:

こんにちは。

私はmql 4の初心者で、簡単な2EMAクロスアドバイザを作りました。デモ口座でテストしましたが、実際の口座で使うのは少し怖いです。

1時間足で小ロットでテストするのは時間がかかりすぎるし、数分足でテストするのはコストがかかるので、私のブローカーの最小ロットは約7米ドルです。

だから、私はあなたがそれを見て、私が作ったかもしれないいくつかの明白な間違いを指摘することができればありがたいのですが。

しかし、エラーが発生した場合、何が問題を引き起こしたかを診断するために、より多くの情報が必要です。

if(tic < 0) Print("Open order error: ", GetLastError());

これはいいのですが、もっと必要です。どの変数をプリントすれば、エラーの原因を特定できるでしょうか? 必要なものが決まったら、それらをすべてプリント()呼び出しに加え、アスク、ビッドなどのダブル変数に正しい小数(DoubeToStr(値、桁))を使用することを確認します。

 
RaptorUK:

トレーディング関数の戻り値を催促されることなくチェックする人がいるのは良いことです.

申し訳ありませんが、私はその部分を理解していませんでした。私が得た唯一のものは、私がPrint()呼び出しに できる限り多くの変数を追加する必要があることです。ご指摘、ありがとうございました。

deVriesさん、 こちらこそアドバイスありがとうございます、これで意味がわかりました。

他に修正すべき点はありますか?

 

あります。

    // check if new bar opened
    if (LastBars == Bars) return(0);
    else LastBars = Bars;

すでに最大限のバーが あるとすると(限度がある)・・・・。

 
deVries:

あります。

すでに最大限のバーがあるとすると(限度がある)......。


では、新しいローソク足が開く瞬間をうまくとらえるにはどうしたらいいでしょうか?
 
prupru:

OK、それでは、新しいキャンドルが開く瞬間をよりよく捉えるにはどうしたらよいでしょうか?


最新のバーの時刻を確認 する Time[0].

NewBarを検索すると、いくつかの例を見つけることができます。

 
deVries:


最新のバーの時刻を確認する Time[0]

NewBarで検索すると、いくつかの例が見つかります。


ありがとうございます、私はこれを見つけたhttps://www.mql5.com/en/code/10370

 
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=Ask + Ask*TakeProfit/100;
    if(StopLoss>0) SL=Ask - Ask*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Green;}

これは正しいとは思えません。

Takeprofitが100pipsでStoplossが150pipsってどうやるんだ?

update see"ストップロスやテイクプロフィットは ピップスではなく、ビッドやアスクのパーセンテージで表示されます。

シンボルが5桁の場合、結果はしばしば2桁多くなります。