2009/01/30
Mizutori_EAの説明(カスタムユーザー向け③)
先回な続きです。
【自作関数の書き方】
※自作関数が処理後に受け渡す形(今回はdouble)で宣言します。
※( )の前は、自作関数の名前、( )内部は、受け渡された物の形(今回は、int)とそれを格納する変数です。
※下記の場合、ポジション数をposに格納したlotSizeCalcという自作関数で,処理後に受け渡すものが、doubleの形であることを意味します。
◆ LOTサイズ計算 ◆
double lotSizeCalc(int pos)
{※ここから(※ここまで)がこの自作関数の範囲です。
int doru = 1;
double lotMM = 0;
int sizeND = 0;
double lotsize = MarketInfo(Symbol(),MODE_LOTSIZE);
【1ロットの単位(数量)をlotsizeに格納】
double maxlots = MarketInfo(Symbol(), MODE_MAXLOT);
【取引可能な最大Lot数をmaxlotsに格納】
double minlots = MarketInfo(Symbol(), MODE_MINLOT);
【取引可能な最少Lot数をminlotsに格納】
double accountFreeMargin = AccountFreeMargin();
【口座の余剰証拠金額をaccountFreeMarginに格納】
string Currency = AccountCurrency();
【口座預金の通貨名をCurrencyに格納】
if(Currency == "JPY") doru = 100;
【もし口座預金の通貨名が、JPYなら、doruに100を格納】
if(Currency =="USD") doru = 1;
【もし口座預金の通貨名が、USDなら、doruに1を格納】
※doruは、通貨ごとに違う単位を合わせるためのものです。
double lot =(accountFreeMargin*Leverage) / (doru*lotsize);
【(余剰証拠金×レバ)/(doru×ロットサイズ)をlotに格納】
if(minlots>=1){sizeND=0;}else{if(minlots>=0.1){sizeND=1;}else{if(minlots>=0.01){sizeND=2;}}}
【取引可能な最少Lot数により、小数点以下の適用範囲を決定する】
switch(pos)
【ナンピン回数により処理を分ける】
{
case 0: 【ナンピン回数0回の場合】
lotMM = NormalizeDouble(lot*Lotpos1,sizeND);
【ナンピン回数による倍率をlotに掛けて、最少Lot数単位で丸めた数値をlotMMに格納】
break;【switch処理を抜け出す】
case 1: 【ナンピン回数1回の場合】
lotMM = NormalizeDouble(lot*Lotpos2,sizeND);
【ナンピン回数による倍率をlotに掛けて、最少Lot数単位で丸めた数値をlotMMに格納】
break; 【switch処理を抜け出す】
case 2: 【ナンピン回数2回の場合】
lotMM = NormalizeDouble(lot*Lotpos3,sizeND);
【ナンピン回数による倍率をlotに掛けて、最少Lot数単位で丸めた数値をlotMMに格納】
break; 【switch処理を抜け出す】
case 3: 【ナンピン回数3回の場合】
lotMM = NormalizeDouble(lot*Lotpos4,sizeND);
【ナンピン回数による倍率をlotに掛けて、最少Lot数単位で丸めた数値をlotMMに格納】
break; 【switch処理を抜け出す】
case 4: 【ナンピン回数4回の場合】
lotMM = NormalizeDouble(lot*Lotpos5,sizeND);
【ナンピン回数による倍率をlotに掛けて、最少Lot数単位で丸めた数値をlotMMに格納】
break; 【switch処理を抜け出す】
default: 【ナンピン回数その他の場合】
lotMM = NormalizeDouble(lot*Lotpos6,sizeND);
【ナンピン回数による倍率をlotに掛けて、最少Lot数単位で丸めた数値をlotMMに格納】
break; 【switch処理を抜け出す】
}
if (lotMM < minlots) lotMM = minlots;
【求められた数値が最少Lot未満なら、lotMMに最小値を格納】
if (lotMM > maxlots) lotMM = maxlots;
【求められた数値が最大Lotを超えていたら、lotMMに最大値を格納】
if (lotMM > MaxLots) lotMM = MaxLots;
【求められた数値が設定した最大Lotを超えていたら、lotMMに設定した最大値を格納】
return (lotMM);
【求められた数値を、doubleの形で、この関数を呼び出したところに、返します。】
}※ここまで(lotSizeCalc自作関数の終わり)
◆時間軸によるMaのshiftの変更◆
int MaShift_Custom(int NowHour)
【MaShift_Customと名前の自作関数で、int型の数値を返します。】
{※ここから
int MaShift = 0;
if(NowHour>= EuTime_S && NowHour<= EuTime_E) MaShift = EuTime_MaShift ;
if(NowHour>= UsTime_S && NowHour<= UsTime_E) MaShift = UsTime_MaShift ;
if(AsTime_S <= AsTime_E) {
if(NowHour>= AsTime_S && NowHour<= AsTime_E) MaShift = AsTime_MaShift ;
} else {
if(NowHour>= AsTime_S || NowHour<= AsTime_E) MaShift = AsTime_MaShift ;
}
【1日を3つの範囲に分けてその範囲ごとの変数を設定するための仕様です。】
return(MaShift);
【求められた数値を、int型で、この関数を呼び出したところに、返します。】
}※ここまで
◆時間軸によるMaLimitのshiftの変更◆
※以前は、必要性がありましたが、今はほとんど使われていないものです。
※上記とほぼ同じことをしているので説明を省略します。
int MaLimtShift_Custom(int NowHour)
{
int MaLimtShift = 0;
if(NowHour>= EuTime_S && NowHour<= EuTime_E) MaLimtShift = EuTime_MaLimtShift;
if(NowHour>= UsTime_S && NowHour<= UsTime_E)MaLimtShift = UsTime_MaLimtShift;
if(AsTime_S <= AsTime_E) {
if(NowHour>= AsTime_S && NowHour<= AsTime_E)MaLimtShift = AsTime_MaLimtShift;
} else {
if(NowHour>= AsTime_S || NowHour<= AsTime_E)MaLimtShift = AsTime_MaLimtShift;
}
return(MaLimtShift);
}
◆時間軸による、Xoxの変更◆
※上記とほぼ同じため説明を省略します。
double Xox_Custom(int NowHour)
{※ここから
double Xox = 0;
if(NowHour>= EuTime_S && NowHour<= EuTime_E)Xox = EuTime_Xox;
if(NowHour>= UsTime_S && NowHour<= UsTime_E) Xox = UsTime_Xox;
if(AsTime_S <= AsTime_E) {
if(NowHour>= AsTime_S && NowHour<= AsTime_E) Xox = AsTime_Xox;
} else {
if(NowHour>= AsTime_S || NowHour<= AsTime_E) Xox = AsTime_Xox;
}
return(Xox);
}※ここまで
◆ マジックナンバーの作成◆
※本来、EAごと、通貨ペアごと、時間軸ごとに、マジックナンバーを変更しなければなりません。
しかし、忘れやすいので、通貨ごと、時間軸ごとで、マジックナンバーを自動的に変更するようにしてあります。
ただし、別のEAと同時に使用する場合、邪魔になるかもしれません。(あくまでも、テスト用の参考ソースです。)
int MagicfromSymbol() {
【MagicfromSymbolという名前の自作関数で、int型の数値を返す】
int MagicNumber=0;
for (int i=0; i<5; i++) { 【5回繰り返します。】
MagicNumber=MagicNumber*3+StringGetChar(Symbol(),i);
【 MagicNumberを3倍し、通貨ペア名のi番目の文字コード番号を加えたものをMagicNumberに格納】
}
MagicNumber=MagicNumber*3+Period();
【MagicNumberを3倍し、時間軸を加えたものをMagicNumberに格納】
return(MagicNumber);
【求められた数値を、int型で、この関数を呼び出したところに、返す。】
}
◆TakeProfitの計算◆
double Take_Profit()
【Take_Profitという関数名で、double型の数値を返す。】
{※ここから
int StopLoss = MarketInfo(Symbol(),MODE_STOPLEVEL);
【注文時に決済注文を同時に発注する場合の最低利益をStopLossに格納】
int FreezLevel = MarketInfo(Symbol(),MODE_FREEZELEVEL);
【成り行き決済した場合の最低利益をFreezLevelに格納】
if(StopLoss>TakeProfit){TPf=StopLoss;}else{TPf=TakeProfit;}
【StopLossとTakeProfit(大域変数)を比べて、大きい方をTPfに格納】
if(FreezLevel>TPf)TPf=FreezLevel;
【FreezLevelがTPfより大きい場合、TPfにFreezLevelを格納】
return(TPf);
【求められた数値を、Double型で、この関数を呼び出したところに、返す。】
}※ここまで
次回に続く・・・・・・・・・
2009/01/28
Mizutori_EAの説明(カスタムユーザー向け②)
前回の続きです。
◆ 指標の計算◆
この部分で、すべての指標計算処理を行っています。
『iMA』とは、移動平均線の組込指標関数です。詳しい説明は、「Meta Editor」のヘルプで確認ください。
※詳細については、次の説明で行いたいと思います。
double Ma = iMA(NULL,0,MaPeriod,MaShift,MODE_SMA,PRICE_OPEN,0);
double MaSS = iMA(NULL,0,25,0,MODE_EMA,PRICE_OPEN,0);
double MaSM = iMA(NULL,0,50,0,MODE_EMA,PRICE_OPEN,0);
double MaMS = iMA(NULL,0,100,0,MODE_EMA,PRICE_OPEN,0);
double MaMM = iMA(NULL,0,200,0,MODE_EMA,PRICE_OPEN,0);
double MaLM = iMA(NULL,0,300,0,MODE_EMA,PRICE_OPEN,0);
double MaLL = iMA(NULL,0,400,0,MODE_EMA,PRICE_OPEN,0);
double Bands_Ma = iMA(NULL,0,10,0,MODE_SMA,PRICE_OPEN,0);
double Bands = Bands_Ma*(Percent/100);
double MaHi = Ma+Bands;
double MaLow = Ma-Bands;
double MaHi_Tr = Ma*(1+Percent_Tr/100);
double MaLow_Tr = Ma*(1-Percent_Tr/100);
double HiLimt = High[iHighest(NULL,0,MODE_CLOSE,LimtPeriod,0)];
double LowLimt = Low[iLowest(NULL,0,MODE_CLOSE,LimtPeriod,0)];
double RSI = iRSI(NULL,0,14,PRICE_CLOSE,0);
double stb = iMA(NULL,0,MaLimtPeriod,MaLimtShift,MODE_SMMA,PRICE_OPEN,0);
double st=(HiLimt-LowLimt)/(stb/100);
double Dv = iStdDev(NULL,PERIOD_H4,Dv_Period,0,MODE_EMA,PRICE_CLOSE,0);
double ATR = iATR(NULL,0,ATRPeriod,0);
◆シグナルの作成・注文及び決済◆
※注文を出す許可シグナルをFlag『旗』としています。
つまり、買い注文を出す場合には、『Buy_Flag』を上げる(true)とします。
許可シグナルを固定することにより、いくつもの条件を追加できるようにしています。
bool Buy_Flag = false;
【Buy_Flagを宣言し、下げる(false)を格納】
bool Sell_Flag = false;
【Sell_Flag を宣言し、下げる(false)を格納】
◆買いポジションの取得◆
//条件式記入---------------------------------------------------
if(
(!OderStop)
&&(pos1<Max_Position)
//&&(MaLimtHi>Ask)
//&&(MaLimtLow<Ask)
&&(st>=Xox)
&&(RSI<=RSILowLimt)
&&(MaLow>=Ask)
&&(ATR<=ATRLimt)
&&((Ask<=(LastPrice-(PipStep*Point)))||pos1==0)
)Buy_Flag = true;
【もし、上記の条件がすべて満たされるのであれば、「Buy_Flag」を上げる(true)】
//----------------------------------------------------------------------------+
if((!fbp)||(!Stop_DV && Dv>=Dv_Point))Buy_Flag = false;
【もし、条件が満たされるのであれば、「Buy_Flag」を下げる(false)】
//+トレンド発生時の停止 --------------------------------------+
if(
//(MaMG>MaLL)
(MaLL>MaLM)
&&(MaLM>MaMM)
&&(MaMM>MaMS)
&&(MaMS>MaSM)
&&(MaSM>MaSS)
)Buy_Flag = false;
【もし、条件が満たされるのであれば、「Buy_Flag」を下げる(false)】
//+新条件-----------------------------------------------------+
if(
(!OderStop)
&&(fbp)
&&(pos1<Max_Position)
&&(MaLL<MaLM)
&&(MaLM<MaMM)
&&(MaMM<MaMS)
&&(MaMS<MaSS)
&&(MaLow_Tr>=Ask)//今回変更
&&((Ask<=(LastPrice-(PipStep*Point)))||pos1==0)
)Buy_Flag = true;
【もし、条件が満たされるのであれば、「Buy_Flag」を上げる(true)】
※このように、最後に、『新条件を追加』することにより、上記の 『「Buy_Flag」を下げる(false)』の条件を無能力化できます。
//+-----------------------------------------------------------+
if(Buy_Flag == true){
【もし、「Buy_Flag」が上げられて(true)いたら、以下の処理を実施する】
ClosePositions(1,SIGNAL_CLOSESELL,Mc1Number);//買い注文と同時に売り注文の決済を行う場合
【ClosePositions自作関数で新規注文と逆のオーダーをすべて閉じる。】
※ちなみに、『ClosePositions(0,SIGNAL_CLOSESELL,Mc1Number);』とすると、逆のオーダーを1つだけ閉じます。
OrderPositions(SIGNAL_BUY,pos1,pos2,Mc1Number);
【OrderPositions自作関数で新規注文を出します。】
※ちなみに、OrderPositions(注文の種類,既存のBUY注文数,既存のSELL注文数,マジック);となっています。
Buy_Flag = false;
【Buy_Flag」を下げる(false)】※特に必要ありませんが、間違いを防止するために記載しています。
fbp=false;
return(0);
【終了:注文を出していますから、終了しています。】
}
【この{までが、「Buy_Flag」が上げられていたら・・・の範囲です】
◆売りポジションの取得◆
買いポジションと同じなので省略です。
//条件式記入---------------------------------------------------
if(
(!OderStop)
&&(pos2<Max_Position)
//&&(MaLimtLow<Bid)
//&&(MaLimtHi>Bid)
&&(st>=Xox)
&&(RSI>=RSIHiLimt)
&&(ATR<=ATRLimt)
&&(MaHi<=Bid)
&&((Bid>=(LastPrice+(PipStep*Point)))||pos2==0)
)Sell_Flag = true;
//-------------------------------------------------------------
if((!fsp)||(!Stop_DV && Dv>Dv_Point))Sell_Flag = false;
//+トレンド発生時の停止 --------------------------------------+
if(
//(MaMG<MaLL)
(MaLL<MaLM)
&&(MaLM<MaMM)
&&(MaMM<MaMS)
&&(MaMS<MaSM)
&&(MaSM<MaSS)
)Sell_Flag = false;
//+新条件-----------------------------------------------------+
if(
(!OderStop)
&&(fsp)//今回追加
&&(pos2<Max_Position)
&&(MaLL>MaLM)
&&(MaLM>MaMM)
&&(MaMM>MaMS)
&&(MaMS>MaSS)
&&(MaHi_Tr<=Bid)
&&((Bid>=(LastPrice+(PipStep*Point)))||pos2==0)
)Sell_Flag = true;
//+-----------------------------------------------------------+
if(Sell_Flag == true){
ClosePositions(1,SIGNAL_CLOSEBUY,Mc1Number);
OrderPositions(SIGNAL_SELL,pos1,pos2,Mc1Number);
Sell_Flag = false;
fsp=false;
return(0);
}
◆決 済◆
//+----------------------------------------------------------------------------------------+
//強制決済条件
※何らかの理由で、注文と同時にTakeProfit(利食い注文)が出来なかった場合、もしくは、利食い注文以下での決済が必要になった際の処理です。
※ただし、各業者が決めている【FreezLevel】以下での決済は行えません。
//買ポジ決済
double Current_Profit_Buy = Bid-LastPrice;
【現在の買いオーダー(BUY)の利食い値をCurrent_Profit_Buyに格納】
if((UseTakeProfit)&&(pos1>0)&&(TPf>TakeProfit*Point)&&(Current_Profit_Buy>(TakeProfit*Point)))ClosePositions(0,SIGNAL_CLOSEBUY,Mc1Number);
【現在の利食い値が、既定のTakeProfit以上なら決済処理を実行する。】※この場合は、1つの決済です。
//売ポジ決済
double Current_Profit_Sell = LastPrice-Ask;
【現在の売りオーダー(SELL)の利食い値をCurrent_Profit_Sellに格納】
if((UseTakeProfit)&&(pos2>0)&&(TPf>TakeProfit*Point)&&(Current_Profit_Sell>(TakeProfit*Point)))ClosePositions(0,SIGNAL_CLOSESELL,Mc1Number);
【現在の利食い値が、既定のTakeProfit以上なら決済処理を実行する。】※この場合は、1つの決済です。
//+----------------------------------------------------------------------------------------+
◆ナンピン回数による特別な決済条件◆
※ただし、ナンピン回数とは、同時ポジション数の最大値を意味します。
switch(NumPos)
【ナンピン回数別に処理を分ける】
{
case 0: 【ナンピン回数が0回の場合、(つまりポジションがない場合)】
break;【処理を脱出する】
case 1: 【ナンピン回数が1回の場合、】
break; 【処理を脱出する】
case 2: 【ナンピン回数が2回の場合、】
//if(pos1==1)ClosePositions(SIGNAL_CLOSEBUY,Mc1Number);
//if(pos2==1)ClosePositions(SIGNAL_CLOSESELL,Mc1Number);
break; 【処理を脱出する】
case 3: 【ナンピン回数が3回の場合、】
//if(pos1==1)ClosePositions(1,SIGNAL_CLOSEBUY,Mc1Number);
//if(pos2==1)ClosePositions(1,SIGNAL_CLOSESELL,Mc1Number);
break; 【処理を脱出する】
case 4: 【ナンピン回数が4回の場合、】
if((pos1==1))ClosePositions(1,SIGNAL_CLOSEBUY,Mc1Number);
if((pos2==1))ClosePositions(1,SIGNAL_CLOSESELL,Mc1Number);
【ポジション数が1になった場合、残りを強制決済する。】
※言い換えれば、ナンピン回数が4回あって3つのポジションが決済されれば、残りを強制決済することを意味します。
break; 【処理を脱出する】
default: 【ナンピン回数が5以上の場合、】
break; 【処理を脱出する】
}
◆指標による決済条件◆
【Buy(買い)注文の処理】
//条件式記入---------------------------------------------------
if(
(pos1>0)&&
(
(HiLimt-Bid<=Lt*Point)
||
//(ATR>ATRLimt)
//||
(MaHi<Bid)
||
(OderClose)
)
//-------------------------------------------------------------
){
ClosePositions(1,SIGNAL_CLOSEBUY,Mc1Number);
return(0);
}
【Sell(売り)注文の処理】
//条件式記入---------------------------------------------------
if(
(pos2>0)&&
(
(Ask-LowLimt<=Lt*Point)
||
//(ATR>ATRLimt)
//||
(MaLow>Ask)
||
(OderClose)
)
//-------------------------------------------------------------
){
ClosePositions(1,SIGNAL_CLOSESELL,Mc1Number);
return(0);
}
//+------------------------------------------------------------------+
return(0);
}
【ここでstart( )関数が終了します。】
※この後は、次回です。
登録:
投稿
(
Atom
)