元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);
}
