元webプログラマーの決死のコードサンプル(笑)
自作EAを作るためのEA設計図のつくりかた(MQL4)
input double LotSize = 0.01; //ロット数 double OrderLotSize; //実際に注文に入れるロット数 extern int Slippage = 3; //スリッページpips int OrderSlippage; input int MagicNumber = 12345; //マジックナンバー extern double StopLoss = 0; //損切りpips double rateStopLoss; //エントリー価格から差し引く前の状態 extern double TakeProfit = 50; //利食いpips double rateTakeProfit; //エントリー価格から差し引く前の状態 int BuyTicket; //買いチケット int SellTicket; //売りチケット bool isBuyTracking; //買い追尾エントリーの判定 bool isSellTracking; //売り追尾エントリーの判定 //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ //lotの検証 if(checkLotSize(LotSize) == true){ OrderLotSize = LotSize; } //スリッページを注文できる形にする OrderSlippage = SlippagePipsUnit(Slippage,_Point); //pipsをレート上のpipsに変換してストップレベルと比べて大きい方を返す:利確と損切り rateStopLoss = getStopLevleRateUnit(Symbol(),Slippage,StopLoss); rateTakeProfit = getStopLevleRateUnit(Symbol(),Slippage,TakeProfit); //グローバル変数初期化 BuyTicket = 0; SellTicket = 0; isBuyTracking = false; isSellTracking = false; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(){ //lot数の上限下限範囲外の場合は取引終了 if(checkLotSize(LotSize)==false){ return; } //iRSIを定義 double previewRSI = iRSI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE,1);//ローソク足1本前のRSIの値を取得 double currentRSI = iRSI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE,0);//現在のRSIの値を取得 //エントリー判定 bool isBuyEntry = PreparationEntry(BuyTicket); bool isSellEntry = PreparationEntry(SellTicket); //1本前のRSIが30以下で現在のRSIが30以上の時 if( previewRSI<30 && currentRSI>30 && isBuyEntry == true ){ //売決済 SellTicket = SellSettlement(SellTicket, OrderSlippage); isSellTracking = false; //買エントリー BuyTicket = BuyEntry(); isBuyTracking = true; //追尾買エントリー }else if( isBuyEntry == true && isBuyTracking == true ){ BuyTicket = BuyEntry(); } //1本前のRSIが70以上で現在のRSIが70以下の時 if( previewRSI>70 && currentRSI<70 && isSellEntry == true ){ //買決済 BuyTicket = BuySettlement(BuyTicket, OrderSlippage); isBuyTracking = false; //売エントリー SellTicket = SellEntry(); isSellTracking = true; //追尾売エントリー }else if( isSellEntry == true && isSellTracking == true ){ SellTicket = SellEntry(); } //チケット初期化 BuyTicket = TicketInitialization_Buy(BuyTicket); SellTicket = TicketInitialization_Sell(SellTicket); } //+------------------------------------------------------------------+ // エントリー関数 //+------------------------------------------------------------------+ int BuyEntry(){ //注文にする損切り価格を算出 double StopLossPrice=0; if(rateStopLoss != 0){ StopLossPrice = getAsk(Symbol())-rateStopLoss; } //注文にする利食い価格を算出 double TakeProfitPrice=0; if(rateTakeProfit != 0){ TakeProfitPrice = getAsk(Symbol())+rateTakeProfit; } int ticket = OrderSend(Symbol(),OP_BUY,OrderLotSize, getAsk(Symbol()),OrderSlippage, StopLossPrice,TakeProfitPrice, "sample",MagicNumber,0,Green); if(ticket==-1){ ticket = 0; Print(GetLastError()); } return ticket; } int SellEntry(){ //注文にする損切り価格を算出 double StopLossPrice=0; if(rateStopLoss != 0){ StopLossPrice = getBid(Symbol())+rateStopLoss; } //注文にする利食い価格を算出 double TakeProfitPrice=0; if(rateTakeProfit != 0){ TakeProfitPrice = getBid(Symbol())-rateTakeProfit; } int ticket = OrderSend(Symbol(),OP_SELL,OrderLotSize, getBid(Symbol()),OrderSlippage, StopLossPrice,TakeProfitPrice, "sample",MagicNumber,0,Green); if(ticket==-1){ ticket = 0; Print(GetLastError()); } return ticket; } //+------------------------------------------------------------------+ // クローズ関数 //+------------------------------------------------------------------+ int BuySettlement(int ticket, int slippage){ if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)){ bool res = OrderClose(ticket,OrderLots(),getBid(Symbol()),slippage,clrNONE); if( res == false ){ Print( GetLastError() ); //エラー内容を出力 } }else{ Print( GetLastError() ); //エラー内容を出力 } ticket = 0; return ticket; } int SellSettlement(int ticket, int slippage){ if( OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) ){ bool res = OrderClose(ticket,OrderLots(),getAsk(Symbol()),slippage,clrNONE); if( res == false ){ Print( GetLastError() ); //エラー内容を出力 } }else{ Print( GetLastError() ); //エラー内容を出力 } ticket = 0; return ticket; } //+------------------------------------------------------------------+ // 待機決済チケット初期化処理 //+------------------------------------------------------------------+ //SellTicket=TicketInitialization_Sell(SellTicket); int TicketInitialization_Sell(int ticket){ if( OrderSelect(ticket,SELECT_BY_TICKET,MODE_HISTORY) && OrderTakeProfit()> Ask && OrderTakeProfit()!=0 ){ ticket=0; } if( OrderSelect(ticket,SELECT_BY_TICKET,MODE_HISTORY) && OrderStopLoss()< Ask && OrderStopLoss()!=0 ){ ticket=0; } return ticket; } //BuyTicket=TicketInitialization_Buy(BuyTicket); int TicketInitialization_Buy(int ticket){ if( OrderSelect(ticket,SELECT_BY_TICKET,MODE_HISTORY) && OrderTakeProfit()< Bid && OrderTakeProfit()!=0 ){ ticket=0; } if( OrderSelect(ticket,SELECT_BY_TICKET,MODE_HISTORY) && OrderStopLoss()> Bid && OrderStopLoss()!=0 ){ ticket=0; } return ticket; } //+------------------------------------------------------------------+ // ポジションの保有チェックメソッド //+------------------------------------------------------------------+ /* ポジションを所持していなければtrue,保有中ならfalseを返す */ bool PreparationEntry(int ticket){ bool have_ticket=false; if((OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) == true)){ have_ticket = true; }else if((OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) == false)|| ticket==0){ have_ticket = false; } bool flag; if( have_ticket == false){ flag = true; }else{ flag = false; } return(flag); } //+------------------------------------------------------------------+ // lotのチェックメソッド //+------------------------------------------------------------------+ bool checkLotSize(double lot){ if(lot< getMinLot(Symbol())){Alert("lot min is ",getMinLot(Symbol())); return(false);} if(getMaxLot(Symbol())< lot){Alert("lot max is ",getMaxLot(Symbol())); return(false);} return(true); } //+------------------------------------------------------------------+ // マーケットのgetメソッド //+------------------------------------------------------------------+ double getMinLot(string symbol){ return MarketInfo(symbol,MODE_MINLOT); } double getMaxLot(string symbol){ return MarketInfo(symbol,MODE_MAXLOT); } double getAsk(string symbol){ return MarketInfo(symbol,MODE_ASK); } double getBid(string symbol){ return MarketInfo(symbol,MODE_BID); } //+------------------------------------------------------------------+ // _Pointの変換関数 //+------------------------------------------------------------------+ /* symbol 通貨ペア pips_slippage 1pips~ pipsval 1pips~ */ double getStopLevleRateUnit(string symbol, int pips_slippage, double pipsval){ if(pipsval != 0){ double rate_val = RatePipsUnit( PipsComparison( getStopLevle(symbol), PointConvert( SlippagePipsUnit(pips_slippage,_Point),_Point ), pipsval ), _Point ); return rate_val; } return 0; } //1point=1pipsをレート上の1pipsに変換 /* convert 1pips~ point _Point 50pips _Point=0.00001をいれるとreturn=0.005 50pips _Point=0.0001をいれても return=0.005 */ double RatePipsUnit(double convert_pips, double point){ if( point==0.01 || point==0.001 ){ convert_pips *= 0.01; }else if(point==0.0001||point==0.00001){ convert_pips *= 0.0001; } return(convert_pips); } //ストップレベルと損益pipsを比較して大きい方を返す /* stoplevel 1point~ pips_slippage 1pips~ pipsval 1pips~ */ double PipsComparison(double stoplevel,double pips_slippage,double pipsval){ if(stoplevel==0)return pipsval; double pipsStoplevel = PointConvert(stoplevel,_Point); if(pipsval<(pipsStoplevel+pips_slippage)){ return(pipsStoplevel+pips_slippage); }else{ return(pipsval); } } //ストップレベルをpoint単位で取得する double getStopLevle(string symbol){ if(MarketInfo(symbol,MODE_STOPLEVEL)==0)return SlippagePipsUnit(10,_Point); return (MarketInfo(symbol,MODE_STOPLEVEL)); } //pointを入れてpipsで返す=>30pointをいれると3pipsで返る デコード /* convert_point 1point~ point _Point */ double PointConvert(double convert_point, double point){ if( point==0.001 || point==0.00001 ){ convert_point /= 10; } return(convert_point); } //pipsをいれてpoint単位で返す=>3pipsをいれると30pointで返る エンコード /* slippage 1pips~ point _Point */ int SlippagePipsUnit(int pips_slippage, double point){ if( point==0.001 || point==0.00001 ){ pips_slippage *= 10; } return(pips_slippage); }