//+------------------------------------------------------------------+ //| BITTERSWEET for AUDNZD.mq4 | //| Copyright (c) 2024, HANDY SYSTEMS, All Rights Reserved. | //| https://www.handy-systems.com/ | //+------------------------------------------------------------------+ #property strict //PRODUCTIONモードでコンパイルする時は、ここから下をコメントアウトする。 #define _DEVELOPMENT //PRODUCTIONモードでコンパイルする時は、ここから上をコメントアウトする。 //EA-BANK口座縛りにする時は、ここから下のコメントアウトを解除する。 //#define _EA_BANK //EA-BANK口座縛りにする時は、ここから上のコメントアウトを解除する。 //GogoJungle形式コメントにする時は、ここから下のコメントアウトを解除する。 //#define _GOGOJUNGLE //GogoJungle形式コメントにする時は、ここから上のコメントアウトを解除する。 //LET'S REAL形式EAにする時は、ここから下のコメントアウトを解除する。 //#define _LETS_REAL //LET'S REAL形式EAにする時は、ここから上のコメントアウトを解除する。 //MQL5.com形式EAにする時は、ここから下のコメントアウトを解除する。 //#define _MQL5_COM //MQL5.com形式EAにする時は、ここから上のコメントアウトを解除する。 #include //----------EA-BANK certification begin #ifdef _EA_BANK #include #endif // _EA_BANK //----------EA-BANK certification end #property copyright "Copyright (c) 2024, HANDY SYSTEMS, All Rights Reserved." //一般的な出品サイトでは外部リンクは許可されていないため、ここから下の行はコメントアウトする //#property link "https://www.handy-systems.com/" //一般的な出品サイトでは外部リンクは許可されていないため、ここから上の行はコメントアウトする #property icon "HANDY-SYSTEMS-LOGO.ico" #property version "1.0" #ifdef _DEVELOPMENT #define dinput input #else #define dinput #endif //_DEVELOPMENT_ #ifdef _GOGOJUNGLE const string STR_EA_ID = "XXXXX"; const string STR_EA_NAME = STR_EA_ID + ":" + "BITTERSWEET_for_AUDNZD"; #else const string STR_EA_NAME = "BITTERSWEET_for_AUDNZD"; #endif // _GOGOJUNGLE const string STR_OP_BUY = "BUY"; const string STR_OP_SELL = "SELL"; // comment string const string STR_COMMENT_BUY = STR_EA_NAME + " " + STR_OP_BUY; const string STR_COMMENT_SELL = STR_EA_NAME + " " + STR_OP_SELL; // maximum character limit of MQL4 const int COMMENT_LENGTH = MathMax(StringLen(STR_COMMENT_BUY), StringLen(STR_COMMENT_SELL)); const int MAX_COMMENT_LENGTH = 31; // マジックナンバー input int MagicNumber = 84002; // MagicNumber // ロット数 input double Lots = 0.01; // Lots // 最大スプレッド (pips) input double MaxSpread = 3.5; // MaxSpread (pips) // テイクプロフィット・ストップロス(オーダー指値・逆指値) input double TakeProfit_pips = 1000.0; // Take Profot (pips) input double StopLoss_pips = 300.0; // Stop Loss (pips) //パラメータ保持用構造体 struct Parameters { // 利確・損切り価格幅(内部制御) double Rikaku_pips; // 内部利確価格幅 (pips) double Songiri_pips; // 内部損切り価格幅 (pips) //トレイリングストップのパラメータ double TrailingStopStartPips; // トレイリングストップを開始する価格幅 (pips) double TrailingStopPips; // トレイリングストップの価格幅 (pips) //指値切り下げのパラメータ double ReLimitActionPips; // 指値注文を再設定する価格幅 (pip)) double ReLimitPips; // 指値注文再設定時の指値幅(pips) // エントリー時のパラメータ double MinExpected_Pips; // エントリー時の最小期待利益 (pips) // 決済時のパラメータ double TP_Acceptable_Pips; // 許容可能な利益 (pips) double SL_Acceptable_Pips; // 許容可能な損失 (pips) }; //想定最大スプレッド const double MAX_ESTIMATED_SPREAD = 35.0; //スプレッドの刻み幅 const double SPREAD_TICK_SIZE = 3.5; //各パラメータ用構造体の設定値 /* const Parameters PARAMETERS[] = { // スプレッド~3.5 (pips) { // 利確・損切り価格(内部制御) 5.0, 120.0, // トレイリングストップのパラメータ 40.0, 5.0, // 指値切り下げのパラメータ 5.0, 35.0, // エントリー時の最小期待利益 (pips) 5.5, // 許容可能な含み損 (pips) 43.5 }, // スプレッド~7.0 (pips) { // 利確・損切り価格(内部制御) 700.0, 980.0, // トレイリングストップのパラメータ 35.0, 5.0, // 指値切り下げのパラメータ 5.0, 80.0, // エントリー時の最小期待利益 (pips) 9.5, // 許容可能な含み損 (pips) 176.0 }, // スプレッド~11.5 (pips) { // 利確・損切り価格(内部制御) 650.0, 940.0, // トレイリングストップのパラメータ 100.0, 85.0, // 指値切り下げのパラメータ 10.0, 60.0, // エントリー時の最小期待利益 (pips) 12.5, // 許容可能な含み損 (pips) 192.0 }, // スプレッド~14.0 (pips) { // 利確・損切り価格(内部制御) 120.0, 1000.0, // トレイリングストップのパラメータ 100.0, 100.0, // 指値切り下げのパラメータ 5.0, 100.0, // エントリー時の最小期待利益 (pips) 8.5, // 許容可能な含み損 (pips) 131.5 }, // スプレッド~17.5 (pips) { // 利確・損切り価格(内部制御) 150.0, 1000.0, // トレイリングストップのパラメータ 100.0, 50.0, // 指値切り下げのパラメータ 40.0, 75.0, // エントリー時の最小期待利益 (pips) 9.5, // 許容可能な含み損 (pips) 132.5 }, // スプレッド~21.0 (pips) { // 利確・損切り価格(内部制御) 90.0, 850.0, // トレイリングストップのパラメータ 650.0, 10.0, // 指値切り下げのパラメータ 35.0, 40.0, // エントリー時の最小期待利益 (pips) 6.0, // 許容可能な含み損 (pips) 136.0 }, // スプレッド~24.5 (pips) { // 利確・損切り価格(内部制御) 85.0, 850.0, // トレイリングストップのパラメータ 1000.0, 100.0, // 指値切り下げのパラメータ 30.0, 35.0, // エントリー時の最小期待利益 (pips) 51.0, // 許容可能な含み損 (pips) 256.0 }, // スプレッド~28.0 (pips) { // 利確・損切り価格(内部制御) 1400.0, 1000.0, // トレイリングストップのパラメータ 500.0, 250.0, // 指値切り下げのパラメータ 5.0, 80.0, // エントリー時の最小期待利益 (pips) 51.5, // 許容可能な含み損 (pips) 259.0 }, // スプレッド~31.5 (pips) { // 利確・損切り価格(内部制御) 1350.0, 2100.0, // トレイリングストップのパラメータ 600.0, 100.0, // 指値切り下げのパラメータ 5.0, 80.0, // エントリー時の最小期待利益 (pips) 51.0, // 許容可能な含み損 (pips) 262.5 }, // スプレッド~35.0 (pips) { // 利確・損切り価格(内部制御) 1800.0, 2100.0, // トレイリングストップのパラメータ 750.0, 70.0, // 指値切り下げのパラメータ 75.0, 115.0, // エントリー時の最小期待利益 (pips) 51.0, // 許容可能な含み損 (pips) 91.5 }, // スプレッド35.0~ (pips) = 40.0を想定 { // 利確・損切り価格(内部制御) 800.0, 3000.0, // トレイリングストップのパラメータ 40.0, 165.0, // 指値切り下げのパラメータ 160.0, 140.0, // エントリー時の最小期待利益 (pips) 51.0, // 許容可能な含み損 (pips) 192.5 } }; */ const Parameters PARAMETERS[] = { // スプレッド~3.5 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 5.0, 0.0, // 指値切り下げのパラメータ 5.0, 35.0, // エントリー時の最小期待利益 (pips) 19.0, // 許容可能な利益 (pips) 910.0, // 許容可能な損失 (pips) 300.0 }, // スプレッド~7.0 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 }, // スプレッド~11.5 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 }, // スプレッド~14.0 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 }, // スプレッド~17.5 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 }, // スプレッド~21.0 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 }, // スプレッド~24.5 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 }, // スプレッド~28.0 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 }, // スプレッド~31.5 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 }, // スプレッド~35.0 (pips) { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 }, // スプレッド35.0~ (pips) = 40.0を想定 { // 利確・損切り価格(内部制御) 0.0, 0.0, // トレイリングストップのパラメータ 0.0, 0.0, // 指値切り下げのパラメータ 0.0, 0.0, // エントリー時の最小期待利益 (pips) 0.0, // 許容可能な利益 (pips) 0.0, // 許容可能な損失 (pips) 0.0 } }; //各パラメータ保持用構造体の最大要素数 const int PARAMETERS_COUNT = (int)ArraySize(PARAMETERS); // = 10 //各パラメータ用構造体に対するスプレッド毎のインデックス enum PARAMETERS_INDEX { PARAMETERS_NONE = 0, // スプレッド指定なし PARAMETERS_035 = 0, // スプレッド~3.5 (pips) PARAMETERS_070 = 1, // スプレッド~7.0 (pips) PARAMETERS_115 = 2, // スプレッド~11.5 (pips) PARAMETERS_140 = 3, // スプレッド~14.0 (pips) PARAMETERS_175 = 4, // スプレッド~17.5 (pips) PARAMETERS_210 = 5, // スプレッド~21.0 (pips) PARAMETERS_245 = 6, // スプレッド~24.5 (pips) PARAMETERS_280 = 7, // スプレッド~28.0 (pips) PARAMETERS_315 = 8, // スプレッド~31.5 (pips) PARAMETERS_350 = 9, // スプレッド~35.0 (pips) PARAMETERS_OVER = 10 // スプレッド35.0~ (pips) }; /* // 利確・損切り価格幅(内部制御) dinput double Rikaku_pips = PARAMETERS[PARAMETERS_NONE].Rikaku_pips; // 内部利確価格幅 (pips) dinput double Songiri_pips = PARAMETERS[PARAMETERS_NONE].Songiri_pips; // 内部損切り価格幅 (pips) //トレイリングストップのパラメータ dinput double TrailingStopStartPips = PARAMETERS[PARAMETERS_NONE].TrailingStopStartPips; // トレイリングストップを開始する価格幅 (pips) dinput double TrailingStopPips = PARAMETERS[PARAMETERS_NONE].TrailingStopPips; // トレイリングストップの価格幅 (pips) //指値切り下げのパラメータ dinput double ReLimitActionPips = PARAMETERS[PARAMETERS_NONE].ReLimitActionPips; // 指値注文を再設定する価格幅 (pip)) dinput double ReLimitPips = PARAMETERS[PARAMETERS_NONE].ReLimitPips; // 指値注文再設定時の指値幅(pips) */ // 利確・損切り価格幅(内部制御) dinput double Rikaku_pips = 500.0; // 内部利確価格幅 (pips) dinput double Songiri_pips = 40.0; // 内部損切り価格幅 (pips) //トレイリングストップのパラメータ dinput double TrailingStopStartPips = 400.0; // トレイリングストップを開始する価格幅 (pips) dinput double TrailingStopPips = 0.5; // トレイリングストップの価格幅 (pips) //指値切り下げのパラメータ dinput double ReLimitActionPips = 5.0; // 指値注文を再設定する価格幅 (pip)) dinput double ReLimitPips = 500.0; // 指値注文再設定時の指値幅(pips) //スリッページ int Slippage = 3; //リトライ回数 const int MAX_ORDER_REPEAT = 5; //マーケットオープン待機時間(秒) const int TIME_WAIT_FOR_MARKET_OPEN = 3600; int xBars = 0, xxBars = 0; double BuyStop = 0, SellStop = DBL_MAX; double BuyLimit = DBL_MAX, SellLimit = 0; //最大ポジション数を、下記で入力指定して下さい。 int maxposition = 1; //ローソク足始値のみに稼働させる場合は、trueにして下さい。 bool CandleStartStarting = true; //最適化制御パラメータ #define OPTIMIZE_RF 0x0001 #define OPTIMIZE_TR 0x0002 #define OPTIMIZE_WR 0x0004 enum OPTYPE { OPTYPE_RF_ONLY = OPTIMIZE_RF, // RF OPTYPE_TR_ONLY = OPTIMIZE_TR, // 取引数 OPTYPE_WR_ONLY = OPTIMIZE_WR, // 勝率 OPTYPE_RF_TR = OPTIMIZE_RF | OPTIMIZE_TR, // RF+取引数 OPTYPE_RF_WR = OPTIMIZE_RF | OPTIMIZE_WR, // RF+勝率 OPTYPE_TR_WR = OPTIMIZE_TR | OPTIMIZE_WR, // 取引数+勝率 OPTYPE_RF_TR_WR = OPTIMIZE_RF | OPTIMIZE_TR | OPTIMIZE_WR, // RF+取引数+勝率 OPTYPE_NONE = 0 // なし }; /* dinput OPTYPE OP_Type = OPTYPE_RF_ONLY; // 最適化タイプ //エントリールールの各変数を下記に貼りつけます。 dinput double MinExpected_Pips = PARAMETERS[PARAMETERS_NONE].MinExpected_Pips; // エントリー時の最小期待利益 (pips) //エントリーフィルターの各変数を下記に貼りつけます。 //決済ルールの各変数を下記に貼りつけます。 dinput double SL_Acceptable_Pips = PARAMETERS[PARAMETERS_NONE].SL_Acceptable_Pips; // 許容可能な含み損 (pips) */ dinput OPTYPE OP_Type = OPTYPE_RF_ONLY; // 最適化タイプ //エントリールールの各変数を下記に貼りつけます。 dinput double MinExpected_Pips = 70.0; // エントリー時の最小期待利益 (pips) //エントリーフィルターの各変数を下記に貼りつけます。 //決済ルールの各変数を下記に貼りつけます。 dinput double TP_Acceptable_Pips = 70.0; // 許容可能な利益 (pips) dinput double SL_Acceptable_Pips = 15.0; // 許容可能な損失 (pips) #ifdef _LETS_REAL // LET'S REALの認証用コードを定義する int lr_product_id=758; // PRODUCT ID #import "wininet.dll" int InternetAttemptConnect(int x); int InternetOpenW(string &sAgent,int lAccessType,string &sProxyName,string &sProxyBypass,int lFlags); int InternetConnectW(int hInternet,string &szServerName,int nServerPort,string &lpszUsername,string &lpszPassword,int dwService,int dwFlags,int dwContext); int HttpOpenRequestW(int hConnect,string &Verb,string &ObjectName,string &Version,string &Referer,string &AcceptTypes,uint dwFlags,int dwContext); int HttpSendRequestW(int hRequest,string &lpszHeaders,int dwHeadersLength,uchar &lpOptional[],int dwOptionalLength); int HttpQueryInfoW(int hRequest,int dwInfoLevel,int &lpvBuffer[],int &lpdwBufferLength,int &lpdwIndex); int InternetReadFile(int hFile,uchar &sBuffer[],int lNumBytesToRead,int &lNumberOfBytesRead); int InternetCloseHandle(int hInet); #import #define OPEN_TYPE_PRECONFIG 0 #define FLAG_KEEP_CONNECTION 0x00400000 #define FLAG_PRAGMA_NOCACHE 0x00000100 #define FLAG_RELOAD 0x80000000 #define SERVICE_HTTP 3 #define CloseHandle InternetCloseHandle(lr_session);InternetCloseHandle(lr_connect);InternetCloseHandle(lr_request);InternetCloseHandle(lr_send); string lr_is_demo="0", lr_platform="MT4_EA", lr_version="1.07", lr_host="api.lets-real.com", lr_path="index.php?route=api/register", lr_vers="HTTP/1.1", lr_verb="POST", lr_head="Content-Type: application/x-www-form-urlencoded", lr_useragent="Mozilla", lr_result, lr_nill, lr_postdata, lr_ct, lr_msg, lr_msg1="Authentication Failed! ", lr_msg2=" from lets-real.com "; int lr_port=80,lr_session,lr_connect,lr_readfile,lr_request,lr_send,lr_auth_failure_times; bool lr_auth_success=false,lr_auth_exec=true; datetime lr_auth_time; #endif // _LETS_REAL //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int OnInit() { #ifdef _EA_BANK //----------EA-BANK certification begin if (!auth()) { return -1; } //----------EA-BANK certification end //認証OKの文字列を表示する Comment("EA-BANK認証:OK"); #endif // _EA_BANK #ifdef _LETS_REAL // LET'S REALの認証用コードを定義する lr_is_demo=IsDemo()?"1":"0"; if (IsTesting()) { lr_auth_exec=false; lr_auth_success=true; } if (lr_auth_exec && !IsDllsAllowed()) { lr_msg=lr_msg1+"Please allow use of DLL "+lr_msg2; Alert(lr_msg); Print(lr_msg); ExpertRemove(); return(INIT_FAILED); } #endif // _LETS_REAL //使用しているインジケータを非表示にする HideTestIndicators(true); // コメント長は最大文字数制限値以内かチェック if (!Validate(COMMENT_LENGTH <= MAX_COMMENT_LENGTH, "The comment exceeds the maximum character length")) { return(INIT_PARAMETERS_INCORRECT); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { #ifdef _EA_BANK //----------EA-BANK certification begin if (!auth()) { return; } //----------EA-BANK certification end #endif // _EA_BANK #ifdef _LETS_REAL // LET'S REALの認証用コードを定義する if (lr_auth_exec && TimeCurrent()>=lr_auth_time) { CloseHandle string lr_p0,lr_p1,lr_p2,lr_p3; char lr_data[]; lr_p0=IntegerToString(IsTradeAllowed()); lr_p1=AccountCompany(); lr_p2=IntegerToString(AccountNumber()); lr_p3=StringSubstr(WindowExpertName(),StringLen(WindowExpertName())-8,8); lr_postdata="trade_allowed="+lr_p0+"&fx_company="+lr_p1+"&fx_account="+lr_p2+"&key="+lr_p3+"&ver="+lr_version+"&product_id="+IntegerToString(lr_product_id)+"&platform="+lr_platform+"&is_demo="+lr_is_demo; StringToCharArray(lr_postdata,lr_data,0,WHOLE_ARRAY,CP_UTF8); lr_session=InternetOpenW(lr_useragent,OPEN_TYPE_PRECONFIG,lr_nill,lr_nill,0); lr_connect=InternetConnectW(lr_session,lr_host,lr_port,lr_nill,lr_nill,SERVICE_HTTP,0,0); lr_request=HttpOpenRequestW(lr_connect,lr_verb,lr_path,lr_vers,lr_nill,lr_nill,FLAG_KEEP_CONNECTION|FLAG_RELOAD|FLAG_PRAGMA_NOCACHE,0); lr_send=HttpSendRequestW(lr_request,lr_head,StringLen(lr_head),lr_data,ArraySize(lr_data)-1); if (lr_send<=0) { lr_msg=lr_msg1+lr_msg2+"\n"+"Please check your network."+"\n"+ "InternetAttemptConnect="+IntegerToString(InternetAttemptConnect(0))+"\n"+ "session="+IntegerToString(lr_session)+"\n"+ "connect="+IntegerToString(lr_connect)+"\n"+ "request="+IntegerToString(lr_request)+"\n"+ "send="+IntegerToString(lr_send); Comment(lr_msg); return; } else { uchar response[100]; int dwBytes1; lr_result=""; while(InternetReadFile(lr_request,response,0,dwBytes1)) { lr_readfile=InternetReadFile(lr_request,response,100,dwBytes1); if (dwBytes1<=0) break; lr_result=lr_result+CharArrayToString(response,0,dwBytes1); } string lr_to_split=lr_result; string lr_sep=","; string lr_respara[]; ushort lr_u_sep=StringGetCharacter(lr_sep,0); int k=StringSplit(lr_to_split,lr_u_sep,lr_respara); if (k>0) { for(int j=0; j4?60:5; lr_auth_time=TimeCurrent()+seconds; lr_msg=lr_msg1+lr_to_split+lr_msg2; Comment(lr_msg); Print(lr_result,lr_msg2); } else { lr_auth_success=true; lr_auth_failure_times=0; lr_auth_time=TimeCurrent()+43200; Print("Authentication Success "+lr_msg2); if (StringLen(lr_msg)>0) Comment(""); } } } if (!lr_auth_success) return; #endif // _LETS_REAL int i; int ticket; int CountBuy = 0,CountSell = 0; double profit; bool res; double xpoint = Point; // 小数点以下の桁数に応じてPipsの値を調整する if (Digits() == 3 || Digits() == 5) { xpoint = xpoint * 10; } //ローソク足始値のみ稼働(選択式)の場合、ココカラ if (Bars != xBars || CandleStartStarting == false) { xBars = Bars; //-------- カスタムコード追加(ココから)-------- /* // 発注済みオーダー数=0の場合、スプレッド値に応じた内部パラメータを設定する if (CountBuy + CountSell == 0) { // 指定されたシンボルの価格情報が更新されているかチェックする MqlTick lastTick; if (SymbolInfoTick(Symbol(), lastTick)) { // スプレッド値に応じて内部パラメータを設定する PrintFormat("Set parameters. but count: %d, sell counr: %d", CountBuy, CountSell); SetParametersBySpreadValue(); } } */ //-------- カスタムコード追加(ココまで)-------- //-------- ポジションのクローズ -------- // 所有しているポジションをクローズする for(i=OrdersTotal()-1; i>=0; i--) { //オーダー選択(エラーを生じた場合、ループから抜け出す) if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false) { Print("OrderSelect returned the error of ", GetLastError() ); break; } //オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る) if (OrderSymbol() != Symbol()) continue; //マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る) if (OrderMagicNumber() != MagicNumber) continue; if (OrderType() == OP_BUY) { profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する // オーダーを成り行き決済する if (profit >= Rikaku_pips * xpoint || profit <= -Songiri_pips * xpoint || Exit2() == 2) { res = WrapperOrderClose(OrderTicket(), OrderLots(), Bid, NULL, Green); } } if (OrderType() == OP_SELL) { profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の、含み損益を計算する // オーダーを成り行き決済する if (profit >= Rikaku_pips * xpoint || profit <= -Songiri_pips * xpoint || Exit1() == 1) { res = WrapperOrderClose(OrderTicket(), OrderLots(), Ask, NULL, Green); } } } //-------- ポジションのクローズ(ココマデ) -------- //-------- ポジションのトレーリング -------- // 所有しているポジションのSL, TPをトレールする for(i=OrdersTotal()-1; i>=0; i--) { //オーダー選択(エラーを生じた場合、ループから抜け出す) if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false) { Print("OrderSelect returned the error of ", GetLastError() ); break; } //オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る) if (OrderSymbol() != Symbol()) continue; //マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る) if (OrderMagicNumber() != MagicNumber) continue; if (OrderType() == OP_BUY) { profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する // TrailingStopを確認する if (profit >= TrailingStopStartPips * xpoint && OrderStopLoss() < NormalizeDouble(Bid - TrailingStopPips * xpoint, Digits())) { res = WrapperOrderModify(OrderTicket(), OrderOpenPrice(), Bid - TrailingStopPips * xpoint, OrderTakeProfit(), 0, Green); } // 指値の置きなおしを確認する else if (Bid <= NormalizeDouble(OrderOpenPrice() - ReLimitActionPips * xpoint, Digits()) && OrderTakeProfit() != NormalizeDouble(OrderOpenPrice() + ReLimitPips * xpoint, Digits())) { res = WrapperOrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), OrderOpenPrice() + ReLimitPips * xpoint, 0, Green); } } if (OrderType() == OP_SELL) { profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の、含み損益を計算する // TrailingStopを確認する if (profit >= TrailingStopStartPips * xpoint && OrderStopLoss() > NormalizeDouble(Ask + TrailingStopPips * xpoint, Digits())) { res = WrapperOrderModify(OrderTicket(), OrderOpenPrice(), Ask + TrailingStopPips * xpoint, OrderTakeProfit(), 0, Green); } // 指値の置きなおしを確認する else if (Ask >= NormalizeDouble(OrderOpenPrice() + ReLimitActionPips * xpoint, Digits()) && OrderTakeProfit() != NormalizeDouble(OrderOpenPrice() - ReLimitPips * xpoint, Digits())) { res = WrapperOrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), OrderOpenPrice() - ReLimitPips * xpoint, 0, Green); } } } //-------- ポジションのトレーリング(ココマデ) -------- //-------- 新規ポジションのエントリー -------- // ポジションの数をカウントする for(i=OrdersTotal()-1; i>=0; i--) { //オーダー選択(エラーを生じた場合、ループから抜け出す) if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false) { Print("OrderSelect returned the error of ", GetLastError() ); break; } //オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る) if (OrderSymbol() != Symbol()) continue; //マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る) if (OrderMagicNumber() != MagicNumber) continue; if (OrderType() == OP_BUY) { CountBuy = CountBuy + 1; } if (OrderType() == OP_SELL) { CountSell = CountSell + 1; } } double lots = Lots; double correct_volume; string message; //注文数量をチェック if (!CheckVolumeValue(Lots, correct_volume, message)) { // 注文数量が不正な場合は、適切な数量を設定する Print(message); lots = correct_volume; } // エントリー条件を確認し、成立していればエントリーを行う if (Entry() == 1 && CountBuy < maxposition && xxBars != Bars) { // 取引資金をチェック if (!CheckMoneyForTrade(OrderSymbol(), lots, OrderType())) { return; } ticket = WrapperOrderSend(Symbol(), OP_BUY, lots, Ask, Slippage, 0, 0, STR_COMMENT_BUY, MagicNumber, 0, Blue); // エントリーに成功していれば、TP, SLをセットする if (ticket != -1) { // チケットを使ってオーダーを選択(エラーを生じた場合、何もしない) if ( OrderSelect( ticket, SELECT_BY_TICKET ) == true ) { res = WrapperOrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - StopLoss_pips * xpoint, OrderOpenPrice() + TakeProfit_pips * xpoint, 0, MediumSeaGreen); } } xxBars = Bars; } else if (Entry() == 2 && CountSell < maxposition && xxBars != Bars) { // 取引資金をチェック if (!CheckMoneyForTrade(OrderSymbol(), lots, OrderType())) { return; } ticket = WrapperOrderSend(Symbol(), OP_SELL, lots, Bid, Slippage, 0, 0, STR_COMMENT_SELL, MagicNumber, 0, Red); // エントリーに成功していれば、TP, SLをセットする if (ticket != -1) { // チケットを使ってオーダーを選択(エラーを生じた場合、何もしない) if ( OrderSelect( ticket, SELECT_BY_TICKET ) == true ) { res = WrapperOrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + StopLoss_pips * xpoint, OrderOpenPrice() - TakeProfit_pips * xpoint, 0, MediumSeaGreen); } } xxBars = Bars; } //-------- 新規ポジションのエントリー(ココマデ) -------- } // ローソク足始値のみ稼働(選択式)の範囲は、ココマデ //-------- ポジションのTP, SLのセット -------- // ポジションにTP, SLをセットする for(i=OrdersTotal()-1; i>=0; i--) { //オーダー選択(エラーを生じた場合、ループから抜け出す) if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false) { Print("OrderSelect returned the error of ", GetLastError() ); break; } //オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る) if (OrderSymbol() != Symbol()) continue; //マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る) if (OrderMagicNumber() != MagicNumber) continue; // 買いポジションの場合 if (OrderType() == OP_BUY) { profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する // TP, SLがどちらも設定されていなければ、TP, SLを設定する if (OrderStopLoss() == 0 && OrderTakeProfit() == 0) { res = WrapperOrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - StopLoss_pips * xpoint, OrderOpenPrice() + TakeProfit_pips * xpoint, 0, MediumSeaGreen); } } // 売りポジションの場合 if (OrderType() == OP_SELL) { profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の、含み損益を計算する // TP, SLがどちらも設定されていなければ、TP, SLを設定する if (OrderStopLoss() == 0 && OrderTakeProfit() == 0) { res = WrapperOrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + StopLoss_pips * xpoint, OrderOpenPrice() - TakeProfit_pips * xpoint, 0, MediumSeaGreen); } } } //-------- ポジションのTP, SLのセット(ココマデ) -------- } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリー総括 | //+------------------------------------------------------------------+ int Entry() { if (Entry_Rule1() == 1 && (Entry_Filter1() == 1 || Entry_Filter1() == 3) && (Entry_Filter2() == 1 || Entry_Filter2() == 3) && (Entry_Filter3() == 1 || Entry_Filter3() == 3) && (Entry_Filter4() == 1 || Entry_Filter4() == 3) && (Entry_Filter5() == 1 || Entry_Filter5() == 3) ) { return(1); } else if (Entry_Rule1() == 2 && (Entry_Filter1() == 2 || Entry_Filter1() == 3) && (Entry_Filter2() == 2 || Entry_Filter2() == 3) && (Entry_Filter3() == 2 || Entry_Filter3() == 3) && (Entry_Filter4() == 2 || Entry_Filter4() == 3) && (Entry_Filter5() == 2 || Entry_Filter5() == 3) ) { return(2); } else { return(0); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 売りポジションの決済総括 | //+------------------------------------------------------------------+ int Exit1() { if (Exit_Rule1() == 3 && Exit_Rule2() == 3 && Exit_Rule3() == 3 && Exit_Rule4() == 3 && Exit_Rule5() == 3) { return(0); } else if (Exit_Rule1() == 1) { return(1); } else if (Exit_Rule2() == 1) { return(1); } else if (Exit_Rule3() == 1) { return(1); } else if (Exit_Rule4() == 1) { return(1); } else if (Exit_Rule5() == 1) { return(1); } else { return(0); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 買いポジションの決済総括 | //+------------------------------------------------------------------+ int Exit2() { if (Exit_Rule1() == 3 && Exit_Rule2() == 3 && Exit_Rule3() == 3 && Exit_Rule4() == 3 && Exit_Rule5() == 3) { return(0); } else if (Exit_Rule1() == 2) { return(2); } else if (Exit_Rule2() == 2) { return(2); } else if (Exit_Rule3() == 2) { return(2); } else if (Exit_Rule4() == 2) { return(2); } else if (Exit_Rule5() == 2) { return(2); } else { return(0); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 注文数量の正確さをチェックする | //+------------------------------------------------------------------+ bool CheckVolumeValue(double volume,double &correct_volume, string &message) { //取引操作で許可される最小数量 double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN); if (volumemax_volume) { message=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume); correct_volume = max_volume; return(false); } //数量変更の最小ステップを取得する double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP); int ratio=(int)MathRound(volume/volume_step); if (MathAbs(ratio*volume_step-volume)>0.0000001) { message=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f", volume_step,ratio*volume_step); correct_volume = ratio*volume_step; return(false); } message="Correct volume value"; correct_volume = volume; return(true); } //+------------------------------------------------------------------+ //| 取引資金が不足しているかをチェックする | //+------------------------------------------------------------------+ bool CheckMoneyForTrade(string symbol, double lots,int type) { if (!IsTesting()) { double free_margin=AccountFreeMarginCheck(symbol, type, lots); // 資金が不足している場合 if (free_margin<0) { string op = (type == OP_BUY ? "Buy" : "Sell"); Print("Not enough money for ", op," ",lots, " ", symbol, " Error code=",GetLastError()); return(false); } } return(true); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ #ifdef _DEVELOPMENT //+------------------------------------------------------------------+ //| OnTester - 指定された最適化タイプで最適化する           | //+------------------------------------------------------------------+ double OnTester() { // 取引数の最適化基準値を1000に設定する const double TRADES_STANDARD = 1000.0; // 最適化基準値を初期化する double optimization_value = 0.0; double recovery_factor = 0.0; double trades_optimization_factor = 0.0; double win_rate = 0.0; // リカバリーファクターを計算するため、純益と証拠金ベースの最大ドローダウンを取得する double profit = TesterStatistics(STAT_PROFIT); double max_drawdown = TesterStatistics(STAT_EQUITY_DD); // 最大ドローダウンが0以外の場合は、リカバリーファクターを計算する if (max_drawdown != 0) { recovery_factor = profit / max_drawdown; } // 取引数を取得する double trades = TesterStatistics(STAT_TRADES); // 取引数が0以外の場合は、勝率(総勝ち数/総取引数)を計算する if (trades != 0) { win_rate = TesterStatistics(STAT_PROFIT_TRADES) / trades; } // 取引数の最適化係数を求める trades_optimization_factor = trades / TRADES_STANDARD; // 最適化基準値 = 最適化タイプに応じた要素の値の積算値 switch(OP_Type) { case OPTYPE_RF_ONLY: optimization_value = recovery_factor; break; case OPTYPE_TR_ONLY: optimization_value = trades_optimization_factor; break; case OPTYPE_WR_ONLY: optimization_value = win_rate; break; case OPTYPE_RF_TR: optimization_value = recovery_factor * trades_optimization_factor; break; case OPTYPE_RF_WR: optimization_value = recovery_factor * win_rate; break; case OPTYPE_TR_WR: optimization_value = trades_optimization_factor * win_rate; break; case OPTYPE_RF_TR_WR: optimization_value = recovery_factor * trades_optimization_factor * win_rate; break; case OPTYPE_NONE: optimization_value = 0.0; break; default: optimization_value = 0.0; break; } return(optimization_value); } //+------------------------------------------------------------------+ #endif // _DEVELOPMENT //+------------------------------------------------------------------+ //| マーケットがオープンしているか確認する           | //+------------------------------------------------------------------+ inline bool IsMarketOpen(string symbol = NULL, int mode = SYMBOL_TRADE_MODE_FULL) { datetime currentTime = TimeCurrent(); // 指定されたシンボルの取引時間を取得 int tradingHours = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_MODE); // 取引時間に基づいてマーケットの状態を判断 if (tradingHours == SYMBOL_TRADE_MODE_DISABLED) { // 取引不可 return false; } else if (tradingHours == SYMBOL_TRADE_MODE_CLOSEONLY) { if (mode == SYMBOL_TRADE_MODE_CLOSEONLY) { // 決済注文のみ可能 return true; } else { // 取引不可 return false; } } else if (tradingHours == SYMBOL_TRADE_MODE_FULL) { // 通常取引可能 return true; } // 上記以外の場合は取引不可と判断 return false; } //+------------------------------------------------------------------+ //| 価格を通貨単位からpips単位に変換する | //+------------------------------------------------------------------+ double PriceToPips( double price, // pips単位に変換する価格 int round_digits = 1 // 丸める小数点以下の桁数 ) { // 換算結果のpips値を宣言する double pips = 0.0; // ブローカーの小数点以下桁数保持単位に応じて、換算のための倍数を計算する int digits = Digits; // 3桁・5桁のFXブローカーの場合 if (digits == 3 || digits == 5) { pips = price * MathPow(10, digits) / 10; } // 2桁・4桁のFXブローカーの場合 else if (digits == 2 || digits == 4) { pips = price * MathPow(10, digits); } // 指定された桁数で小数点以下を丸める pips = NormalizeDouble(pips, round_digits); return(pips); } //+------------------------------------------------------------------+ //| 価格をpips単位から通貨単位に変換する | //+------------------------------------------------------------------+ double PipsToPrice(double pips) { // 換算結果の価格値を宣言する double price = 0; // ブローカーの小数点以下桁数保持単位に応じて、換算のための倍数を計算する int digits = Digits; // 3桁・5桁のFXブローカーの場合 if (digits == 3 || digits == 5) { price = pips / MathPow(10, digits) * 10; } // 2桁・4桁のFXブローカーの場合 else if (digits == 2 || digits == 4) { price = pips / MathPow(10, digits); } // 価格を有効桁数で丸める price = NormalizeDouble(price, digits); return(price); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| スプレッドに応じてパラメータを設定する  | //+------------------------------------------------------------------+ bool Validate(bool condition, string message) { if (!(condition)) { Print("Validation failed: ", message); return false; } return true; } //+------------------------------------------------------------------+ //| 現在のスプレッドのpips値を取得する | //+------------------------------------------------------------------+ double GetSpreadValue() { // スプレッドのpips値を宣言する double spread_pips = 0.0; // (Ask - Bid)から、スプレッドの価格値を計算する double spread_price = (Ask - Bid); // ブローカーの小数点以下桁数保持単位に応じて、換算のための倍数を計算する int digits = Digits; // 2桁のFXブローカーの場合 switch (digits) { case 2: spread_pips = spread_price * 10; break; case 3: spread_pips = spread_price * 10 * 10; break; case 4: spread_pips = spread_price * 10 * 10 * 10; break; case 5: spread_pips = spread_price * 10 * 10 * 10 * 10; break; default: spread_pips = spread_price * MathPow(10, digits) / 10; break; } // 指定された桁数で小数点以下を丸める spread_pips = ((int)(spread_pips * 10)) / 10; return spread_pips; } //+------------------------------------------------------------------+ //| スプレッド値に応じて内部パラメータを設定する | //+------------------------------------------------------------------+ /* void SetParametersBySpreadValue() { // スプレッドのpips値を取得する double spread = GetSpreadValue(); Parameters parameters = PARAMETERS[PARAMETERS_NONE]; if (spread <= SPREAD_TICK_SIZE * PARAMETERS_035) { parameters = PARAMETERS[PARAMETERS_035]; } else if (spread <= SPREAD_TICK_SIZE * PARAMETERS_070) { parameters = PARAMETERS[PARAMETERS_070]; } else if (spread <= SPREAD_TICK_SIZE * PARAMETERS_115) { parameters = PARAMETERS[PARAMETERS_115]; } else if (spread <= SPREAD_TICK_SIZE * PARAMETERS_140) { parameters = PARAMETERS[PARAMETERS_140]; } else if (spread <= SPREAD_TICK_SIZE * PARAMETERS_175) { parameters = PARAMETERS[PARAMETERS_175]; } else if (spread <= SPREAD_TICK_SIZE * PARAMETERS_210) { parameters = PARAMETERS[PARAMETERS_210]; } else if (spread <= SPREAD_TICK_SIZE * PARAMETERS_245) { parameters = PARAMETERS[PARAMETERS_245]; } else if (spread <= SPREAD_TICK_SIZE * PARAMETERS_280) { parameters = PARAMETERS[PARAMETERS_280]; } else if (spread <= SPREAD_TICK_SIZE * PARAMETERS_315) { parameters = PARAMETERS[PARAMETERS_315]; } else if (spread <= SPREAD_TICK_SIZE * PARAMETERS_350) { parameters = PARAMETERS[PARAMETERS_350]; } else { parameters = PARAMETERS[PARAMETERS_OVER]; } // 利確・損切り価格幅(内部制御) Rikaku_pips = parameters.Rikaku_pips; // 内部利確価格幅 (pips) Songiri_pips = parameters.Songiri_pips; // 内部損切り価格幅 (pips) // トレイリングストップのパラメータ TrailingStopStartPips = parameters.TrailingStopStartPips; // トレイリングストップを開始する価格幅 (pips) TrailingStopPips = parameters.TrailingStopPips; // トレイリングストップの価格幅 (pips) // 指値切り下げのパラメータ ReLimitActionPips = parameters.ReLimitActionPips; // 指値注文を再設定する価格幅 (pip)) ReLimitPips = parameters.ReLimitPips; // 指値注文再設定時の指値幅(pips) // エントリー時のパラメータ MinExpected_Pips = parameters.MinExpected_Pips; // エントリー時の最小期待利益 (pips) // 決済時のパラメータ TP_Acceptable_Pips = parameters.TP_Acceptable_Pips; // 許容可能な利益 (pips) SL_Acceptable_Pips = parameters.SL_Acceptable_Pips; // 許容可能な損失 (pips) } */ //+------------------------------------------------------------------+ //| エントリールール1 | //+------------------------------------------------------------------+ int Entry_Rule1() { //エントリールール1を差し替える時は、下記を差し替えて下さい。 int shift = 0; // 直前の終値と現在価格の位置関係を確認 double close = iClose(NULL, 0, shift+1); double ask = Ask; double bid = Bid; double open = iOpen(NULL, 0, shift); // 期待されるpips数を計算 double expected_pips = 0; // 買いエントリーの場合 if (close > open) { // 直前の終値から現在のAskまでのpips数を計算 expected_pips = PriceToPips(close - ask); if (expected_pips >= MinExpected_Pips) { return(1); } } // 売りエントリーの場合 else if (close < open) { // 現在のBidから直前の終値までのpips数を計算 expected_pips = PriceToPips(bid - close); if (expected_pips >= MinExpected_Pips) { return(2); } } return(0); //エントリールール1を差し替える時は、ココマデを差し替えて下さい。 } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター1 | //+------------------------------------------------------------------+ int Entry_Filter1() { //エントリーフィルター1を差し替える時は、下記を差し替えて下さい。 if (GetSpreadValue() > MaxSpread) return(0); // トレード不許可 else return(3); // トレード許可 //エントリーフィルター1を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター2 | //+------------------------------------------------------------------+ int Entry_Filter2() { //エントリーフィルター2を差し替える時は、下記を差し替えて下さい。 //エントリーフィルター2を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター3 | //+------------------------------------------------------------------+ int Entry_Filter3() { //エントリーフィルター3を差し替える時は、下記を差し替えて下さい。 //エントリーフィルター3を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター4 | //+------------------------------------------------------------------+ int Entry_Filter4() { //エントリーフィルター4を差し替える時は、下記を差し替えて下さい。 //エントリーフィルター4を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| エントリーフィルター5 | //+------------------------------------------------------------------+ int Entry_Filter5() { //エントリーフィルター5を差し替える時は、下記を差し替えて下さい。 //エントリーフィルター5を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール1 | //+------------------------------------------------------------------+ int Exit_Rule1() { // 決済ルール1を差し替える時は、下記を差し替えて下さい。 // 含み損益が出ている場合は、強制決済を行う double profit = 0.0; // 含み損益 // 買いポジションの場合 if (OrderType() == OP_BUY) { profit = OrderProfit(); // 買いポジションだった場合の、含み損益を計算する if (PriceToPips(profit) >= TP_Acceptable_Pips) { // 含み益が期待値以上の場合は、強制決済売り return(2); } } /// 決済売り // 売りポジションの場合 else if (OrderType() == OP_SELL) { profit = OrderProfit(); // 売りポジションだった場合の、含み損益を計算する if (PriceToPips(profit) >= TP_Acceptable_Pips) { // 含み益が期待値以上の場合は、強制決済買い return(1); } } // 決済買い // 決済ルール1を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール2 | //+------------------------------------------------------------------+ int Exit_Rule2() { // 決済ルール2を差し替える時は、下記を差し替えて下さい。 // 含み損益が出ている場合は、強制決済を行う double profit = 0.0; // 含み損益 // 買いポジションの場合 if (OrderType() == OP_BUY) { profit = OrderProfit(); // 買いポジションだった場合の、含み損益を計算する if (PriceToPips(profit) < -SL_Acceptable_Pips) { // 含み損が許容値を超えている場合は、強制決済売り return(2); } } /// 決済売り // 売りポジションの場合 else if (OrderType() == OP_SELL) { profit = OrderProfit(); // 売りポジションだった場合の、含み損益を計算する if (PriceToPips(profit) < -SL_Acceptable_Pips) { // 含み損が許容値を超えている場合は、強制決済買い return(1); } } // 決済買い // 決済ルール2を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール3 | //+------------------------------------------------------------------+ int Exit_Rule3() { // 決済ルール3を差し替える時は、下記を差し替えて下さい。 if (GetSpreadValue() > MaxSpread) return(0); // トレード不許可 else return(3); // トレード許可 // 決済ルール3を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール4 | //+------------------------------------------------------------------+ int Exit_Rule4() { // 決済ルール4を差し替える時は、下記を差し替えて下さい。 // 決済ルール4を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 決済ルール5 | //+------------------------------------------------------------------+ int Exit_Rule5() { // 決済ルール5を差し替える時は、下記を差し替えて下さい。 // 決済ルール5を差し替える時は、ココマデを差し替えて下さい。 return(3); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| トレード関数群  | //+------------------------------------------------------------------+ // OrderSendのラッパー関数 //  マーケットの制約に合う形にSL、TPを修正したのち発注し // OederSendのエラー時のリトライおよびエラー処理を実施する int WrapperOrderSend(string symbol, // シンボル int cmd, // 注文の種類 double volume, // ロット double price, // 注文価格 int slippage, // スリッページ double stoploss, // StopLoss double takeprofit, // TakeProfit string comment=NULL, // コメント int magic=0, // マジックナンバー datetime expiration=0, // 有効期限 color arrow_color=clrNONE // 矢印のカラー ) { int i; int err = 0; // エラーNo. int res = 0; // OrderSendの戻り値 // マーケットがオープンするまで待機する datetime currentTime = TimeCurrent(); datetime waitEndTime = currentTime + TIME_WAIT_FOR_MARKET_OPEN; while (TimeCurrent() < waitEndTime) { // マーケットがオープンしていたら、ループを抜ける if (IsMarketOpen()) { break; } // 次のリトライまで500msec待つ Sleep(500); // 待機時間の制限に達しているか確認する if (TimeCurrent() >= waitEndTime) { PrintFormat("WrapperOrderSend error: The waiting time limit (&d s) has been reached.", (waitEndTime - currentTime)); return(res); } } // MAX_ORDER_REPEAT回数だけリトライする for ( i=0; i