gryps2/EA-code/TNK/ZM-S08G_XAUUSD_M5.mq4
super.admin ae3f0ebf03 convert
2025-05-30 14:58:21 +02:00

1775 lines
129 KiB
MQL4
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//+------------------------------------------------------------------+
//| ZM-S08G.mq4 |
//| Copyright 2024, TNK |
//| https://note.com/tnk_system |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, TNK"
#property link "https://note.com/tnk_system"
#property version "1.0" // AGX再調整
//#property icon "TNKIcon.ico" // アイコン取り込み
#property strict
#include <stdlib.mqh>
#property description "通貨ペ : XAUUSD"
#property description "時間足 : M5"
#property description "スタイル : スキャル"
#property description "ポジション数 : 1"
#property description "両建て : 無し トレール : 無し"
#property description "最大TP/SL : 200/120 pips(変更不可)"
#property description "週末持ち越し : 無し"
#property description "12/20~1/3 : 新規エントリー無し・決済のみ実行"
#property description "口座 : 日足5本(GMT冬+2/夏+3)専用"
//+------------------------------------------------------------------+
//|ユーザー入力用パラメーター |
//+------------------------------------------------------------------+
input int MagicNumber = 148910; // マジックナンバー(他EAと重複不可)
input double Lots = 0.25; // ロット(単利運用時)
input double MM_Risk = 1.0; // リスク%(複利選択項目の何%か)
enum MM_Select{
Fixed, // 0:単利/固定
FreeMargin, // 1:複利/余剰証拠金
Balance, // 2:複利/残高
AddCredit, // 3:複利/残高+クレジット
};
input MM_Select MM_ON = Fixed; // 複利機能(0:固定/1:余剰証拠金/2:残高/3:残高+クレジット)
double MaxSpread_pips = 5.0; // 許容スプレッド(Pips)
input double AllowSpread = 10.0; // 許容スプレッドPips(0:自動)
int GMT = 2; // GMT(冬時間)
int Summertime = 1; // サマータイム(1:米/2:英/0:無し)
//+------------------------------------------------------------------+
//|内部設定・グローバル関数 |
//+------------------------------------------------------------------+
//内部設定
string _Comment = "ZM-S08G_XAUUSD_M5"; // 通知用コメント
int Maxposition = 1; // 最大ポジション
int Slippage = 10; // 許容スリッページ(Point)
int TakeProfit_pips = 100; // 利確指値(Pips)
int StopLoss_pips = 120; // 損切逆指値(Pips)
int TakeProfit_pips1 = 50; // 利確指値(Pips)
int StopLoss_pips1 = 100; // 損切逆指値(Pips)
int TakeProfit_pips2 = 200; // 利確指値(Pips)
int StopLoss_pips2 = 120; // 損切逆指値(Pips)
bool WeekendTrade = false; // 週末トレード
bool Monday0Trade = false; // 月朝トレード
bool YearendClose = true; // 12/24~1/3クローズ
//バーカウント・桁合わせ・時間制御用
double xpoint;
int xTime, xxTime, xxxTime, yTime;
//週末決済(日本時間)
bool GMT_Kadou_NG = false; // 週末稼働
bool PositionClose = false; // 週末決済
int EntryNG_StartTime1 = 1; // エントリー中止時間(開始)
int EntryNG_EndTime1 = 7; // エントリー中止時間(終了)
int EntryNG_DayOfWeek1 = 6; // エントリー中止曜日
int PositionClose_Time_W = 4; // ポジション決済時間
int PositionClose_DayOfWeek1 = 6; // ポジション決済曜日
//ロジック毎の時間割り振り(サーバー時間)
bool Logic1_Time = true; // ロジック1時間帯
int EntryOK_StartTime1 = 1; // ロジック1開始時間1
int EntryOK_EndTime1 = 1; // ロジック1終了時間1
int EntryOK_StartTime2 = 22; // ロジック1開始時間2
int EntryOK_EndTime2 = 23; // ロジック1終了時間2
//バックテスト用モード切替
bool BacktestMode = false; // 0時台決済無し
bool ROTime = false; // ロールオーバー・メンテナンス時間
bool Development = false; // 開発モードON/OFF(OnTester欄にRF表示、インジケータ表示)
int Mode1 = 0; // ATRモード切替_0:全部/1:低ボラ/2:高ボラ
bool Buy_Entry = true; // 買いエントリー
bool Sell_Entry = true; // 売りエントリー
//+------------------------------------------------------------------+
//|便利機能系 |
//+------------------------------------------------------------------+
//チャートセット固定用
string SYMBOL1 = "XAUUSD"; // シンボル名(頭6文字)
string SYMBOL2 = "GOLD"; // シンボル名(頭4文字)
int Chart_TimeFrame = PERIOD_M5; // タイムフレーム
// EAの状態を表示
bool Pass = true;
int CT = 0;
int ChartWarning;
// チャートにトレード履歴表示用
double tes = 0.0; // 外付け手数料(PIPS換算)
int sf, tof;
datetime hf;
double totalpips = 0, ProfitFactor = 0;
double plus_profit = 0, minus_profit = 0;
double minus_count = 0, plus_count = 0;
double RRR, WinPer;
double TradeCounts;
// マジックナンバー重複セットアラート
static bool check_duplicate = true;
static const string kEA_NAME = (string)MagicNumber;
// スプレッド計測用
double MeasureSpread, SpreadMin = 1000, SpreadMax = 0, SpreadSum = 0, SpreadAve = 0;
double SpreadMin1 = 100, SpreadMax1 = 0, SpreadSum1 = 0, SpreadAve1 = 0;
int TickCount = 0, TickCount1 = 0, lastBars;
// オートスプレッド用
double Adjustspread = 5.0; // 平均スプレッド加算用宣言
double AllowMaxSpread = 8.0; // 自動最大許容スプレッド
double Adjustspread_Margin = 3.0; // 自動スプレッド調整幅
double Adjustspread_Margin1 = 2.0; // 自動スプレッド調整幅(エントリー時間帯)
// 証拠金チェック
int aCmd = 0;
// DPI換算
double DPIAdjust;
//+------------------------------------------------------------------+
//|ロジック用パラメータ |
//+------------------------------------------------------------------+
//エントリー・決済ベースルールの各変数
int WPR_Period1 = 42; // 【買い|エントリー】ウィリアムズ%R期間1
int WPR_Line1 = -97; // 【買い|エントリー】ウィリアムズライン1
int WPR_Ex_Line1 = -93; // 【買い|決済】ウィリアムズライン1
int WPR_Period2 = 14; // 【買い|エントリー】ウィリアムズ%R期間2
int WPR_Line2 = -97; // 【買い|エントリー】ウィリアムズライン2
int WPR_Ex_Line2 = -90; // 【買い|決済】ウィリアムズライン2
int RSI_Period1 = 8; // 【買い|エントリー】RSI期間1
int RSI_Line1 = 72; // 【買い|エントリー】RSIライン1
int RSI_Ex_Line1 = 68; // 【買い|決済】RSIライン1
int RSI_Period2 = 8; // 【買い|エントリー】RSI期間2
int RSI_Line2 = 73; // 【買い|エントリー】RSIライン2
int RSI_Ex_Line2 = 67; // 【買い|決済】RSIライン2
//エントリーフィルター
int Gap_Pips = 1; // フィルター1|1本前ローソク足終値と現在価格の差pips
double ATR_D14;
ENUM_TIMEFRAMES ATR_TF = PERIOD_D1;
int ATR_PERIOD = 14;
double ALim = 21.0; // フィルター3|ATR15Low
ENUM_TIMEFRAMES MA_TF_buy1 = PERIOD_M30; // 【買い|フィルター】MAタイムフレーム1
int MA_Period_buy1 = 50; // 【買い|フィルター】MA期間1
ENUM_TIMEFRAMES MA_TF_sell1 = PERIOD_M30; // 【売り|フィルター】MAタイムフレーム1
int MA_Period_sell1 = 60; // 【売り|フィルター】MA期間1
ENUM_TIMEFRAMES MA_TF_buy2 = PERIOD_D1; // 【買い|フィルター】MAタイムフレーム2
int MA_Period_buy2 = 70; // 【買い|フィルター】MA期間2
ENUM_TIMEFRAMES MA_TF_sell2 = PERIOD_D1; // 【売り|フィルター】MAタイムフレーム2
int MA_Period_sell2 = 100; // 【売り|フィルター】MA期間2
ENUM_TIMEFRAMES SD_TF1 = PERIOD_D1; // 【共通|フィルター】SDタイムフレーム1
int SD_Period1 = 20; // 【共通|フィルター】SD期間1
double SD_Value1 = 33.0; // 【共通|フィルター】SD値1
int SDx_count1 = 1; // 【共通|フィルター】SDカウント本数1
ENUM_TIMEFRAMES SD_TF2 = PERIOD_D1; // 【共通|フィルター】SDタイムフレーム2
int SD_Period2 = 20; // 【共通|フィルター】SD期間2
double SD_Value2 = 100.0; // 【共通|フィルター】SD値2
int SDx_count2 = 1; // 【共通|フィルター】SDカウント本数2
//決済ルールの各変数
int ExTime1 = 8; // 【共通|決済】強制決済時刻1
int ExMinute1 = 0; // 【共通|決済】強制決済分1
int ExTime2 = 4; // 【共通|決済】強制決済時刻2
int ExMinute2 = 0; // 【共通|決済】強制決済分2
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| tester function |
//+------------------------------------------------------------------+
double OnTester()
{
// OnTesterに表示【リカバリーファクター|勝率】
if (Development == true)
{
// リカバリーファクター
return(NormalizeDouble(TesterStatistics(STAT_PROFIT) / TesterStatistics(STAT_EQUITY_DD), 2));
// 勝率
// return(NormalizeDouble(100*TesterStatistics(STAT_PROFIT_TRADES) / TesterStatistics(STAT_TRADES), 2));
}
return(0);
}
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//+------------------------------------------------------------------+
// 小数点以下の桁数に応じてPipsの値を調整する
xpoint = Point();
if (Digits() == 2 || Digits() == 5)
{
xpoint = xpoint * 10;
}
else if (Digits() == 3)
{
xpoint = xpoint * 100;
}
//+------------------------------------------------------------------+
// バックテストのモード切り替え
if (BacktestMode == true)
{
EntryOK_StartTime1 = 1;
}
//+------------------------------------------------------------------+
// 最大SL算出(コメント・複利の計算で使用)
TakeProfit_pips = MathMax(TakeProfit_pips1, TakeProfit_pips2);
StopLoss_pips = MathMax(StopLoss_pips1, StopLoss_pips2);
//+------------------------------------------------------------------+
// DPI換算
double USERdpi = TerminalInfoInteger(TERMINAL_SCREEN_DPI);
double DevPCdpi = 144;
DPIAdjust = USERdpi / DevPCdpi;
//+------------------------------------------------------------------+
// 初期化スプレッド(バックテスト時または手動時、それ以外や自動)
if (IsTesting() || AllowSpread != 0) MaxSpread_pips = AllowSpread;
if (AllowSpread == 0) MaxSpread_pips = AllowMaxSpread;
//+------------------------------------------------------------------+
// チャート自動変更・シンボル・チャートコメント・状態表示
if (!IsTesting())
{
ChartSet(); // チャート自動変更
CenterSymbol(); // 中央のシンボル
ChartComment(); // チャートコメント
EA_test(); // 状態表示
EventSetTimer(60); // 状態表示
}
//+------------------------------------------------------------------+
// トレード履歴をチャートに表示(ライン・pips)
history();
PosHis();
//+------------------------------------------------------------------+
// 開発モード(販売時はfalseに)
if (Development) HideTestIndicators(false);// 使用しているインジケータを表示する
else HideTestIndicators(true);// 使用しているインジケータを非表示にする
//+------------------------------------------------------------------+
// マジックナンバー重複セットアラート
if (check_duplicate)
{
double term_global_var;
if (GlobalVariableGet(kEA_NAME, term_global_var))
{
Alert("Magic numbers are duplicated" +"\n"+ "マジックナンバー重複");
}
const datetime mutex_time = GlobalVariableSet(kEA_NAME, 1.0);
if (mutex_time == 0)
{
const int errcode = GetLastError();
Print("GlobalVariableSet: ERRCODE[", errcode, "]:", ErrorDescription(errcode));
}
}
//+------------------------------------------------------------------+
return(0);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if (!IsTesting())
{
ObjectsDeleteAll();
ChartSetInteger(0,CHART_COLOR_CHART_UP,clrLime);
ChartSetInteger(0,CHART_COLOR_CHART_DOWN,clrLime);
ChartSetInteger(0,CHART_COLOR_CHART_LINE,clrLime);
Comment("");
}
// マジックナンバー重複用
if (check_duplicate)
{
if (!GlobalVariableDel(kEA_NAME))
{
const int errcode = GetLastError();
Print("GlobalVariableDel: ERRCODE[", errcode, "]:", ErrorDescription(errcode));
}
}
// 状態表示
EventKillTimer();
ObjectDelete("EA_label");
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//+------------------------------------------------------------------+
// サマータイム調整・時間制御
GetSummertimeShift();
// ポジションをクローズ
PositionClose();
// ポジションのエントリー
PositionOpen();
// TP, SLの再設定
SetTPSL();
//+------------------------------------------------------------------+
// チャート自動変更・シンボル・チャートコメント・状態表示
if (!IsTesting())
{
CenterSymbol(); // センターにシンボル情報
ChartComment(); // チャートコメント
CT++; // 状態表示用
EA_test(); // 状態表示
}
//+------------------------------------------------------------------+
// スプレッド値取得
if (!IsTesting() && AllowSpread == 0)
{
MeasureSpread = MarketInfo(Symbol(),MODE_SPREAD) / 10;
MeasureSP();
//PipsObject();
}
//+------------------------------------------------------------------+
// チャートにトレード線とpips表示
if (!IsTesting() || IsVisualMode())
{
if (sf != Seconds() && OrdersTotal() > 0)
{
PosHis();
sf = Seconds();
}
if ((hf != iTime((string)0, 60, 0) && Seconds() > 30) || tof != OrdersHistoryTotal())
{
history();
hf = iTime((string)0, 60, 0);
tof = OrdersHistoryTotal();
}
}
//+------------------------------------------------------------------+
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 補正関数 |
//+------------------------------------------------------------------+
void GetSummertimeShift()
{
int MON, SUN_day, xGMT;
int summertime_shift = 0;
datetime gmtadjusted;
// GMT+9を基準に、どれだけずれているかを算出する------------------------
MON = TimeMonth(TimeCurrent()); // 何月?
SUN_day = TimeDay(TimeCurrent()) - TimeDayOfWeek(TimeCurrent()); // その週の日曜日は何日?
if (Summertime == 2) // 英国式の場合
{
if ((MON == 3 && SUN_day >= 25) || (MON >= 4 && MON <= 9) || (MON == 10 && SUN_day <= 24))
//3月で、その週の日曜日が25日以上/4月~9月/10月で、その週の日曜日が23日以下
{
summertime_shift = 1;
}
else
{
summertime_shift = 0;
}
}
else if (Summertime == 1) // 米国式の場合
{
if ((MON == 3 && SUN_day >= 8) || (MON >= 4 && MON <= 10) || (MON == 11 && SUN_day <= 0))
//3月で、その週の日曜日が8日以上/4月~10月/11月で、その週の日曜日が存在しない
{
summertime_shift = 1;
}
else
{
summertime_shift = 0;
}
}
else // サマータイム無しの場合
{
summertime_shift = 0;
}
xGMT = GMT - 9 + summertime_shift;//GMT+9を基準に
//GMT+9基準でどれだけずれているかを算出する(ココマデ)--------------------
//+------------------------------------------------------------------+
//| 時間制御 |
//+------------------------------------------------------------------+
//---- トレード許可時間の判定 ----
xTime = TimeHour(TimeCurrent()) - xGMT; // 日本時間
xxTime = TimeHour(TimeCurrent()) - (GMT - 2); // サーバー時間(サマータイム計算なし)
xxxTime = TimeHour(TimeCurrent()) - (GMT - 2 + summertime_shift); // サーバー時間(サマータイム計算あり)
yTime = TimeMinute(TimeCurrent()); // サーバーの分
gmtadjusted = TimeCurrent() - 60 * 60 * xGMT;
// 日本時間
if (xTime < 0)
{
xTime = xTime + 24;
}
else if (xTime > 23)
{
xTime = xTime - 24;
}
// サーバー時間
if (xxTime < 0)
{
xxTime = xxTime + 24;
}
else if (xxTime > 23)
{
xxTime = xxTime - 24;
}
// サーバー時間(サマータイムあり)
if (xxxTime < 0)
{
xxxTime = xxxTime + 24;
}
else if (xxxTime > 23)
{
xxxTime = xxxTime - 24;
}
// 週末ポジションクローズ
if ((xTime == PositionClose_Time_W
&& TimeDayOfWeek(gmtadjusted) == PositionClose_DayOfWeek1
&& WeekendTrade == true)
)
{
PositionClose = true;
}
else
{
PositionClose = false;
}
// エントリーNG時間
if ( // 週末決済(日本時間)
(xTime >= EntryNG_StartTime1 && xTime <= EntryNG_EndTime1 // 週末決済用(日本時間)
&& TimeDayOfWeek(gmtadjusted) >= EntryNG_DayOfWeek1 // 週末決済曜日(日本時間)
&& WeekendTrade == false)
||
(xxTime <= 1 && TimeDayOfWeek(TimeCurrent()) == 1 && Monday0Trade == false) // 月朝トレード
)
{
GMT_Kadou_NG = true;
}
else
{
GMT_Kadou_NG = false;
}
// ロールオーバー・メンテナンス時間
if (((xxTime == 23 && yTime >= 55 && TimeDayOfWeek(TimeCurrent()) != 5)
|| (xxTime == 23 && yTime >= 50 && TimeDayOfWeek(TimeCurrent()) == 5)
|| (xxTime == 0 && yTime <= 9))
&& BacktestMode == true)
{
ROTime = true;
}
else
{
ROTime = false;
}
// エントリーOK時間
if ( (xxTime >= EntryOK_StartTime1 && xxTime <= EntryOK_EndTime1) // エントリー可能時間1(サーバー時間)
|| (xxTime >= EntryOK_StartTime2 && xxTime <= EntryOK_EndTime2)) // エントリー可能時間2(サーバー時間)
{
Logic1_Time = true;
}
else
{
Logic1_Time = false;
}
// ここまで、エグジットとトレーリングは、取引時間に関係なく実施する
//---- トレード許可時間の判定(ココマデ) ----
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ポジションのクローズ |
//+------------------------------------------------------------------+
void PositionClose()
{
int i;
double profit;
bool res;
// 始値から指定ティックのみ判定
if(Volume[0] <= 10)
{
// 所有しているポジションをクローズする
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;
//エントリーからのローソク足本数が1本未満なら、for文の先頭に戻る)
int OrderOpenCandleCount = iBarShift(NULL, 0, OrderOpenTime());
if (OrderOpenCandleCount == 0) continue;
if (OrderType() == OP_BUY)
{
profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する
// オーダーを成り行き決済する
if ( ROTime == false &&
( (Exit2(false) == 2 && Ask - Bid <= MaxSpread_pips * xpoint)
|| (Exit2(false) == 2 && Ask - Bid > MaxSpread_pips * xpoint && profit > 0)
|| PositionClose == true
)
)
{
res = OrderClose(OrderTicket(), OrderLots(), Bid, NULL, Green);
}
}
if (OrderType() == OP_SELL)
{
profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の、含み損益を計算する
// オーダーを成り行き決済する
if ( ROTime == false &&
( (Exit1(true) == 1 && Ask - Bid <= MaxSpread_pips * xpoint)
|| (Exit1(true) == 1 && Ask - Bid > MaxSpread_pips * xpoint && profit > 0)
|| PositionClose == true
)
)
{
res = OrderClose(OrderTicket(), OrderLots(), Ask, NULL, Green);
}
}
} // 所有しているポジションをクローズする(ココマデ)
} // 始値から指定ティックのみ判定(ココマデ)
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ポジションのオープン |
//+------------------------------------------------------------------+
void PositionOpen()
{
int i, j;
int ticket;
int CountBuy = 0,CountSell = 0;
bool res;
int OrderOpen_BarCount_buy = 1; // 0にすると、履歴無いときにエントリーしないため、他の値を初期値にする
int OrderOpen_BarCount_sell = 1;
int OrderClose_BarCount_buy = 1;
int OrderClose_BarCount_sell = 1;
// 始値から指定ティックのみ判定
if(Volume[0] <= 5)
{
// ポジションの数をカウントする
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;
}
aCmd = OrderType();
} // ポジションの数をカウントする(ココマデ)
// 最終決済からのローソク足本数をカウントする
for(j=OrdersHistoryTotal()-1; j>=0; j--)
{
//オーダー選択(エラーを生じた場合、ループから抜け出す)
if (OrderSelect( j, SELECT_BY_POS, MODE_HISTORY ) == false)
{
Print("OrderSelect returned the error of ", GetLastError() );
break;
}
//オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る)
if (OrderSymbol() != Symbol()) continue;
//マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る)
if (OrderMagicNumber() != MagicNumber) continue;
//最終決済からのローソク足本数
if (OrderType() == OP_BUY) // 買いの場合
{
OrderOpen_BarCount_buy = iBarShift(NULL, 0, OrderOpenTime());
OrderClose_BarCount_buy = iBarShift(NULL, 0, OrderCloseTime());
if (OrderClose_BarCount_buy != -1) break; // 一度最終決済を抽出したらループから抜ける
}
if (OrderType() == OP_SELL) // 売りの場合
{
OrderOpen_BarCount_sell = iBarShift(NULL, 0, OrderOpenTime());
OrderClose_BarCount_sell = iBarShift(NULL, 0, OrderCloseTime());
if (OrderClose_BarCount_sell != -1) break; // 一度最終決済を抽出したらループから抜ける
}
} // 最終決済からのローソク足本数をカウントする(ココマデ)
ATR_D14 = iATR(NULL, ATR_TF, ATR_PERIOD, 1);
if (ATR_D14 < ALim)
{
TakeProfit_pips = TakeProfit_pips1;
StopLoss_pips = StopLoss_pips1;
}
else if (ATR_D14 >= ALim)
{
TakeProfit_pips = TakeProfit_pips2;
StopLoss_pips = StopLoss_pips2;
}
// 証拠金不足・トレード許可チェック
if (EquityCheck())
{
// エントリー条件を確認し、成立していればエントリーを行う
if (Entry(true) == 1 // 買いエントリー
&& CountSell == 0
&& CountBuy < Maxposition
&& GMT_Kadou_NG == false
&& Logic1_Time == true
&& Buy_Entry == true
&& Exit2(false) != 2 // 買い決済シグナル無し
)
{
ticket = OrderSend(Symbol(),
OP_BUY,
CalculateLots(MM_Risk, StopLoss_pips),
Ask,
Slippage,
Ask - StopLoss_pips * xpoint,
Ask + TakeProfit_pips * xpoint,
_Comment,
MagicNumber,
0,
Blue);
// エントリーが失敗であれば、TPSLを分割して注文する
if (ticket == -1)
{
ticket = OrderSend(Symbol(),
OP_BUY,
CalculateLots(MM_Risk, StopLoss_pips),
Ask,
Slippage,
0,
0,
_Comment,
MagicNumber,
0,
Blue);
// エントリーに成功していれば、TP, SLをセットする
if (ticket != -1)
{
// チケットを使ってオーダーを選択(エラーを生じた場合、何もしない)
if( OrderSelect( ticket, SELECT_BY_TICKET ) == true )
{
res = OrderModify(OrderTicket(),
OrderOpenPrice(),
OrderOpenPrice() - StopLoss_pips * xpoint,
OrderOpenPrice() + TakeProfit_pips * xpoint,
0, MediumSeaGreen);
}
}
}
}
else if (Entry(false) == 2 // 売りエントリー
&& CountBuy == 0
&& CountSell < Maxposition
&& GMT_Kadou_NG == false
&& Logic1_Time == true
&& Sell_Entry == true
&& Exit1(true) != 1 // 売り決済シグナル無し
)
{
ticket = OrderSend(Symbol(),
OP_SELL,
CalculateLots(MM_Risk, StopLoss_pips),
Bid,
Slippage,
Bid + StopLoss_pips * xpoint,
Bid - TakeProfit_pips * xpoint,
_Comment,
MagicNumber,
0,
Red);
// エントリーが失敗であれば、TPSLを分割して注文する
if (ticket == -1)
{
ticket = OrderSend(Symbol(),
OP_SELL,
CalculateLots(MM_Risk, StopLoss_pips),
Bid,
Slippage,
0,
0,
_Comment,
MagicNumber,
0,
Red);
// エントリーに成功していれば、TP, SLをセットする
if (ticket != -1)
{
// チケットを使ってオーダーを選択(エラーを生じた場合、何もしない)
if( OrderSelect( ticket, SELECT_BY_TICKET ) == true )
{
res = OrderModify(OrderTicket(),
OrderOpenPrice(),
OrderOpenPrice() + StopLoss_pips * xpoint,
OrderOpenPrice() - TakeProfit_pips * xpoint,
0, MediumSeaGreen);
}
}
}
}
}
} // 始値から指定ティックのみ判定(ココマデ)
}
//+------------------------------------------------------------------+
bool EquityCheck()
{
// 証拠金不足・トレード許可チェック
double usedMoney = AccountEquity() - AccountFreeMarginCheck(Symbol(), aCmd, CalculateLots(MM_Risk, StopLoss_pips));
if (!(
(AccountStopoutMode() == 0 && usedMoney > 0.0 && (AccountEquity() / usedMoney) * 100 <= AccountStopoutLevel())
|| (AccountStopoutMode() == 0 && usedMoney > 0.0 && AccountFreeMarginCheck(Symbol(), aCmd, CalculateLots(MM_Risk, StopLoss_pips)) <= 0)
|| (AccountStopoutMode() == 1 && AccountFreeMarginCheck(Symbol(), aCmd, CalculateLots(MM_Risk, StopLoss_pips)) <= AccountStopoutLevel())
)
&& IsTradeAllowed() == true) // トレード許可判定
{
return(true);
}
else return(false);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| TakeProfit, StopLoss |
//+------------------------------------------------------------------+
void SetTPSL()
{
int i;
double profit;
bool res;
// 始値から指定ティックのみ判定
if(Volume[0] <= 1)
{
// ポジションに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;
ATR_D14 = iATR(NULL, ATR_TF, ATR_PERIOD, 1);
if (ATR_D14 < ALim)
{
TakeProfit_pips = TakeProfit_pips1;
StopLoss_pips = StopLoss_pips1;
}
else if (ATR_D14 >= ALim)
{
TakeProfit_pips = TakeProfit_pips2;
StopLoss_pips = StopLoss_pips2;
}
// 買いポジションの場合
if (OrderType() == OP_BUY)
{
profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する
// TP, SLがどちらも設定されていなければ、TP, SLを設定する
if (OrderStopLoss() == 0 && OrderTakeProfit() == 0)
{
res = OrderModify(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 = OrderModify(OrderTicket(),
OrderOpenPrice(),
OrderOpenPrice() + StopLoss_pips * xpoint,
OrderOpenPrice() - TakeProfit_pips * xpoint,
0, MediumSeaGreen);
}
}
}
} // 始値から指定ティックのみ判定(ココマデ)
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 複利機能 |
//+------------------------------------------------------------------+
// 複利機能のロット数を計算する
double CalculateLots(double risk, // 許容するリスク
int sl_pips) // ストップロス
{
// バックテスト時は、バックテスト用の複利機能を使用する
if (IsTesting())
return(CalculateLots_forTest(risk, sl_pips));
else
return(CalculateLots_forReal(risk, sl_pips));
}
// 複利機能のロット数を計算する(実トレード用)
double CalculateLots_forReal(double risk, // 許容するリスク
int sl_pips) // ストップロス
{
double freemargin; // アカウントの余剰証拠金
double balance; // アカウントの口座残高
double credit; // アカウントのクレジット
double tickvalue; // 1ロット1pip当たりの証拠金通貨相当額
double lotstep; // サーバのロット数の最小刻み制限
double maxlots; // サーバの最大ロット数制限
double minlots; // サーバの最小ロット数制限
double lotsize = Lots; // ロットサイズ
freemargin = AccountFreeMargin();
balance = AccountBalance();
credit = AccountCredit();
tickvalue = MarketInfo(NULL, MODE_TICKVALUE);
lotstep = MarketInfo(NULL, MODE_LOTSTEP);
maxlots = MarketInfo(NULL, MODE_MAXLOT);
minlots = MarketInfo(NULL, MODE_MINLOT);
// 複利機能を使わない場合、Lotsから修正されたlotsizeを返す
int step = (int)MathAbs(MathLog10(MarketInfo(Symbol(), MODE_LOTSTEP)));
lotsize = NormalizeDouble(Lots, (int)step); //ロットステップで四捨五入
lotsize = MathMax(minlots, MathMin(maxlots, lotsize)); //最小ロット以下なら最小ロットに、最大ロット以上なら最大ロットに修正
if (MM_ON == Fixed) return(lotsize);
// tickvalueはpipsではなくpointなので、小数点以下の桁数に応じて補正する
if (StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD")
{
if (Digits() == 2)
tickvalue = tickvalue * 10;
else if (Digits() == 3)
tickvalue = tickvalue * 100;
}
else if (!(StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD"))
{
if (Digits() == 3 || Digits() == 5)
tickvalue = tickvalue * 10;
}
// 許容するリスクとSLの幅から、ロットサイズを計算する。
if (MM_ON == FreeMargin) // 余剰証拠金方式
{
lotsize = (freemargin * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%)
/ (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額
}
else if (MM_ON == Balance) // 残高方式
{
lotsize = (balance * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%)
/ (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額
}
else if (MM_ON == AddCredit) // 残高+クレジット方式
{
lotsize = ((balance + credit) * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%)
/ (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額
}
// サーバのロット数の刻みに合わせてロット数を修正
lotsize = MathFloor(lotsize / lotstep) * lotstep;
// サーバの最小ロット数・最大ロット数で補正をかける
lotsize = MathMax(lotsize, minlots);
lotsize = MathMin(lotsize, maxlots);
return(lotsize);
}
// 複利機能のロット数を計算する(バックテスト用)
double CalculateLots_forTest(double risk, // 許容するリスク
int sl_pips) // ストップロス
{
double freemargin; // アカウントの余剰証拠金
double balance; // アカウントの口座残高
double credit; // アカウントのクレジット
double tickvalue; // 1ロット1pip当たりの証拠金通貨相当額
double lotstep; // サーバのロット数の最小刻み制限
double maxlots; // サーバの最大ロット数制限
double minlots; // サーバの最小ロット数制限
double lotamount; // 1ロットの通貨数
double lotsize = Lots; // ロットサイズ
double conv; // 口座通貨種類による補正係数
freemargin = AccountFreeMargin();
balance = AccountBalance();
credit = AccountCredit();
tickvalue = MarketInfo(NULL, MODE_TICKVALUE);
lotstep = MarketInfo(NULL, MODE_LOTSTEP);
maxlots = MarketInfo(NULL, MODE_MAXLOT);
minlots = MarketInfo(NULL, MODE_MINLOT);
lotamount = MarketInfo(NULL, MODE_LOTSIZE);
// 複利機能を使わない場合、Lotsから修正されたlotsizeを返す
int step = (int)MathAbs(MathLog10(MarketInfo(Symbol(), MODE_LOTSTEP)));
lotsize = NormalizeDouble(Lots, step); //ロットステップで四捨五入
lotsize = MathMax(minlots, MathMin(maxlots, lotsize)); //最小ロット以下なら最小ロットに、最大ロット以上なら最大ロットに修正
if (MM_ON == Fixed) return(lotsize);
// 1万通貨*1pips = $1 = 100円と仮定し、1ロット1pipの変動が口座通貨でいくらに相当するか計算
// 1 lot = 10万通貨
// 口座通貨 = JPY : tickvalue = 1000円/(lot・pip)
// 口座通貨 = USD : tickvalue = $10/(lot・pip)
if (StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD")
{
conv = 1000;
if (AccountCurrency() == "JPY")
conv = 100000;
tickvalue = lotamount / 10000 * conv;
}
else if (!(StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD"))
{
conv = 1;
if (AccountCurrency() == "JPY")
conv = 100;
tickvalue = lotamount / 10000 * conv;
}
// 許容するリスクとSLの幅から、ロットサイズを計算する。
if (MM_ON == FreeMargin) // 余剰証拠金方式
{
lotsize = (freemargin * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%)
/ (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額
}
else if (MM_ON == Balance) // 残高方式
{
lotsize = (balance * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%)
/ (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額
}
else if (MM_ON == AddCredit) // 残高+クレジット方式
{
lotsize = ((balance + credit) * risk / 100.0) // 許容するリスク (余剰証拠金のrisk%)
/ (sl_pips * tickvalue); // 1ロットでSLにかかった時の金額
}
// サーバのロット数の刻みに合わせてロット数を修正
lotsize = MathFloor(lotsize / lotstep) * lotstep;
// サーバの最小ロット数・最大ロット数で補正をかける
lotsize = MathMax(lotsize, minlots);
lotsize = MathMin(lotsize, maxlots);
return(lotsize);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリー総括 |
//+------------------------------------------------------------------+
int Entry(bool isbuy)
{
if (Entry_Rule1(isbuy) == 1 && (Entry_Filter1(isbuy) == 1 || Entry_Filter1(isbuy) == 3)
&& (Entry_Filter2(isbuy) == 1 || Entry_Filter2(isbuy) == 3)
&& (Entry_Filter3(isbuy) == 1 || Entry_Filter3(isbuy) == 3)
&& (Entry_Filter4(isbuy) == 1 || Entry_Filter4(isbuy) == 3)
&& (Entry_Filter5(isbuy) == 1 || Entry_Filter5(isbuy) == 3)
)
{
return(1);
}
else if (Entry_Rule1(isbuy) == 2 && (Entry_Filter1(isbuy) == 2 || Entry_Filter1(isbuy) == 3)
&& (Entry_Filter2(isbuy) == 2 || Entry_Filter2(isbuy) == 3)
&& (Entry_Filter3(isbuy) == 2 || Entry_Filter3(isbuy) == 3)
&& (Entry_Filter4(isbuy) == 2 || Entry_Filter4(isbuy) == 3)
&& (Entry_Filter5(isbuy) == 2 || Entry_Filter5(isbuy) == 3)
)
{
return(2);
}
else
{
return(0);
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 売りポジションの決済総括 |
//+------------------------------------------------------------------+
int Exit1(bool isbuy)
{
if (Exit_Rule1(isbuy) == 3 && Exit_Rule2(isbuy) == 3 && Exit_Rule3(isbuy) == 3
&& Exit_Rule4(isbuy) == 3 && Exit_Rule5(isbuy) == 3)
{
return(0);
}
else if (Exit_Rule1(isbuy) == 1)
{
return(1);
}
else if (Exit_Rule2(isbuy) == 1)
{
return(1);
}
else if (Exit_Rule3(isbuy) == 1)
{
return(1);
}
else if (Exit_Rule4(isbuy) == 1)
{
return(1);
}
else if (Exit_Rule5(isbuy) == 1)
{
return(1);
}
else
{
return(0);
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 買いポジションの決済総括 |
//+------------------------------------------------------------------+
int Exit2(bool isbuy)
{
if (Exit_Rule1(isbuy) == 3 && Exit_Rule2(isbuy) == 3 && Exit_Rule3(isbuy) == 3
&& Exit_Rule4(isbuy) == 3 && Exit_Rule5(isbuy) == 3)
{
return(0);
}
else if (Exit_Rule1(isbuy) == 2)
{
return(2);
}
else if (Exit_Rule2(isbuy) == 2)
{
return(2);
}
else if (Exit_Rule3(isbuy) == 2)
{
return(2);
}
else if (Exit_Rule4(isbuy) == 2)
{
return(2);
}
else if (Exit_Rule5(isbuy) == 2)
{
return(2);
}
else
{
return(0);
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリールール1 |
//+------------------------------------------------------------------+
int Entry_Rule1(bool isbuy)
{
//エントリールール1
//RSIが指定値以下になったら「買い」、指定値以上になったら「売り」
//かつ、1本前と2本前のRSI値差が指定範囲以内ならエントリー可(価格変動の速度制御)
double RSI1 = iRSI(NULL, PERIOD_M5, (ATR_D14 < ALim? RSI_Period1 : RSI_Period2), PRICE_CLOSE, 1);
double RSI2 = iRSI(NULL, PERIOD_M5, (ATR_D14 < ALim? RSI_Period1 : RSI_Period2), PRICE_CLOSE, 2);
//ウィリアムズ%Rが指定値以下にいる間は「買い」、指定値以上にいる間は「売り」
double WPR1 = iWPR(NULL, PERIOD_M5, (ATR_D14 < ALim? WPR_Period1 : WPR_Period2), 1);
double WPR2 = iWPR(NULL, PERIOD_M5, (ATR_D14 < ALim? WPR_Period1 : WPR_Period2), 2);
if ( isbuy == true && Logic1_Time == true //&& LowerBB20_1 >= Close[1]
&& (RSI1 <= 100 - (ATR_D14 < ALim? RSI_Line1 : RSI_Line2)
|| WPR1 <= (ATR_D14 < ALim? WPR_Line1 : WPR_Line2))
)
{
return(1);
} // 買い
if ( isbuy == false && Logic1_Time == true //&& UpperBB20_1 <= Close[1]
&& (RSI1 >= (ATR_D14 < ALim? RSI_Line1 : RSI_Line2)
|| WPR1 >= -100 - (ATR_D14 < ALim? WPR_Line1 : WPR_Line2))
)
{
return(2);
} // 売り
return(0);
// エントリー出来ない
//エントリールール1ココマデ
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター1 |
//+------------------------------------------------------------------+
int Entry_Filter1(bool isbuy)
{
//エントリーフィルター1
//スプレッドフィルター
double spread = MarketInfo(NULL, MODE_SPREAD);
if (StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD") // ゴールド桁合わせ
{
if (Digits() == 2) spread /= 10.0;
else if (Digits() == 3) spread /= 100.0;
}
else if (!(StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD")) // ゴールド以外桁合わせ
{
if (Digits == 3 || Digits == 5) spread /= 10.0;
}
if (spread > MaxSpread_pips) return(0);
//ローソク足マージンフィルター
// (現在価格-1本足終値)が、指定pips以上だったら買い禁止(売りは逆)
if(isbuy == true && Close[0] - Close[1] >= Gap_Pips * xpoint) return(0);
if(isbuy == false && Close[1] - Close[0] >= Gap_Pips * xpoint) return(0);
//年末年始フィルター
//12/20~1/3まではエントリーしない
int NGMonth = Month();
int NGDay = Day();
if (YearendClose == true
&& ((NGMonth == 12 && NGDay >= 20) || (NGMonth == 1 && NGDay <= 3))
)
{
return(0);
} // エントリー出来ない
//エントリーフィルター1ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター2 |
//+------------------------------------------------------------------+
int Entry_Filter2(bool isbuy)
{
//エントリーフィルター2
//ボラティリティフィルター|ATRが基準値を越えたら、エントリー禁止
if (Mode1 == 1)
{
if (ATR_D14 >= ALim) return(0);
}
if (Mode1 == 2)
{
if (ATR_D14 < ALim) return(0);
}
//エントリーフィルター2ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター3 |
//+------------------------------------------------------------------+
int Entry_Filter3(bool isbuy)
{
//エントリーフィルター3
// MAフィルター
// 指定MAより下なら買い不可、上なら売り不可
double MA11_buy = iMA(NULL, (ATR_D14 < ALim? MA_TF_buy1 : MA_TF_buy2), (ATR_D14 < ALim? MA_Period_buy1 : MA_Period_buy2), 0, MODE_SMA, PRICE_CLOSE, 1);
double MA12_buy = iMA(NULL, (ATR_D14 < ALim? MA_TF_buy1 : MA_TF_buy2), (ATR_D14 < ALim? MA_Period_buy1 : MA_Period_buy2), 0, MODE_SMA, PRICE_CLOSE, 2);
double MA11_sell = iMA(NULL, (ATR_D14 < ALim? MA_TF_sell1 : MA_TF_sell2), (ATR_D14 < ALim? MA_Period_sell1 : MA_Period_sell2), 0, MODE_SMA, PRICE_CLOSE, 1);
double MA12_sell = iMA(NULL, (ATR_D14 < ALim? MA_TF_sell1 : MA_TF_sell2), (ATR_D14 < ALim? MA_Period_sell1 : MA_Period_sell2), 0, MODE_SMA, PRICE_CLOSE, 2);
if (isbuy == true && Close[1] < MA11_buy)
{
return(0);
} // 買い禁止
if (isbuy == false && Close[1] > MA11_sell)
{
return(0);
} // 売り禁止
//エントリーフィルター3ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター4 |
//+------------------------------------------------------------------+
int Entry_Filter4(bool isbuy)
{
//エントリーフィルター4
// SDの値が一定以上ならエントリー禁止
for (int SDx_buy1=1; SDx_buy1<=(ATR_D14 < ALim? SDx_count1 : SDx_count2); SDx_buy1++)
{
double StdDev_buy1 = iStdDev(NULL, (ATR_D14 < ALim? SD_TF1 : SD_TF2), (ATR_D14 < ALim? SD_Period1 : SD_Period2), 0, MODE_SMA, PRICE_CLOSE, 1);
if (StdDev_buy1 >= (ATR_D14 < ALim? SD_Value1 : SD_Value2)) return(0);
}
//エントリーフィルター4ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター5 |
//+------------------------------------------------------------------+
int Entry_Filter5(bool isbuy)
{
//エントリーフィルター5
//エントリーフィルター5ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール1 |
//+------------------------------------------------------------------+
int Exit_Rule1(bool isbuy)
{
// 決済ルール1
//WPRが指定値以上になったら「買いポジション決済」、指定値以下になったら「売りポジション決済」
double WPR1 = iWPR(NULL, PERIOD_M5, (ATR_D14 < ALim? WPR_Period1 : WPR_Period2), 1);
// WPRが指定以上になったら買いポジション決済
if (WPR1 >= - 100 - (ATR_D14 < ALim? WPR_Ex_Line1 : WPR_Ex_Line2))
{
return(2);
}
else if (WPR1 <= (ATR_D14 < ALim? WPR_Ex_Line1 : WPR_Ex_Line2))
{
return(1);
}
else
{
return(0);
}
// 決済ルール1ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール2 |
//+------------------------------------------------------------------+
int Exit_Rule2(bool isbuy)
{
// 決済ルール2
//RSIが指定値以上になったら「買いポジション決済」、指定値以下になったら「売りポジション決済」
double RSI1 = iRSI(NULL, PERIOD_M5, (ATR_D14 < ALim? RSI_Period1 : RSI_Period2), PRICE_CLOSE, 1);
// RSIが指定以上になったら買いポジション決済
if (RSI1 >= (ATR_D14 < ALim? RSI_Ex_Line1 : RSI_Ex_Line2))
{
return(2);
}
else if (RSI1 <= 100 - (ATR_D14 < ALim? RSI_Ex_Line1 : RSI_Ex_Line2))
{
return(1);
}
else
{
return(0);
}
// 決済ルール2ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール3 |
//+------------------------------------------------------------------+
int Exit_Rule3(bool isbuy)
{
// 決済ルール3
// 時間決済|指定時以降決済。予備でエントリー開始可能時間以前で決済
if ((xxTime == (ATR_D14 < ALim? ExTime1 : ExTime2) && yTime >= (ATR_D14 < ALim? ExMinute1 : ExMinute2))
|| ( xxTime > (ATR_D14 < ALim? ExTime1 : ExTime2) && xxTime < EntryOK_StartTime2)
)
{
PositionClose = true;
}
else
{
PositionClose = false;
}
// 決済ルール3ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール4 |
//+------------------------------------------------------------------+
int Exit_Rule4(bool isbuy)
{
// 決済ルール4
// 逆側のエントリーサインが出たら決済
if (Entry(true) == 1)
{
return(1);
}
if (Entry(false) == 2)
{
return(2);
}
// 決済ルール4ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール5 |
//+------------------------------------------------------------------+
int Exit_Rule5(bool isbuy)
{
// 決済ルール5
// 決済ルール5ココマデ
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| チャート自動セット(初期化工程) |
//+------------------------------------------------------------------+
void ChartSet()
{
// 気配値強制表示&自動切替
int chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); // チャート幅の計算
int textWidth = 200;//StringLen(WindowExpertName()) * 12; // 固定値pxまたはテキストの幅の計算
double ShiftPer = textWidth * 100 / chartWidth;
if (!IsTesting())
{
if (StringSubstr(Symbol(), 0, 6) != SYMBOL1 || Period() != Chart_TimeFrame)
{
SymbolSelect(SYMBOL1 + StringSubstr(Symbol(), 6, StringLen(Symbol())), true);
ChartSetSymbolPeriod(0, SYMBOL1 + StringSubstr(Symbol(), 6, StringLen(Symbol())), Chart_TimeFrame);
}
// 現在のシンボルが4文字の場合。無しならコメントアウト
if (StringSubstr(Symbol(), 0, 4) != SYMBOL2 || Period() != Chart_TimeFrame)
{
SymbolSelect(SYMBOL2 + StringSubstr(Symbol(), StringSubstr(Symbol(), 0, 4) == SYMBOL2? 4 : 6, StringLen(Symbol())), true);
ChartSetSymbolPeriod(0, SYMBOL2 + StringSubstr(Symbol(), StringSubstr(Symbol(), 0, 4) == SYMBOL2? 4 : 6, StringLen(Symbol())), Chart_TimeFrame);
}
ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrBlack);
ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrWhite);
ChartSetInteger(0, CHART_COLOR_GRID, clrLightSlateGray);
ChartSetInteger(0, CHART_COLOR_CHART_UP, clrOlive);
ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrOlive);
ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrBlack);
ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrBeige);
ChartSetInteger(0, CHART_COLOR_CHART_LINE, clrOlive);
ChartSetInteger(0, CHART_COLOR_VOLUME, clrOlive);
ChartSetInteger(0, CHART_COLOR_ASK, clrRed);
ChartSetInteger(0, CHART_COLOR_STOP_LEVEL, clrRed);
ChartSetInteger(0, CHART_SHIFT, true);
ChartSetDouble(0, CHART_SHIFT_SIZE, ShiftPer);
ChartSetInteger(0, CHART_AUTOSCROLL, true);
//ChartSetInteger(0, CHART_SHOW_DATE_SCALE, true); // これを入れるとなぜか表示範囲が狭くなる
//ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, true); // これを入れるとなぜか表示範囲が狭くなる
ChartSetInteger(0, CHART_FOREGROUND, false);
ChartSetInteger(0, CHART_SHOW_GRID, false);
ChartSetInteger(0, CHART_SHOW_ONE_CLICK, false);
ChartSetInteger(0, CHART_SHOW_OHLC, false);
ChartSetInteger(0, CHART_SHOW_PERIOD_SEP, true);
ChartSetInteger(0, CHART_SHOW_ASK_LINE, true);
ChartSetInteger(0, CHART_SCALE, 3);
ChartSetInteger(0, CHART_MODE, CHART_CANDLES);
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| チャートの中央にシンボルを描画する |
//+------------------------------------------------------------------+
void CenterSymbol()
{
string TEXT1 = StringSubstr(Symbol(), 0, 6);
string TEXT2 = (Period() == 1? "M1": Period() == 5? "M5": Period() == 15? "M15": Period() == 30? "M30":
Period() == 60? "H1": Period() == 240? "H4": Period() == 1440? "D1": Period() == 10080? "W1": "MN1")
+ "/" + DoubleToStr(MarketInfo(Symbol(),MODE_SPREAD) / 10, 1);
int FontSize = 36;
int chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int chartHeight = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
int textWidth = StringLen(TEXT1) * FontSize / 2; // テキストの幅の計算
int textHeight = FontSize; // テキストの高さ
// テキストの中心からの座標を計算
int x = (chartWidth - textWidth) / 2 + textWidth / 2;
int y = (chartHeight - textHeight) / 2 + textHeight / 2;
DrawTextInCenter("Symbol1", TEXT1, x, y - FontSize, FontSize, C'60, 60, 60');
DrawTextInCenter("Symbol2", TEXT2, x, y + FontSize, FontSize, C'60, 60, 60');
}
void DrawTextInCenter(string Symbolname, string label_text, int pos_x, int pos_y, int s, color clr= clrBlack)
{
ObjectCreate(Symbolname, OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, Symbolname, OBJPROP_TEXT, label_text);
ObjectSetInteger(0, Symbolname, OBJPROP_FONTSIZE, s);
ObjectSetString(0, Symbolname, OBJPROP_FONT, "Segoe UI");
ObjectSetInteger(0, Symbolname, OBJPROP_XDISTANCE, pos_x);
ObjectSetInteger(0, Symbolname, OBJPROP_YDISTANCE, pos_y);
ObjectSetInteger(0, Symbolname, OBJPROP_COLOR, clr);
ObjectSetInteger(0, Symbolname, OBJPROP_BACK, true);
ObjectSetInteger(0, Symbolname, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, Symbolname, OBJPROP_ANCHOR, ANCHOR_CENTER);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| EAの状態を表示 |
//+------------------------------------------------------------------+
void OnTimer()
{
EA_test();
if (CT == 0)
{
EA_label ("Updating...", clrYellow);
ChartWarning = 1; // この変数は、チャート表示やチャートコメント表示と連動
ChartSet2();
CT = 0;
}
}
void EA_test()
{
string label1 = "EA is running";
string label2 = "Authentication Failed";
string label3 = "No trade allowed";
string label4 = "Network Errors";
string labelx = label1;
if (Pass == false) labelx = label2;
else if (IsTradeAllowed() == false) labelx = label3;
else if (IsConnected() == false) labelx = label4;
if (Pass == false)
{
EA_label (label2, clrOrangeRed);
ChartWarning = 2;
ChartSet2();
}
else if (IsTradeAllowed() == false)
{
EA_label (label3, clrOrangeRed);
ChartWarning = 3;
ChartSet2();
}
else if (IsConnected() == false)
{
EA_label (label4, clrOrangeRed);
ChartWarning = 4;
ChartSet2();
}
else
{
EA_label (label1, clrLime);
ChartWarning = 0;
ChartSet2();
}
}
void EA_label(string text, color clr)
{
int x = (int)NormalizeDouble(4 * DPIAdjust, 0); // 別途DPI換算コードで調整
int y = (int)NormalizeDouble(18 * DPIAdjust, 0); // 別途DPI換算コードで調整
ObjectCreate(0, "EA_label", OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, "EA_label", OBJPROP_TEXT, text);
ObjectSetInteger(0, "EA_label", OBJPROP_COLOR, clr);
ObjectSetInteger(0, "EA_label", OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, "EA_label", OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, "EA_label", OBJPROP_FONTSIZE, 10);
ObjectSetInteger(0, "EA_label", OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, "EA_label", OBJPROP_HIDDEN, true);
ObjectSetString(0, "EA_label", OBJPROP_FONT, "Segoe UI");
ObjectSetInteger(0, "EA_label", OBJPROP_CORNER, CORNER_RIGHT_UPPER);
ObjectSetInteger(0, "EA_label", OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);
ObjectSetInteger(0, "EA_label", OBJPROP_BACK, false);
}
// 状態によるチャート配色変更
void ChartSet2()
{
color ChartWar1 = ChartWarning >= 2? clrDarkGray : clrWhite;
color ChartWar2 = ChartWarning >= 2? clrDimGray : clrOlive;
color ChartWar3 = ChartWarning >= 2? clrSilver : clrBeige;
if (!IsTesting())
{
ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrBlack);
ChartSetInteger(0, CHART_COLOR_FOREGROUND, ChartWar1);
ChartSetInteger(0, CHART_COLOR_GRID, clrLightSlateGray);
ChartSetInteger(0, CHART_COLOR_CHART_UP, ChartWar2);
ChartSetInteger(0, CHART_COLOR_CHART_DOWN, ChartWar2);
ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrBlack);
ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, ChartWar3);
ChartSetInteger(0, CHART_COLOR_CHART_LINE, ChartWar2);
ChartSetInteger(0, CHART_COLOR_VOLUME, ChartWar2);
ChartSetInteger(0, CHART_COLOR_ASK, clrRed);
ChartSetInteger(0, CHART_COLOR_STOP_LEVEL, clrRed);
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| チャートコメント表示 |
//+------------------------------------------------------------------+
void ChartComment()
{
color clrChartWar = ChartWarning >= 2? clrNONE : clrWhite;
color clrChartWarPP = ChartWarning >= 2? clrNONE : totalpips < 0? clrOrangeRed : clrWhite;
color clrChartWarPF = ChartWarning >= 2? clrNONE : 0 < ProfitFactor && ProfitFactor < 1? clrOrangeRed : clrWhite;
string LotsComment;
if (MM_ON == Fixed) LotsComment = DoubleToStr(Lots,2);
else LotsComment = DoubleToStr(CalculateLots(MM_Risk, StopLoss_pips),2) +
" (" + DoubleToStr(MM_Risk,1) +"%)";
string Comment0 = "Magic : " + (string)MagicNumber;
string Comment1 = "Lots : " + LotsComment;
string Comment2 = "MM : " + (MM_ON == 0 ? "Fixed" : MM_ON == 1 ? "FreeMargin" : MM_ON == 2 ? "Balance" : "AddCredit");
// string Comment3 = "Summertime : " + (Summertime == 0 ? "none" : Summertime == 1 ? "US" : "UK");
string Comment3 = "MaxTP/SL : " + DoubleToStr(TakeProfit_pips, 0) + "/" + DoubleToStr(StopLoss_pips, 0);
string Comment4 = "Swap B/S : " + DoubleToStr(MarketInfo(Symbol(),MODE_SWAPLONG), 2) + "/" +
DoubleToStr(MarketInfo(Symbol(),MODE_SWAPSHORT), 2);
string Comment5 = "Spread Lim/Ave : " + DoubleToStr(MaxSpread_pips,1) + "/" + DoubleToStr(SpreadAve,1);
string Comment6 = "TradeCounts : " + DoubleToStr(TradeCounts, 0);
string Comment7 = "Profit (pips) : " + DoubleToStr(totalpips, 1);
string Comment8 = (plus_profit == 0 || minus_profit == 0? "Profit factor : ---" :
"Profit factor : " + DoubleToStr(ProfitFactor, 2));
string Comment9 = (plus_profit == 0 || minus_profit == 0? "RRR/Win% : ---/---" :
"RRR/Win% : " + DoubleToStr(RRR, 2) + "/" + DoubleToStr(WinPer, 1));
CommentLabel("ComObj0", Comment0, 4, 38, 10, clrYellow);
CommentLabel("ComObj1", Comment1, 4, 58, 10, clrYellow);
CommentLabel("ComObj2", Comment2, 6, 82, 8, clrChartWar);
CommentLabel("ComObj3", Comment3, 6, 100, 8, clrChartWar);
CommentLabel("ComObj4", Comment4, 6, 118, 8, clrChartWar);
CommentLabel("ComObj5", Comment5, 6, 136, 8, clrChartWar);
CommentLabel("ComObj6", Comment6, 6, 154, 8, clrChartWar);
CommentLabel("ComObj7", Comment7, 6, 172, 8, clrChartWarPP);
CommentLabel("ComObj8", Comment8, 6, 190, 8, clrChartWarPF);
CommentLabel("ComObj9", Comment9, 6, 208, 8, clrChartWar);
//CommentLabel("ComObj10", Comment10, 6, 226, 8, clrChartWar);
}
//+------------------------------------------------------------------+
void CommentLabel(string ComName, string ComText, int ComPos_x, int ComPos_y, int ComSize, color ComClr= clrBlack)
{
ComPos_x = (int)NormalizeDouble(ComPos_x * DPIAdjust, 0); // 別途DPI換算コードで調整
ComPos_y = (int)NormalizeDouble(ComPos_y * DPIAdjust, 0); // 別途DPI換算コードで調整
ObjectCreate(ComName, OBJ_LABEL, 0, 0, 0);
ObjectSetString (0, ComName, OBJPROP_TEXT, ComText);
ObjectSetInteger(0, ComName, OBJPROP_XDISTANCE, ComPos_x);
ObjectSetInteger(0, ComName, OBJPROP_YDISTANCE, ComPos_y);
ObjectSetInteger(0, ComName, OBJPROP_FONTSIZE, ComSize);
ObjectSetInteger(0, ComName, OBJPROP_COLOR, ComClr);
ObjectSetString (0, ComName, OBJPROP_FONT, "Segoe UI");
ObjectSetInteger(0, ComName, OBJPROP_BACK, true);
ObjectSetInteger(0, ComName, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, ComName, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
ObjectSetInteger(0, ComName, OBJPROP_ANCHOR, ANCHOR_RIGHT_UPPER);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| チャートにトレード履歴表示・各計算 |
//+------------------------------------------------------------------+
void PosHis()
{
int res;
double pips = 0;
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
res = OrderSelect(i, SELECT_BY_POS);
if (OrderSymbol() != Symbol() || OrderType() > 1 || OrderMagicNumber() != MagicNumber)
continue;
pips += trend((string)OrderTicket(), OrderOpenTime(), OrderOpenPrice(), Time[0], OrderType() == 0 ? Bid : Ask, OrderType());
}
}
//+------------------------------------------------------------------+
void history()
{
int res;
totalpips = 0;
plus_profit = 0;
minus_profit = 0;//, ProfitFactor = 0;
minus_count = 0;
plus_count = 0;
TradeCounts = 0;
// トレード履歴を検索
for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
{
res = OrderSelect(i, SELECT_BY_POS, MODE_HISTORY);
if (OrderSymbol() != Symbol() || OrderType() > 1 || OrderMagicNumber() != MagicNumber)
continue;
// 合計pips計算
totalpips += trend((string)OrderTicket(), OrderOpenTime(), OrderOpenPrice(), OrderCloseTime(), OrderClosePrice(), OrderType());
// プロフィットファクター・RRR・勝率計算
if (OrderProfit() < 0)
{
minus_profit -= OrderProfit();
minus_count += 1;
}
else if (OrderProfit() >= 0)
{
plus_profit += OrderProfit();
plus_count += 1;
}
if (minus_profit != 0 && plus_count != 0 && minus_count != 0)
{
ProfitFactor = plus_profit / minus_profit;
RRR = (plus_profit / plus_count) / (minus_profit / minus_count);
WinPer = (plus_count * 100) / (plus_count + minus_count);
}
TradeCounts = minus_count + plus_count;
}
}
//+------------------------------------------------------------------+
double trend(string obj_name, datetime Time1, double Close1, datetime Time2, double Close2, int type)
{
double pips = (double)DoubleToStr((type == 0 ? Close2 - Close1 : Close1 - Close2) / Point() * 0.1 - tes, 1);
int Shift2 = iBarShift(NULL, 0, Time2);
datetime Timex = iTime(NULL, 0, Shift2 + 1);
// トレード線
ObjectDelete("hislt" + obj_name);
ObjectCreate(0, "hislt" + obj_name, OBJ_TREND, 0, Time1, Close1, Time2, Close2);
ObjectSetInteger(0, "hislt" + obj_name, OBJPROP_COLOR, type == 0 ? clrDodgerBlue : clrOrangeRed);
ObjectSetInteger(0, "hislt" + obj_name, OBJPROP_STYLE, 0);
ObjectSetInteger(0, "hislt" + obj_name, OBJPROP_WIDTH, 2);
ObjectSetInteger(0, "hislt" + obj_name, OBJPROP_SELECTABLE, false); // オブジェクトの選択可否設定
ObjectSetInteger(0, "hislt" + obj_name, OBJPROP_RAY_RIGHT, false); // 右に線を延長
// トレード線内のpips表示
// 文字本体
ObjectDelete("hislx" + obj_name);
ObjectCreate(0, "hislx" + obj_name, OBJ_TEXT, 0, Timex, Close2);
ObjectSetInteger(0, "hislx" + obj_name, OBJPROP_COLOR, pips < 0 ? clrOrangeRed : !IsTesting()? clrLime : clrYellow);//type == 0 ? BuyColor : SellColor);
ObjectSetInteger(0, "hislx" + obj_name, OBJPROP_SELECTABLE, false); // オブジェクトの選択可否設定
ObjectSetInteger(0, "hislx" + obj_name, OBJPROP_FONTSIZE, 12); // フォントサイズ
ObjectSetInteger(0, "hislx" + obj_name, OBJPROP_ANCHOR, ANCHOR_RIGHT); // 描画位置
ObjectSetString(0, "hislx" + obj_name, OBJPROP_TEXT, DoubleToStr(pips, 1)); // 表示するテキスト
ObjectSetString(0, "hislx" + obj_name, OBJPROP_FONT, "Segoe UI Semibold"); // フォント
return(pips);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| スプレッド計測・オートスプレッド |
//+------------------------------------------------------------------+
void MeasureSP()
{
TickCount++;
SpreadSum += MeasureSpread;
SpreadMin = SpreadMin == 0 ? SpreadMin = MeasureSpread : SpreadMin;
if (TickCount > 0 && SpreadSum > 0) SpreadAve = SpreadSum / TickCount;
if (SpreadMax < MeasureSpread) SpreadMax = MeasureSpread;
if (SpreadMin > MeasureSpread) SpreadMin = MeasureSpread;
// エントリー時間帯のスプレッド
yTime = TimeMinute(TimeCurrent());
if (Logic1_Time)
{
TickCount1++;
SpreadSum1 += MeasureSpread;
SpreadMin1 = SpreadMin1 == 0 ? SpreadMin1 = MeasureSpread : SpreadMin1;
if (TickCount1 > 0 && SpreadSum1 > 0) SpreadAve1 = SpreadSum1 / TickCount1;
if (SpreadMax1 < MeasureSpread) SpreadMax1 = MeasureSpread;
if (SpreadMin1 > MeasureSpread) SpreadMin1 = MeasureSpread;
}
// 月足のバー更新時に累積値リセット
if (lastBars != iBars(NULL, PERIOD_MN1))
{
lastBars = iBars(NULL, PERIOD_MN1);
SpreadSum = 0;
TickCount = 0;
SpreadSum1 = 0;
TickCount1 = 0;
}
// オートスプレッド計算
Adjustspread = SpreadAve + Adjustspread_Margin; // 平均にマージン加算
MaxSpread_pips = MathMin(Adjustspread, AllowMaxSpread); // 内部設定の最大値とマージン加算を比較し小さい方を採用
if (SpreadAve1 != 0) // エントリー時間帯制御用
{
Adjustspread = SpreadAve1 + Adjustspread_Margin1; // 平均にマージン加算
MaxSpread_pips = MathMax(MathMin(Adjustspread, AllowMaxSpread), MaxSpread_pips); // 最大値とマージン加算、全体平均を比較
}
}
//+------------------------------------------------------------------+