1827 lines
131 KiB
MQL4
1827 lines
131 KiB
MQL4
//+------------------------------------------------------------------+
|
||
//| MAN-010EB.mq4 |
|
||
//| Copyright 2023, TNK.Co.,Ltd.|
|
||
//| https://note.com/tnk_system |
|
||
//+------------------------------------------------------------------+
|
||
#property copyright "Copyright 2023, TNK/TNK_SYSTEM"
|
||
#property link "https://note.com/tnk_system"
|
||
#property version "4.3" //軽量化
|
||
#property icon "TNKIcon.ico" // アイコン取り込み
|
||
//#define ROSOKU_Check
|
||
//#define MQLDebug_OPCL
|
||
//#define MQLDebug_SLTP
|
||
//#include <MQL4to5.mqh>
|
||
|
||
#property description "[通貨ペア] USDJPY [時間足] M5"
|
||
#property description "[スタイル] アノマリー [ポジション数] 1"
|
||
#property description "[両建て] 無し [トレール] 無し [週末持ち越し] 有り"
|
||
#property description "[最大TP/SL] 130/80 pips(変更不可)"
|
||
#property description "[年末年始] 新規エントリー無し・決済のみ実行(12/23~1/3)"
|
||
#property description "[口座] 日足5本(GMT冬+2/夏+3)専用"
|
||
|
||
#property strict
|
||
#include <stdlib.mqh>
|
||
|
||
//+------------------------------------------------------------------+
|
||
//|ユーザー入力用パラメーター |
|
||
//+------------------------------------------------------------------+
|
||
input int MagicNumber = 5031302; // マジックナンバー(他EAと重複不可)
|
||
|
||
input double Lots = 0.28; // ロット(単利運用時)
|
||
input double MM_Risk = 3.0; // リスク%(複利選択項目の何%か)
|
||
enum MM_Select{
|
||
Fixed, // 0:単利/固定
|
||
FreeMargin, // 1:複利/余剰証拠金
|
||
Balance, // 2:複利/残高
|
||
};
|
||
input MM_Select MM_ON = Fixed; // 複利機能(0:固定/1:余剰証拠金/2:残高)
|
||
double MaxSpread_pips = 3.0; // 許容スプレッド(Pips)
|
||
input double AllowSpread = 10; // 許容スプレッドPips(0:自動)
|
||
enum Summertime_Select{
|
||
None, // 0:none/無し
|
||
US, // 1:US/米国式
|
||
UK, // 2:UK/英国式
|
||
};
|
||
input Summertime_Select Summertime = 1; // サマータイム(0:無し/1:米/2:英)
|
||
input bool VisualHistory = false; // 取引履歴データ等をチャートに表示
|
||
|
||
//+------------------------------------------------------------------+
|
||
//|内部設定・グローバル関数 |
|
||
//+------------------------------------------------------------------+
|
||
//内部設定
|
||
int Maxposition = 1; // 最大ポジション
|
||
int Slippage = 50; // 許容スリッページ(Point)
|
||
//bool WeekendClose = true; // 週末クローズ
|
||
bool YearendClose = true; // 12/23~1/3クローズ
|
||
string _Comment = "MAN-010_USDJPY_M5"; // 通知用コメント
|
||
int TakeProfit_pips = 100; // 【共通】利確指値(Pips)
|
||
int StopLoss_pips = 100; // 【共通】損切逆指値(Pips)
|
||
int GMT = 2; // GMT(冬時間)
|
||
|
||
//バーカウント・桁合わせ用
|
||
double xpoint;
|
||
int xxBars = 0, yyBars = 0;
|
||
int xxTime, xxxTime, yTime;
|
||
|
||
//エントリー時間(サーバー時間)
|
||
bool GMT_Kadou_OK_L1 = false; // エントリー時間
|
||
bool GMT_Kadou_OK_L2 = false; // エントリー時間
|
||
bool GMT_Kadou_OK_L3 = false; // エントリー時間
|
||
bool GMT_Kadou_OK_L4 = false; // エントリー時間
|
||
|
||
//ポジション決済(サーバー時間)
|
||
bool PositionClose_L1 = false; // ポジション決済(買い)
|
||
bool PositionClose_L2 = false; // ポジション決済(買い)
|
||
bool PositionClose_L3 = false; // ポジション決済(買い)
|
||
bool PositionClose_L4 = false; // ポジション決済(売り)
|
||
|
||
//バックテスト用モード切替
|
||
bool Development = false; // 開発モードON/OFF(OnTester欄にRF表示、インジケータ表示)
|
||
|
||
//+------------------------------------------------------------------+
|
||
//|便利機能系 |
|
||
//+------------------------------------------------------------------+
|
||
//チャートセット固定用
|
||
string SYMBOL1 = "USDJPY"; // シンボル名(頭6文字)
|
||
ENUM_TIMEFRAMES Chart_TimeFrame = PERIOD_M5; // タイムフレーム
|
||
|
||
// EAの状態変化用
|
||
bool ChartWarning;
|
||
|
||
// マジックナンバー重複セットアラート
|
||
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 = 2.0; // 自動スプレッド調整幅
|
||
double Adjustspread_Margin1 = 1.0; // 自動スプレッド調整幅(1:00)
|
||
|
||
// 証拠金チェック
|
||
int aCmd = 0;
|
||
|
||
// DPI換算
|
||
double DPIAdjust;
|
||
|
||
// バックテスト時間計測
|
||
uint StartingTimestamp;
|
||
|
||
// チャートにトレード履歴表示・データ表示用
|
||
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;
|
||
|
||
// GMT0ブローカー禁止・サマータイム自動調整
|
||
string BrokerName0 = "Ava Trad"; // Ava "Ava Trade Ltd.";
|
||
string BrokerName1 = "Exness T"; // Exness "Exness Technologies Ltd";
|
||
string BrokerName2 = "HF Marke"; // HFM "HF Markets (SV) Ltd.";"HF Markets(SV)Ltd.";
|
||
string BrokerName3 = "Tradexfi"; // XM "Tradexfin Limited";
|
||
string BrokerName4 = "FinTrade"; // XM "FinTrade Limited";
|
||
string BrokerName5 = "NOTESCO "; // IronFX "NOTESCO Ltd";
|
||
|
||
//+------------------------------------------------------------------+
|
||
//|ロジック用パラメータ |
|
||
//+------------------------------------------------------------------+
|
||
string Common_Parameters = "■■■■■共通パラメータ■■■■■"; // 共通パラメータ
|
||
//エントリーフィルター
|
||
double Gap_Pips = 6.0; // 【共通】1本前ローソク足終値と現在価格の差pips
|
||
int MaxTakeprofit_pips = 130;
|
||
int MaxStopLoss_pips = 80;
|
||
|
||
//+------------------------------------------------------------------+
|
||
string Logic1_Parameters = "■■■■■ロジック1パラメータ■■■■■"; // ロジック1パラメータ
|
||
bool Logic1 = false; // 【L1|稼働スイッチ】
|
||
//エントリーフィルター
|
||
int StartDay_L1 = 1; // 【L1|エントリー】開始日
|
||
int EndDay_L1 = 31; // 【L1|エントリー】終了日
|
||
int TimeOpen_L1 = 1; // 【L1|エントリー】時刻
|
||
int MinuteOpen_L1 = 0; // 【L1|エントリー】分
|
||
int MinuteOpen_L1_2 = 5; // 【L1|エントリー】分2
|
||
int RSI_FilterLine_L1 = 43; // 【L1|フィルター】RSIライン
|
||
//input int CandleCheckCount_L1_1 = 48; // 【L3|フィルター】過去ボラティリティチェックHLローソク足本数
|
||
//input int HL_margin_L1_1 = 70; // 【L3|フィルター】過去ボラティリティチェックHL幅(pips)
|
||
//input int CandleCheckCount_L1_2 = 240; // 【L3|フィルター】過去ボラティリティチェックHCローソク足本数
|
||
//input int HC_margin_L1_2 = 70; // 【L3|フィルター】過去ボラティリティチェックHC幅(pips)
|
||
//決済フィルター
|
||
int TimeClose_L1 = 2; // 【L1|決済】時刻
|
||
int MinuteClose_L1 = 55; // 【L1|決済】分
|
||
int TimeClose_L1_2 = 2; // 【L1|決済】時刻2
|
||
int MinuteClose_L1_2 = 5; // 【L1|決済】分2
|
||
int TakeProfit_pips_L1 = 100; // 【L1|決済】TakeProfit(Pips)
|
||
int StopLoss_pips_L1 = 140; // 【L1|決済】StopLoss(Pips)
|
||
|
||
//+------------------------------------------------------------------+
|
||
string Logic2_Parameters = "■■■■■ロジック2パラメータ■■■■■"; // ロジック2パラメータ
|
||
bool Logic2 = true; // 【L2|稼働スイッチ】
|
||
//エントリーフィルター
|
||
//input int CandleCheckCount_L2_1 = 288; // 【L2|フィルター】過去ボラティリティチェックHLローソク足本数
|
||
//input int HL_margin_L2_1 = 200; // 【L2|フィルター】過去ボラティリティチェックHL幅(pips)
|
||
//input int CandleCheckCount_L2_2 = 192; // 【L2|フィルター】過去ボラティリティチェックLCローソク足本数
|
||
//input int LC_margin_L2_2 = 50; // 【L2|フィルター】過去ボラティリティチェックLC幅(pips)
|
||
int StartDay_L2 = 23; // 【L2|エントリー】開始日
|
||
int EndDay_L2 = 30; // 【L2|エントリー】終了日
|
||
int StartDay_L2_0 = 23; // 【L2|エントリー】開始日0
|
||
int EndDay_L2_0 = 30; // 【L2|エントリー】終了日0
|
||
int StartDay_L2_1 = 23; // 【L2|エントリー】開始日1
|
||
int EndDay_L2_1 = 30; // 【L2|エントリー】終了日1
|
||
int TimeOpen_L2 = 2; // 【L2|エントリー】時刻
|
||
int MinuteOpen_L2 = 5; // 【L2|エントリー】分
|
||
int MinuteOpen_L2_2 = 5; // 【L1|エントリー】分2
|
||
//input int RSI_FilterLine_L2 = 10; // 【L2|フィルター】RSIライン
|
||
//決済フィルター
|
||
int TimeClose_L2 = 8; // 【L2|決済】時刻
|
||
int MinuteClose_L2 = 45; // 【L2|決済】分
|
||
int TakeProfit_pips_L2 = 130; // 【L2|決済】TakeProfit(Pips)
|
||
int StopLoss_pips_L2 = 80; // 【L2|決済】StopLoss(Pips)
|
||
|
||
//+------------------------------------------------------------------+
|
||
string Logic3_Parameters = "■■■■■ロジック3パラメータ■■■■■"; // ロジック3パラメータ
|
||
bool Logic3 = true; // 【L3|稼働スイッチ】
|
||
//エントリーフィルター
|
||
int StartDay_L3 = 25; // 【L3|エントリー】開始日
|
||
int EndDay_L3 = 30; // 【L3|エントリー】終了日
|
||
int TimeOpen_L3 = 9; // 【L3|エントリー】時刻
|
||
int MinuteOpen_L3 = 10; // 【L3|エントリー】分
|
||
int MinuteOpen_L3_2 = 20; // 【L3|エントリー】分2
|
||
//input int RSI_FilterLine_L3 = 41; // 【L3|フィルター】RSIライン
|
||
//input int CandleCheckCount_L3_1 = 48; // 【L3|フィルター】過去ボラティリティチェックHLローソク足本数
|
||
//input int HL_margin_L3_1 = 70; // 【L3|フィルター】過去ボラティリティチェックHL幅(pips)
|
||
int CandleCheckCount_L3_2 = 240; // 【L3|フィルター】過去ボラティリティチェックHCローソク足本数
|
||
int HC_margin_L3_2 = 50; // 【L3|フィルター】過去ボラティリティチェックHC幅(pips)
|
||
//input int CandleCheckCount_L3_3 = 96; // 【L3|フィルター】過去ボラティリティチェックLCローソク足本数
|
||
//input int LC_margin_L3_3 = 70; // 【L3|フィルター】過去ボラティリティチェックLC幅(pips)
|
||
//決済フィルター
|
||
int TimeClose_L3 = 19; // 【L3|決済】時刻
|
||
int MinuteClose_L3 = 40; // 【L3|決済】分
|
||
int TakeProfit_pips_L3 = 60; // 【L3|決済】TakeProfit(Pips)
|
||
int StopLoss_pips_L3 = 80; // 【L3|決済】StopLoss(Pips)
|
||
|
||
//+------------------------------------------------------------------+
|
||
string Logic4_Parameters = "■■■■■ロジック4パラメータ■■■■■"; // ロジック4パラメータ
|
||
bool Logic4 = true; // 【L4|稼働スイッチ】
|
||
//エントリーフィルター
|
||
//input int StartDay_L4 = 4; // 【L4|エントリー】開始日
|
||
//input int EndDay_L4 = 27; // 【L4|エントリー】終了日
|
||
int TimeOpen_L4 = 21; // 【L4|エントリー】時刻
|
||
int MinuteOpen_L4 = 0; // 【L4|エントリー】分
|
||
int MinuteOpen_L4_2 = 55; // 【L4|エントリー】分2
|
||
int RSI_FilterLine_L4 = 62; // 【L4|フィルター】RSIライン
|
||
int CandleCheckCount_L4 = 96; // 【L4|フィルター】過去ボラティリティチェックHLローソク足本数
|
||
int HL_margin_L4 = 120; // 【L4|フィルター】過去ボラティリティチェックHL幅(pips)
|
||
//input ENUM_TIMEFRAMES ADX_TF_L4 = PERIOD_M30; // 【L4|フィルター】トレンド発生判定ADXタイムフレーム
|
||
//input int ADX_value_L4 = 45; // 【L4|フィルター】トレンド発生判定ADX基準ライン
|
||
//決済フィルター
|
||
//input int TimeClose_L4 = 15; // 【L4|決済】時刻
|
||
//input int MinuteClose_L4 = 15; // 【L4|決済】分
|
||
int TakeProfit_pips_L4 = 80; // 【L4|決済】TakeProfit(Pips)
|
||
int StopLoss_pips_L4 = 80; // 【L4|決済】StopLoss(Pips)
|
||
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| tester function |
|
||
//+------------------------------------------------------------------+
|
||
double OnTester()
|
||
{
|
||
// OnTesterに表示【リカバリーファクター|勝率】
|
||
if (Development)
|
||
{
|
||
// リカバリーファクター
|
||
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()
|
||
{
|
||
//+------------------------------------------------------------------+
|
||
// バックテスト時間計測
|
||
StartingTimestamp = GetTickCount();
|
||
//+------------------------------------------------------------------+
|
||
// GMT0ブローカー稼働禁止
|
||
if (StringSubstr(AccountCompany(), 0, 8) == BrokerName0
|
||
|| StringSubstr(AccountCompany(), 0, 8) == BrokerName1
|
||
)
|
||
{
|
||
Alert(
|
||
WindowExpertName() + " cannot run on brokers at GMT0"
|
||
+ "\n"
|
||
+ "GMT0のブローカーは稼働できません"
|
||
);
|
||
return(INIT_FAILED);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
// サマータイム自動調整
|
||
/*if (StringSubstr(AccountCompany(), 0, 8) == BrokerName1)
|
||
{
|
||
Summertime = 0;
|
||
}
|
||
else if (StringSubstr(AccountCompany(), 0, 8) == BrokerName2
|
||
|| StringSubstr(AccountCompany(), 0, 8) == BrokerName3
|
||
|| StringSubstr(AccountCompany(), 0, 8) == BrokerName4
|
||
|| StringSubstr(AccountCompany(), 0, 8) == BrokerName5
|
||
)
|
||
{
|
||
Summertime = 2;
|
||
}
|
||
else
|
||
{
|
||
Summertime = 1;
|
||
}*/
|
||
//+------------------------------------------------------------------+
|
||
// 小数点以下の桁数に応じてPipsの値を調整する
|
||
xpoint = Point();
|
||
/*if (StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD") // ゴールド用
|
||
{
|
||
if (Digits() == 2)
|
||
{
|
||
xpoint = xpoint * 10;
|
||
}
|
||
else if (Digits() == 3)
|
||
{
|
||
xpoint = xpoint * 100;
|
||
}
|
||
}
|
||
else if (!(StringSubstr(Symbol(), 0, 6) == "XAUUSD" || StringSubstr(Symbol(), 0, 4) == "GOLD")) // ゴールド以外用
|
||
{*/
|
||
if (Digits() == 3 || Digits() == 5)
|
||
{
|
||
xpoint = xpoint * 10;
|
||
}
|
||
//}
|
||
//+-----------------------------------------------------------------+
|
||
// 最大SL算出(コメント・複利の計算で使用)
|
||
MaxStopLoss_pips = MathMax(Logic2? StopLoss_pips_L2 : 0,
|
||
MathMax(Logic3? StopLoss_pips_L3 : 0, Logic4? StopLoss_pips_L4 : 0));
|
||
//+------------------------------------------------------------------+
|
||
// 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(); // チャートコメント
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
// トレード履歴をチャートに表示(ライン・pips)
|
||
if (VisualHistory)
|
||
{
|
||
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(
|
||
WindowExpertName() + " may have duplicate magic numbers. If all is well, press OK to continue with the setup"
|
||
+ "\n"
|
||
+ "マジックナンバー重複の可能性があります。問題が無ければ、OKを押して設定を継続してください。"
|
||
);
|
||
}
|
||
|
||
const datetime mutex_time = GlobalVariableSet(kEA_NAME, 1.0);
|
||
if (mutex_time == 0)
|
||
{
|
||
const int errcode = GetLastError();
|
||
Print("GlobalVariableSet: ERRCODE[", errcode, "]:", ErrorDescription(errcode));
|
||
}
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
// バックテストで稼働
|
||
/*if (IsTesting() == false)
|
||
{
|
||
Alert("Not allowed account!" +"\n"+ "バックテスト専用です");
|
||
return(INIT_FAILED); // 初期化が失敗した事を返し、EAを終了させる
|
||
}*/
|
||
//+------------------------------------------------------------------+
|
||
|
||
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));
|
||
}
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
// バックテスト時間計算・出力
|
||
if (IsTesting())
|
||
{
|
||
uint EndingTimestamp = GetTickCount(); //始動時間
|
||
uint BT_Time = EndingTimestamp - StartingTimestamp;
|
||
uint msec_unit = BT_Time % 1000;
|
||
datetime temp_date = BT_Time / 1000;
|
||
|
||
Print( "バックテスト時間= ",
|
||
TimeHour(temp_date), "hour ",
|
||
TimeMinute(temp_date), "min ",
|
||
TimeSeconds(temp_date), ".", msec_unit, "sec ",
|
||
" 元データ= ", BT_Time );
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| Expert tick function |
|
||
//+------------------------------------------------------------------+
|
||
void OnTick()
|
||
{
|
||
//+------------------------------------------------------------------+
|
||
// 注文制御
|
||
if (Volume[0] <= 20)
|
||
{
|
||
GetSummertimeShift(); // サマータイム調整・時間制御
|
||
PositionClose(); // クローズ
|
||
PositionOpen(); // オープン
|
||
}
|
||
if (Volume[0] == 21) SetTPSL(); // TP, SLの再設定
|
||
//+------------------------------------------------------------------+
|
||
// チャート自動変更・シンボル・チャートコメント・状態表示
|
||
if (!IsTesting())
|
||
{
|
||
CenterSymbol(); // センターにシンボル情報
|
||
ChartComment(); // チャートコメント
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
//スプレッド値取得
|
||
if (!IsTesting() && AllowSpread == 0)
|
||
{
|
||
MeasureSpread = MarketInfo(Symbol(),MODE_SPREAD) / 10;
|
||
MeasureSP(); // スプレッド計測
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
// チャートにトレード線とpips表示
|
||
if (VisualHistory) TradeLinePips();
|
||
//+------------------------------------------------------------------+
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 補正関数 |
|
||
//+------------------------------------------------------------------+
|
||
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基準でどれだけずれているかを算出する(ココマデ)--------------------
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 時間制御 |
|
||
//+------------------------------------------------------------------+
|
||
//---- トレード許可時間の判定 ----
|
||
xxTime = TimeHour(TimeCurrent()) - (GMT - 2); // サーバー時間(サマータイム計算なし)
|
||
xxxTime = TimeHour(TimeCurrent()) - (GMT - 2 + summertime_shift); // サーバー時間(サマータイム計算あり)
|
||
yTime = TimeMinute(TimeCurrent()); // サーバーの分
|
||
gmtadjusted = TimeCurrent() - 60 * 60 * xGMT;
|
||
|
||
// サーバー時間
|
||
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;
|
||
}
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ロジック別時間制御 |
|
||
//+------------------------------------------------------------------+
|
||
// ロジック1
|
||
if (Logic1)
|
||
{
|
||
// ポジションクローズ時間(サーバー時間)
|
||
if (
|
||
(xxxTime == TimeClose_L1 && yTime == MinuteClose_L1
|
||
|
||
&& !(Day() >= StartDay_L2 && Day() <= EndDay_L2))
|
||
||
|
||
(xxTime == TimeClose_L1_2 && yTime == MinuteClose_L1_2
|
||
&& (Day() >= StartDay_L2 && Day() <= EndDay_L2))
|
||
|
||
)
|
||
{
|
||
PositionClose_L1 = true;
|
||
}
|
||
else
|
||
{
|
||
PositionClose_L1 = false;
|
||
}
|
||
// エントリー時間(サーバー時間)
|
||
if (xxTime == TimeOpen_L1 && yTime >= MinuteOpen_L1 && yTime <= MinuteOpen_L1_2
|
||
&& (Day() >= StartDay_L1 && Day() <= EndDay_L1)
|
||
//&& (TimeDayOfWeek(TimeCurrent()) == 1
|
||
//|| TimeDayOfWeek(TimeCurrent()) == 2)
|
||
&& !(TimeMonth(TimeCurrent()) == 1)
|
||
//&& !(TimeMonth(TimeCurrent()) == 12)
|
||
)
|
||
{
|
||
TakeProfit_pips = TakeProfit_pips_L1;
|
||
StopLoss_pips = StopLoss_pips_L1;
|
||
GMT_Kadou_OK_L1 = true;
|
||
}
|
||
else
|
||
{
|
||
GMT_Kadou_OK_L1 = false;
|
||
}
|
||
}
|
||
|
||
// ロジック2
|
||
if (Logic2)
|
||
{
|
||
// ポジションクローズ時間(サーバー時間)
|
||
if (xxTime == TimeClose_L2 && yTime == MinuteClose_L2)
|
||
{
|
||
PositionClose_L2 = true;
|
||
}
|
||
else
|
||
{
|
||
PositionClose_L2 = false;
|
||
}
|
||
// エントリー時間(サーバー時間)
|
||
if (xxTime == TimeOpen_L2 && yTime == MinuteOpen_L2 && yTime <= MinuteOpen_L2_2
|
||
//&& (Day() >= StartDay_L2 && Day() <= EndDay_L2)
|
||
&& ((summertime_shift == 0 && Day() >= StartDay_L2_0 && Day() <= EndDay_L2_0)
|
||
|| (summertime_shift == 1 && Day() >= StartDay_L2_1 && Day() <= EndDay_L2_1))
|
||
//&& !(TimeMonth(TimeCurrent()) == 1)
|
||
//&& !(TimeDayOfWeek(TimeCurrent()) == 1)
|
||
//|| TimeDayOfWeek(TimeCurrent()) == 4
|
||
//)
|
||
)
|
||
{
|
||
TakeProfit_pips = TakeProfit_pips_L2;
|
||
StopLoss_pips = StopLoss_pips_L2;
|
||
GMT_Kadou_OK_L2 = true;
|
||
}
|
||
else
|
||
{
|
||
GMT_Kadou_OK_L2 = false;
|
||
}
|
||
}
|
||
|
||
// ロジック3
|
||
if (Logic3)
|
||
{
|
||
// ポジションクローズ時間(サーバー時間)
|
||
if (xxTime == TimeClose_L3 && yTime == MinuteClose_L3)
|
||
{
|
||
PositionClose_L3 = true;
|
||
}
|
||
else
|
||
{
|
||
PositionClose_L3 = false;
|
||
}
|
||
// エントリー時間(サーバー時間)
|
||
if (xxTime == TimeOpen_L3 && yTime >= MinuteOpen_L3 && yTime <= MinuteOpen_L3_2
|
||
&& (Day() >= StartDay_L3 && Day() <= EndDay_L3)
|
||
//&& !(TimeMonth(TimeCurrent()) == 1)
|
||
//&& !(TimeMonth(TimeCurrent()) == 8)
|
||
&& !(TimeDayOfWeek(TimeCurrent()) == 1)
|
||
)
|
||
{
|
||
TakeProfit_pips = TakeProfit_pips_L3;
|
||
StopLoss_pips = StopLoss_pips_L3;
|
||
GMT_Kadou_OK_L3 = true;
|
||
}
|
||
else
|
||
{
|
||
GMT_Kadou_OK_L3 = false;
|
||
}
|
||
}
|
||
|
||
// ロジック4
|
||
if (Logic4)
|
||
{
|
||
// ポジションクローズ時間(サーバー時間)
|
||
if (
|
||
(xxxTime == TimeClose_L1 && yTime == MinuteClose_L1
|
||
&& !(Day() >= StartDay_L2 && Day() <= EndDay_L2))
|
||
||
|
||
(xxTime == TimeClose_L1_2 && yTime == MinuteClose_L1_2
|
||
&& (Day() >= StartDay_L2 && Day() <= EndDay_L2))
|
||
)
|
||
{
|
||
PositionClose_L4 = true;
|
||
}
|
||
else
|
||
{
|
||
PositionClose_L4 = false;
|
||
}
|
||
// エントリー時間(サーバー時間)
|
||
if (xxxTime == TimeOpen_L4 && yTime >= MinuteOpen_L4 && yTime <= MinuteOpen_L4_2
|
||
//&& (Day() >= StartDay_L4 && Day() <= EndDay_L4)
|
||
//&& (TimeDayOfWeek(TimeCurrent()) == 5)
|
||
)
|
||
{
|
||
TakeProfit_pips = TakeProfit_pips_L4;
|
||
StopLoss_pips = StopLoss_pips_L4;
|
||
GMT_Kadou_OK_L4 = true;
|
||
}
|
||
else
|
||
{
|
||
GMT_Kadou_OK_L4 = false;
|
||
}
|
||
}
|
||
// ここまで、エグジットとトレーリングは、取引時間に関係なく実施する
|
||
//---- トレード許可時間の判定(ココマデ) ----
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ポジションのクローズ |
|
||
//+------------------------------------------------------------------+
|
||
void PositionClose()
|
||
{
|
||
int i;
|
||
double profit;
|
||
bool res;
|
||
|
||
// 所有しているポジションをクローズする
|
||
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, PERIOD_M5, OrderOpenTime());
|
||
if (OrderOpenCandleCount == 0) continue;
|
||
|
||
if (OrderType() == OP_BUY)
|
||
{
|
||
profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する
|
||
|
||
if (Exit2(false) == 2)
|
||
{
|
||
res = OrderClose(OrderTicket(), OrderLots(), Bid, NULL, Green);
|
||
}
|
||
}
|
||
|
||
if (OrderType() == OP_SELL)
|
||
{
|
||
profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の、含み損益を計算する
|
||
|
||
if (Exit1(true) == 1)
|
||
{
|
||
res = OrderClose(OrderTicket(), OrderLots(), Ask, NULL, Green);
|
||
}
|
||
}
|
||
} // 所有しているポジションをクローズする(ココマデ)
|
||
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ポジションのオープン |
|
||
//+------------------------------------------------------------------+
|
||
void PositionOpen()
|
||
{
|
||
int i;
|
||
int ticket;
|
||
int CountBuy = 0,CountSell = 0;
|
||
bool res;
|
||
|
||
// ポジションの数をカウントする
|
||
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();
|
||
|
||
} // ポジションの数をカウントする(ココマデ)
|
||
|
||
|
||
// 証拠金不足・トレード許可チェック
|
||
if (EquityCheck())
|
||
{
|
||
// エントリー条件を確認し、成立していればエントリーを行う
|
||
if (Entry(true) == 1 // 買いエントリー
|
||
&& CountSell == 0
|
||
&& CountBuy < Maxposition
|
||
&& xxBars != Bars
|
||
)
|
||
{
|
||
ticket = OrderSend(Symbol(),
|
||
OP_BUY,
|
||
CalculateLots(MM_Risk, MaxStopLoss_pips),//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, MaxStopLoss_pips),//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);
|
||
|
||
}
|
||
}
|
||
}
|
||
if (ticket > 0) xxBars = Bars;
|
||
}
|
||
|
||
if (Entry(false) == 2 // 売りエントリー
|
||
&& CountBuy == 0
|
||
&& CountSell < Maxposition
|
||
&& yyBars != Bars
|
||
)
|
||
{
|
||
ticket = OrderSend(Symbol(),
|
||
OP_SELL,
|
||
CalculateLots(MM_Risk, MaxStopLoss_pips),//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, MaxStopLoss_pips),//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);
|
||
}
|
||
}
|
||
}
|
||
if (ticket > 0) yyBars = Bars;
|
||
}
|
||
}
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
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()) // トレード許可判定
|
||
{
|
||
return(true);
|
||
}
|
||
else return(false);
|
||
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| TakeProfit, StopLoss |
|
||
//+------------------------------------------------------------------+
|
||
void SetTPSL()
|
||
{
|
||
int i;
|
||
double profit;
|
||
bool res;
|
||
|
||
// ポジションに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 = 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 + 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 + 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
|
||
// 時間制御によるエントリー可能時間でエントリー判定
|
||
if (isbuy
|
||
&& (GMT_Kadou_OK_L1 || GMT_Kadou_OK_L3 || GMT_Kadou_OK_L4)
|
||
)
|
||
{
|
||
return(1);
|
||
} // 買い
|
||
|
||
if (!isbuy
|
||
&& (GMT_Kadou_OK_L2)// || GMT_Kadou_OK_L4 == true)
|
||
)
|
||
{
|
||
return(2);
|
||
} // 売り
|
||
|
||
return(0); // エントリー出来ない
|
||
|
||
//エントリールール1ココマデ
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター1 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter1(bool isbuy)
|
||
{
|
||
//エントリーフィルター1
|
||
//スプレッドフィルター
|
||
double spread = MarketInfo(NULL, MODE_SPREAD);
|
||
|
||
if (Digits == 3 || Digits == 5)
|
||
spread /= 10.0;
|
||
if (spread > MaxSpread_pips)
|
||
return(0); // スプレッドが指定pips以上でトレード不許可
|
||
|
||
//ローソク足マージンフィルター
|
||
double Close0 = iClose(NULL, PERIOD_M5, 0);
|
||
double Close1 = iClose(NULL, PERIOD_M5, 1);
|
||
|
||
if (isbuy && Close0 - Close1 >= Gap_Pips * xpoint) return(0); // (現在価格-1本足終値)が、指定pips以上だったら買い禁止
|
||
if (!isbuy && Close1 - Close0 >= Gap_Pips * xpoint) return(0); // (1本足終値-現在価格)が、指定pips以上だったら売り禁止
|
||
|
||
//年末年始フィルター
|
||
int NGMonth = Month();
|
||
int NGDay = Day();
|
||
if (YearendClose
|
||
&& ((NGMonth == 12 && NGDay >= 23) || (NGMonth == 1 && NGDay <= 3))
|
||
)
|
||
{
|
||
return(0);
|
||
} // エントリー出来ない
|
||
|
||
//エントリーフィルター1ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター2 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter2(bool isbuy)
|
||
{
|
||
//エントリーフィルター2
|
||
// 1時買いロング毎日(ロジック1)
|
||
if (GMT_Kadou_OK_L1)
|
||
{
|
||
// RSIが指定値以上にいる間は「買い」
|
||
double RSI1 = iRSI(NULL, PERIOD_M5, 14, PRICE_CLOSE, 1);
|
||
|
||
if (RSI1 <= RSI_FilterLine_L1)
|
||
{
|
||
return(1);
|
||
} // 買い
|
||
|
||
else
|
||
{
|
||
return(0);
|
||
} // エントリー不可
|
||
}
|
||
if (GMT_Kadou_OK_L4)
|
||
{
|
||
// RSIが指定値以上にいる間は「買い」
|
||
double RSI1_4 = iRSI(NULL, PERIOD_M5, 14, PRICE_CLOSE, 1);
|
||
|
||
if (RSI1_4 <= RSI_FilterLine_L4)
|
||
{
|
||
return(1);
|
||
} // 買い
|
||
|
||
else
|
||
{
|
||
return(0);
|
||
} // エントリー不可
|
||
}
|
||
|
||
//エントリーフィルター2ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター3 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter3(bool isbuy)
|
||
{
|
||
//エントリーフィルター3
|
||
// ゴトウビフィルター
|
||
|
||
if (GMT_Kadou_OK_L4)
|
||
{
|
||
if (Day() == 4 || Day() == 9 || Day() == 14 || Day() == 19 || Day() == 29
|
||
||
|
||
(TimeDayOfWeek(TimeCurrent()) == 5 &&
|
||
( //Day() == 2 || Day() == 3
|
||
Day() == 7 || Day() == 8
|
||
//|| Day() == 12 || Day() == 13
|
||
|| Day() == 17 || Day() == 18
|
||
|| Day() == 22 || Day() == 23
|
||
//|| Day() == 27 || Day() == 28
|
||
)
|
||
)
|
||
)
|
||
{
|
||
return(3);
|
||
}
|
||
|
||
else
|
||
{
|
||
return(0);
|
||
}
|
||
}
|
||
|
||
//エントリーフィルター3ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター4 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter4(bool isbuy)
|
||
{
|
||
//エントリーフィルター4
|
||
// ボラティリティフィルター
|
||
|
||
if(GMT_Kadou_OK_L3)
|
||
{
|
||
//int HighestIndex1 = iHighest(NULL, PERIOD_M5, MODE_HIGH, CandleCheckCount_L3_1, 1);
|
||
//int LowestIndex1 = iLowest(NULL, PERIOD_M5, MODE_LOW , CandleCheckCount_L3_1, 1);
|
||
//double MostHigh1 = iHigh(NULL, PERIOD_M5, HighestIndex1);
|
||
//double MostLow1 = iLow(NULL, PERIOD_M5, LowestIndex1);
|
||
|
||
int HighestIndex2 = iHighest(NULL, PERIOD_M5, MODE_HIGH, CandleCheckCount_L3_2, 1);
|
||
double MostHigh2 = iHigh(NULL, PERIOD_M5, HighestIndex2);
|
||
|
||
if (//MostHigh1 - MostLow1 > HL_margin_L3_1 * xpoint // 過去◯本の高値安値間に指定pips以上値動きがあったらエントリー禁止
|
||
MostHigh2 - Close[1] > HC_margin_L3_2 * xpoint // 過去◯本の高値と1本前終値が、指定pips以上値動きがあればエントリー不可
|
||
)
|
||
{
|
||
return(0);
|
||
} // エントリー不可
|
||
}
|
||
|
||
if(GMT_Kadou_OK_L4)
|
||
{
|
||
int HighestIndex = iHighest(NULL, PERIOD_M5, MODE_HIGH, CandleCheckCount_L4, 1);
|
||
int LowestIndex = iLowest(NULL, PERIOD_M5, MODE_LOW, CandleCheckCount_L4, 1);
|
||
double MostHigh = iHigh(NULL, PERIOD_M5, HighestIndex);
|
||
double MostLow = iLow(NULL, PERIOD_M5, LowestIndex);
|
||
|
||
if (MostHigh - MostLow > HL_margin_L4 * xpoint) // 過去〇本に〇〇pips以上値動きがあったらエントリー禁止
|
||
{
|
||
return(0);
|
||
} // エントリー不可
|
||
}
|
||
|
||
//エントリーフィルター4ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター5 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter5(bool isbuy)
|
||
{
|
||
//エントリーフィルター5
|
||
|
||
|
||
//エントリーフィルター5ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 決済ルール1 |
|
||
//+------------------------------------------------------------------+
|
||
int Exit_Rule1(bool isbuy)
|
||
{
|
||
// 決済ルール1
|
||
// 時間制御による決済判定
|
||
|
||
if (!isbuy
|
||
&& (PositionClose_L1 || PositionClose_L3 || PositionClose_L4)
|
||
)
|
||
{
|
||
return(2);
|
||
} // 買いを決済
|
||
|
||
if (isbuy
|
||
&& (PositionClose_L2)// || GMT_Kadou_OK_L4 == true)
|
||
)
|
||
{
|
||
return(1);
|
||
} // 売りを決済
|
||
|
||
// 決済ルール1ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 決済ルール2 |
|
||
//+------------------------------------------------------------------+
|
||
int Exit_Rule2(bool isbuy)
|
||
{
|
||
// 決済ルール2
|
||
|
||
// 決済ルール2ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 決済ルール3 |
|
||
//+------------------------------------------------------------------+
|
||
int Exit_Rule3(bool isbuy)
|
||
{
|
||
// 決済ルール3
|
||
|
||
// 決済ルール3ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 決済ルール4 |
|
||
//+------------------------------------------------------------------+
|
||
int Exit_Rule4(bool isbuy)
|
||
{
|
||
// 決済ルール4
|
||
|
||
// 決済ルール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 ChartSet2()
|
||
{
|
||
color ChartWar1 = ChartWarning? clrDarkGray : clrWhite;
|
||
color ChartWar2 = ChartWarning? clrDimGray : clrOlive;
|
||
color ChartWar3 = ChartWarning? 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 CenterSymbol()
|
||
{
|
||
string TEXT1 = StringSubstr(Symbol(), 0, 6);
|
||
string TEXT2 = (Period() == 1? "M1": Period() == PERIOD_M5? "M5": Period() == PERIOD_M15? "M15": Period() == PERIOD_M30? "M30":
|
||
Period() == PERIOD_H1? "H1": Period() == PERIOD_H4? "H4": Period() == PERIOD_D1? "D1": Period() == PERIOD_W1? "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);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
//+------------------------------------------------------------------+
|
||
//| チャートコメント表示 |
|
||
//+------------------------------------------------------------------+
|
||
void ChartComment()
|
||
{
|
||
if (!IsTradeAllowed() || !IsConnected())
|
||
{
|
||
ChartWarning = true;
|
||
ChartSet2();
|
||
}
|
||
else
|
||
{
|
||
ChartWarning = false;
|
||
ChartSet2();
|
||
}
|
||
|
||
color clrChartWar = ChartWarning? clrNONE : clrWhite;
|
||
|
||
string LotsComment;
|
||
if (MM_ON == Fixed) LotsComment = DoubleToStr(Lots,2);
|
||
else LotsComment = DoubleToStr(CalculateLots(MM_Risk, MaxStopLoss_pips),2) +
|
||
" (" + DoubleToStr(MM_Risk,1) +"%)";
|
||
|
||
string Comment0 = (string)MagicNumber + " [Magic]";
|
||
string Comment1 = LotsComment + " [Lots]";
|
||
string Comment2 = (MM_ON == 0 ? "Fixed" : MM_ON == 1 ? "FreeMargin" : "Balance") + " [MM]";
|
||
string Comment3 = DoubleToStr(MaxSpread_pips,1) + "/" + DoubleToStr(SpreadAve,1) + " [Spread Lim/Ave]";
|
||
string Comment4 = (Summertime == 0 ? "none" : Summertime == 1 ? "US" : "UK") + " [Summertime]";
|
||
string Comment5 = DoubleToStr(MaxTakeprofit_pips, 0) + "/" + DoubleToStr(MaxStopLoss_pips, 0) + " [Max TP/SL]";
|
||
|
||
CommentLabel("Comment0", Comment0, 4, 18, 10, clrYellow);
|
||
CommentLabel("Comment1", Comment1, 4, 40, 10, clrYellow);
|
||
CommentLabel("Comment2", Comment2, 4, 64, 8, clrChartWar);
|
||
CommentLabel("Comment3", Comment3, 4, 82, 8, clrChartWar);
|
||
CommentLabel("Comment4", Comment4, 4, 100, 8, clrChartWar);
|
||
CommentLabel("Comment5", Comment5, 4, 118, 8, clrChartWar);
|
||
|
||
//+------------------------------------------------------------------+
|
||
// 履歴表示用
|
||
color clrVisualHistory = !VisualHistory? clrNONE : ChartWarning? clrNONE : clrWhite;
|
||
color clrVisualHistoryPP = !VisualHistory? clrNONE : ChartWarning? clrNONE : totalpips < 0? clrOrangeRed : clrWhite;
|
||
color clrVisualHistoryPF = !VisualHistory? clrNONE : ChartWarning? clrNONE : 0 < ProfitFactor && ProfitFactor < 1? clrOrangeRed : clrWhite;
|
||
|
||
string Comment6 = "------------------------------";
|
||
string Comment7 = DoubleToStr(MarketInfo(Symbol(),MODE_SWAPLONG), 2) + "/" +
|
||
DoubleToStr(MarketInfo(Symbol(),MODE_SWAPSHORT), 2) + " [Swap B/S]";
|
||
string Comment8 = DoubleToStr(TradeCounts, 0) + " [TradeCounts]";
|
||
string Comment9 = DoubleToStr(totalpips, 1) + " [Profit (pips)]";
|
||
string Comment10 = (plus_profit == 0 || minus_profit == 0? "--- [Profit factor]" :
|
||
DoubleToStr(ProfitFactor, 2) + " [Profit factor]");
|
||
string Comment11 = (plus_profit == 0 || minus_profit == 0? "---/--- [RRR/Win%]" :
|
||
DoubleToStr(RRR, 2) + "/" + DoubleToStr(WinPer, 1) + " [RRR/Win%]");
|
||
|
||
CommentLabel("Comment6", Comment6, 4, 136, 8, clrVisualHistory);
|
||
CommentLabel("Comment7", Comment7, 4, 154, 8, clrVisualHistory);
|
||
CommentLabel("Comment8", Comment8, 4, 172, 8, clrVisualHistory);
|
||
CommentLabel("Comment9", Comment9, 4, 190, 8, clrVisualHistoryPP);
|
||
CommentLabel("Comment10", Comment10, 4, 208, 8, clrVisualHistoryPF);
|
||
CommentLabel("Comment11", Comment11, 4, 226, 8, clrVisualHistory);
|
||
//+------------------------------------------------------------------+
|
||
|
||
}
|
||
// チャートコメントの仕様
|
||
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 TradeLinePips()
|
||
{
|
||
{
|
||
if (sf != Seconds() && OrdersTotal() > 0)
|
||
{
|
||
PosHis();
|
||
sf = Seconds();
|
||
}
|
||
|
||
if ((hf != iTime((string)0, PERIOD_H1, 0) && Seconds() > 30) || tof != OrdersHistoryTotal())
|
||
{
|
||
history();
|
||
hf = iTime((string)0, PERIOD_H1, 0);
|
||
tof = OrdersHistoryTotal();
|
||
}
|
||
}
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
void PosHis()
|
||
{
|
||
int res;
|
||
double pips = 0;
|
||
|
||
for (int i = OrdersTotal() - 1; i >= 0; i--)
|
||
{
|
||
res = OrderSelect(i, SELECT_BY_POS);
|
||
if (res == false) continue;
|
||
if (OrderSymbol() != Symbol() || OrderType() > 1 || OrderMagicNumber() != MagicNumber)
|
||
continue;
|
||
pips += trend((string)TradeCounts, 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 (res == false) continue;
|
||
if (OrderSymbol() != Symbol() || OrderType() > 1 || OrderMagicNumber() != MagicNumber)
|
||
continue;
|
||
|
||
// プロフィットファクター・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;
|
||
|
||
// 合計pips計算
|
||
totalpips += trend((string)TradeCounts, OrderOpenTime(), OrderOpenPrice(), OrderCloseTime(), OrderClosePrice(), OrderType());
|
||
|
||
}
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
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("TradeLine" + obj_name);
|
||
ObjectCreate(0, "TradeLine" + obj_name, OBJ_TREND, 0, Time1, Close1, Time2, Close2);
|
||
ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_COLOR, type == 0 ? clrDodgerBlue : clrOrangeRed);
|
||
ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_STYLE, 0);
|
||
ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_WIDTH, 2);
|
||
ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_SELECTABLE, false); // オブジェクトの選択可否設定
|
||
ObjectSetInteger(0, "TradeLine" + obj_name, OBJPROP_RAY_RIGHT, false); // 右に線を延長
|
||
|
||
// トレード線内のpips表示
|
||
// 文字本体
|
||
ObjectDelete("TradePips" + obj_name);
|
||
ObjectCreate(0, "TradePips" + obj_name, OBJ_TEXT, 0, Timex, Close2);
|
||
ObjectSetInteger(0, "TradePips" + obj_name, OBJPROP_COLOR, pips < 0 ? clrOrangeRed : !IsTesting()? clrLime : clrYellow);//type == 0 ? BuyColor : SellColor);
|
||
ObjectSetInteger(0, "TradePips" + obj_name, OBJPROP_SELECTABLE, false); // オブジェクトの選択可否設定
|
||
ObjectSetInteger(0, "TradePips" + obj_name, OBJPROP_FONTSIZE, 12); // フォントサイズ
|
||
ObjectSetInteger(0, "TradePips" + obj_name, OBJPROP_ANCHOR, ANCHOR_RIGHT); // 描画位置
|
||
ObjectSetString(0, "TradePips" + obj_name, OBJPROP_TEXT, DoubleToStr(pips, 1)); // 表示するテキスト
|
||
ObjectSetString(0, "TradePips" + 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;
|
||
|
||
// MT4時間1:00のスプレッド
|
||
yTime = TimeMinute(TimeCurrent());
|
||
if (xxTime == 1 && yTime == 0)
|
||
{
|
||
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) // 1:00エントリーEA用
|
||
{
|
||
Adjustspread = SpreadAve1 + Adjustspread_Margin1; // 平均にマージン加算
|
||
MaxSpread_pips = MathMax(MathMin(Adjustspread, AllowMaxSpread), MaxSpread_pips); // 最大値とマージン加算、全体平均を比較
|
||
}
|
||
|
||
}
|
||
//+------------------------------------------------------------------+
|