1876 lines
No EOL
136 KiB
Text
1876 lines
No EOL
136 KiB
Text
//+------------------------------------------------------------------+
|
||
//| オープン・クローズ別々で書き込み(TP/SL対応) |
|
||
//+------------------------------------------------------------------+
|
||
// 各計測用パラメータ
|
||
input bool Measurement = true; // 計測ログcsv作成(実行スプレッド・スリッページ等)
|
||
int err, fp;
|
||
string filename;
|
||
double OSpread, CSpread;
|
||
uint StartOrderTimestamp, OrderCloseTimestamp;
|
||
double Order_Price, Close_Price;
|
||
double Open_Yakujyou_Price, Close_Yakujou_Price;
|
||
double Open_Spread, Close_Spread;
|
||
double Open_Slippage, Close_Slippage;
|
||
uint OpenLatency, CloseLatency;
|
||
double profitpips;
|
||
string Timeframe = (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");
|
||
string Open_Type, Close_Type;
|
||
datetime OrderCloseTime_bak = 0, OrderOpenTime_bak = 0;
|
||
int V0;
|
||
|
||
// 指値逆指値注文時_[]内はリピート数+2?
|
||
int k, open_type_Buy[12], open_type_Sell[12];
|
||
int Ticket_Buy[12], Ticket_Sell[12];
|
||
double Gapentry[12], GapentryBuy[12], GapentrySell[12];
|
||
|
||
int OnInit()// return(0)の直前に挿入
|
||
{
|
||
|
||
// ファイル出力初期化処理
|
||
if (Measurement) FileInit();
|
||
//+------------------------------------------------------------------+
|
||
|
||
return(0);
|
||
}
|
||
|
||
void OnTick() // 優先が低いので最後に挿入
|
||
{
|
||
// 決済がTP/SLなら情報取得
|
||
if (Measurement) ClosedTradeTPSL();
|
||
//+------------------------------------------------------------------+
|
||
}
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ポジションのクローズ |
|
||
//+------------------------------------------------------------------+
|
||
// OrderCloseの前後に挟む
|
||
// 買い
|
||
CSpread = Ask - Bid; // スプレッド計測
|
||
OrderCloseTimestamp = GetTickCount();// レイテンシー計測
|
||
Close_Price = Bid; // 決済売り注文を入れる価格
|
||
V0 = (int)Volume[0];// Volume[0]の値
|
||
res = OrderClose(OrderTicket(), OrderLots(), Bid, NULL, Green);
|
||
|
||
if (res == true && Measurement == true)
|
||
{
|
||
CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー計測
|
||
|
||
if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==false) // 履歴を選択
|
||
{
|
||
Print("Access to history failed with error (",GetLastError(),")");
|
||
return;
|
||
}
|
||
// オーダー確認(通貨ペアとマジックナンバーが一致した場合は、次の処理へ進む
|
||
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
||
{
|
||
CloseTradeInfo();
|
||
}
|
||
}
|
||
|
||
// 売り
|
||
CSpread = Ask - Bid; //スプレッド計測
|
||
OrderCloseTimestamp = GetTickCount(); // レイテンシー計測
|
||
Close_Price = Ask; // 決済買い注文を入れる価格
|
||
V0 = (int)Volume[0];// Volume[0]の値
|
||
res = OrderClose(OrderTicket(), OrderLots(), Ask, NULL, Green);
|
||
|
||
if (res == true && Measurement == true)
|
||
{
|
||
CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー計測
|
||
|
||
if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==false) // 履歴を選択
|
||
{
|
||
Print("Access to history failed with error (",GetLastError(),")");
|
||
return;
|
||
}
|
||
// オーダー確認(通貨ペアとマジックナンバーが一致した場合は、次の処理へ進む
|
||
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
||
{
|
||
CloseTradeInfo();
|
||
}
|
||
}
|
||
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ポジションのオープン |
|
||
//+------------------------------------------------------------------+
|
||
// ticketの前後を挟む
|
||
// 買い
|
||
OSpread = Ask - Bid;// スプレッド計測
|
||
StartOrderTimestamp = GetTickCount();// レイテンシー計測
|
||
Order_Price = Ask;// 買い注文を入れる価格
|
||
V0 = (int)Volume[0];// Volume[0]の値
|
||
ticket = OrderSend(Symbol(),
|
||
OP_BUY,
|
||
CalculateLots(MM_Risk, StopLoss_pips),
|
||
Ask,
|
||
Slippage,
|
||
Ask - StopLoss_pips * xpoint,
|
||
Ask + TakeProfit_pips * xpoint,
|
||
_Comment,
|
||
MagicNumber,
|
||
0,
|
||
Blue);
|
||
|
||
// チケットを使ってオーダーを選択(エラーを生じた場合、何もしない)
|
||
if (OrderSelect(ticket, SELECT_BY_TICKET) == true && Measurement == true)
|
||
{
|
||
OpenTradeInfo();
|
||
}
|
||
|
||
// 売り
|
||
OSpread = Ask - Bid;// スプレッド計測
|
||
StartOrderTimestamp = GetTickCount();// レイテンシー計測
|
||
Order_Price = Bid;// 売り注文を入れる価格
|
||
V0 = (int)Volume[0];// Volume[0]の値
|
||
ticket = OrderSend(Symbol(),
|
||
OP_SELL,
|
||
CalculateLots(MM_Risk, StopLoss_pips),
|
||
Bid,
|
||
Slippage,
|
||
Bid + StopLoss_pips * xpoint,
|
||
Bid - TakeProfit_pips * xpoint,
|
||
_Comment,
|
||
MagicNumber,
|
||
0,
|
||
Red);
|
||
|
||
// チケットを使ってオーダーを選択(エラーを生じた場合、何もしない)
|
||
if (OrderSelect(ticket, SELECT_BY_TICKET) == true && Measurement == true)
|
||
{
|
||
OpenTradeInfo();
|
||
}
|
||
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 実行スプレッド・スリッページ・実行スプレッド計測・ファイル作成 |
|
||
//+------------------------------------------------------------------+
|
||
// ファイル初期化
|
||
int FileInit()
|
||
{
|
||
filename = AccountCompany() + "_スリッページログ.csv";// ファイル名を決める
|
||
|
||
fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)
|
||
if(fp==INVALID_HANDLE)
|
||
{
|
||
err = GetLastError();
|
||
printf("Error occured: [%d] %s", err, ErrorDescription(err));
|
||
return(0.0);
|
||
}
|
||
FileWrite(fp, "注文番号", "注文時間", "時刻", "分", "取引種別", "注文価格", "約定価格",
|
||
"スプレッド(pips)", "スリッページ(pips)", "レイテンシー(ms)",
|
||
"損益(pips)", "数量", "通貨ペア", "時間足", "EA名",
|
||
"マジックナンバー", "Volume[0]", "書込時Volume[0]", "書込時i");
|
||
// ファイルを閉じる
|
||
FileClose(fp);
|
||
|
||
return(0);
|
||
}
|
||
|
||
// トレード情報(成行用)
|
||
void OpenTradeInfo()
|
||
{
|
||
OpenLatency = GetTickCount() - StartOrderTimestamp; // レイテンシー計測
|
||
Order_Price = NormalizeDouble(Order_Price , Digits); // 買い注文価格を正規化
|
||
Open_Yakujyou_Price = NormalizeDouble(OrderOpenPrice(), Digits); // 実際約定した価格、正規化
|
||
Open_Slippage = NormalizeDouble(OrderType() == OP_BUY? Order_Price - Open_Yakujyou_Price :
|
||
Open_Yakujyou_Price - Order_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Open_Spread = NormalizeDouble(OSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
Open_Type = OrderType() == OP_BUY? "Buy" : "Sell";
|
||
FileWriteingOpen(); // 書き込み処理
|
||
}
|
||
void CloseTradeInfo()
|
||
{
|
||
Close_Price = NormalizeDouble(Close_Price, Digits); // 売り注文価格を正規化
|
||
Close_Yakujou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格
|
||
Close_Slippage = NormalizeDouble(OrderType() == OP_BUY? Close_Yakujou_Price - Close_Price :
|
||
Close_Price - Close_Yakujou_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Close_Spread = NormalizeDouble(CSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
profitpips = NormalizeDouble(OrderType() == OP_BUY? (OrderClosePrice() - OrderOpenPrice()) / xpoint :
|
||
(OrderOpenPrice() - OrderClosePrice()) / xpoint, 1);
|
||
Close_Type = "Close";
|
||
FileWriteingClose(); // 書き込み処理
|
||
}
|
||
|
||
// ファイル書き込み
|
||
void FileWriteingOpen()
|
||
{
|
||
for(int i = 0; i < 3000; i++)
|
||
{
|
||
FileClose(fp); // ファイルが開きっぱなしで開けないエラーを防ぐ
|
||
fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)、失敗戻り値は-1
|
||
|
||
if (fp != INVALID_HANDLE)
|
||
{
|
||
FileSeek(fp, 0, SEEK_END);
|
||
FileWrite(fp, OrderTicket(), OrderOpenTime(), Hour(), Minute(), Open_Type, Order_Price, Open_Yakujyou_Price,
|
||
Open_Spread, Open_Slippage, OpenLatency,
|
||
"---", CalculateLots(MM_Risk, MaxStopLoss_pips), Symbol(), Timeframe, WindowExpertName(),
|
||
OrderMagicNumber(), V0, Volume[0], i);
|
||
FileClose(fp);
|
||
break;
|
||
}
|
||
}
|
||
if (fp == -1) Print("Error=", GetLastError(), " ファイルの書き込みに失敗しました");
|
||
}
|
||
void FileWriteingClose()
|
||
{
|
||
for(int i = 0; i < 3000; i++)
|
||
{
|
||
FileClose(fp); // ファイルが開きっぱなしで開けないエラーを防ぐ
|
||
fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)、失敗戻り値は-1
|
||
|
||
if (fp != INVALID_HANDLE)
|
||
{
|
||
FileSeek(fp, 0, SEEK_END);
|
||
FileWrite(fp, OrderTicket(), OrderCloseTime(), Hour(), Minute(), Close_Type, Close_Price, Close_Yakujou_Price,
|
||
Close_Spread, Close_Slippage, CloseLatency,
|
||
profitpips, CalculateLots(MM_Risk, MaxStopLoss_pips), Symbol(), Timeframe, WindowExpertName(),
|
||
OrderMagicNumber(), V0, Volume[0], i);
|
||
FileClose(fp);
|
||
break;
|
||
}
|
||
}
|
||
if (fp == -1) Print("Error=", GetLastError(), " ファイルの書き込みに失敗しました");
|
||
}
|
||
|
||
// TP/SL時の検出_コメント欄の[tp]等の仕様で判別。最後尾以外の仕様は要アレンジ
|
||
void ClosedTradeTPSL()
|
||
{
|
||
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
|
||
{
|
||
//オーダー選択(エラーを生じた場合、ループから抜け出す)
|
||
if (OrderSelect( i, 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 || OrderType() == OP_SELL) && OrderCloseTime() == OrderCloseTime_bak) break;
|
||
|
||
if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderCloseTime() > OrderCloseTime_bak) // 決済時間が最新であれば
|
||
{
|
||
OrderCloseTime_bak = OrderCloseTime();
|
||
int length = StringLen(OrderComment());//StringLenは文字数を返す
|
||
if (length >= 4)
|
||
{
|
||
// TP/SL決済の確認
|
||
string tpsl = StringSubstr(OrderComment(), length-4, 4);
|
||
if (tpsl == "[tp]" || tpsl == "[sl]")
|
||
{
|
||
Close_Price = NormalizeDouble((tpsl == "[tp]"? OrderTakeProfit() : OrderStopLoss()), Digits); // 売り注文価格を正規化
|
||
Close_Yakujou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格
|
||
Close_Slippage = NormalizeDouble(OrderType() == OP_BUY? Close_Yakujou_Price - Close_Price : Close_Price - Close_Yakujou_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Close_Spread = MarketInfo(NULL,MODE_SPREAD) / 10; // スプレッド、桁合わせ
|
||
profitpips = NormalizeDouble(OrderType() == OP_BUY? (OrderClosePrice() - OrderOpenPrice()) / xpoint :
|
||
(OrderOpenPrice() - OrderClosePrice()) / xpoint, 1);
|
||
Close_Type = tpsl == "[tp]"? "TP" : "SL";
|
||
FileWriteingClose(); // 書き込み処理
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
|
||
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| オープンが指値・逆指値の場合_以下以外は、上記と同じで記述 |
|
||
//+------------------------------------------------------------------+
|
||
datetime OrderOpenTime_bak = 0;
|
||
|
||
void OnTick()
|
||
{
|
||
|
||
// エントリーが指値・逆指値の場合検知
|
||
OpenedTradeGap()
|
||
}
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ポジションのオープン |
|
||
//+------------------------------------------------------------------+
|
||
//ループがある場合、kで代入
|
||
//ticket = OrderSend処理の後に挿入
|
||
|
||
// 買い
|
||
// チケットを使ってオーダーを選択(エラーを生じた場合、何もしない)
|
||
if (OrderSelect(ticket, SELECT_BY_TICKET) == true)
|
||
{
|
||
Ticket_Buy[k] = OrderTicket();
|
||
open_type_Buy[k] = OrderType();
|
||
GapentryBuy[k] = OrderOpenPrice();
|
||
}
|
||
|
||
// 売り
|
||
// チケットを使ってオーダーを選択(エラーを生じた場合、何もしない)
|
||
if (OrderSelect(ticket, SELECT_BY_TICKET) == true)
|
||
{
|
||
Ticket_Sell[k] = OrderTicket();
|
||
open_type_Sell[k] = OrderType();
|
||
GapentrySell[k] = OrderOpenPrice();
|
||
}
|
||
|
||
//+------------------------------------------------------------------+
|
||
// 指値逆指値時の検出
|
||
void OpenedTradeGap()
|
||
{
|
||
for(int 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 || OrderType() == OP_SELL) && OrderOpenTime() <= OrderOpenTime_bak) break;
|
||
|
||
if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderOpenTime() > OrderOpenTime_bak)// エントリー時間が最新であれば。
|
||
{
|
||
OrderOpenTime_bak = OrderOpenTime();
|
||
|
||
for(k=1; k<=Repeat_count ; k++)
|
||
{
|
||
if (Ticket_Buy[k] != OrderTicket() && Ticket_Sell[k] != OrderTicket()) continue;
|
||
|
||
if (Ticket_Buy[k] == OrderTicket() || Ticket_Sell[k] == OrderTicket())
|
||
{
|
||
Open_Type = OrderType() == OP_BUY && open_type_Buy[k] == OP_BUYSTOP? "BuyStop" :
|
||
OrderType() == OP_BUY && open_type_Buy[k] == OP_BUYLIMIT? "BuyLimit" :
|
||
OrderType() == OP_SELL && open_type_Sell[k] == OP_SELLSTOP? "SellStop" : "SellLimit";
|
||
Order_Price = OrderType() == OP_BUY? GapentryBuy[k] : GapentrySell[k];
|
||
Open_Yakujyou_Price = OrderOpenPrice();
|
||
Open_Spread = MarketInfo(NULL,MODE_SPREAD) / 10;
|
||
Open_Slippage = Order_Price - Open_Yakujyou_Price; // 逆指値との差
|
||
OpenLatency = 0;
|
||
FileWriteingOpen();
|
||
}
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
|
||
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| オープン・クローズ一緒に書き込み(旧バージョン) |
|
||
//+------------------------------------------------------------------+
|
||
|
||
// 各計測用パラメータ
|
||
input bool Measurement = false; // 計測ログcsv作成(実行スプレッド・スリッページ等)
|
||
int err, fp;
|
||
double Order_Price, Close_Price;
|
||
double Open_Yakujyou_Price, Close_Yakujou_Price;
|
||
double Open_Spread, Close_Spread;
|
||
double Open_Slippage, Close_Slippage;
|
||
uint OpenLatency, CloseLatency;
|
||
string filename;
|
||
double profitpips;
|
||
|
||
int OnInit()
|
||
{
|
||
|
||
// return(0)の直前に挿入
|
||
// ファイル出力初期化処理
|
||
if (Measurement) FileInit();
|
||
|
||
return(0);
|
||
}
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ポジションのクローズ |
|
||
//+------------------------------------------------------------------+
|
||
// OrderCloseの前後に挟む
|
||
// 買い
|
||
double CSpread = Ask - Bid; // スプレッド計測
|
||
uint OrderCloseTimestamp = GetTickCount(); // レイテンシー計測
|
||
Close_Price = Bid; // 決済売り注文を入れる価格
|
||
res = OrderClose(OrderTicket(), OrderLots(), Bid, NULL, Green);
|
||
|
||
if (res == true && Measurement == true)
|
||
{
|
||
CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー計測
|
||
|
||
if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==false) // 履歴を選択
|
||
{
|
||
Print("Access to history failed with error (",GetLastError(),")");
|
||
return;
|
||
}
|
||
// オーダー確認(通貨ペアとマジックナンバーが一致した場合は、次の処理へ進む
|
||
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
||
{
|
||
Close_Price = NormalizeDouble(Close_Price, Digits); // 売り注文価格を正規化
|
||
Close_Yakujou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格
|
||
Close_Slippage = NormalizeDouble(Close_Yakujou_Price - Close_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Close_Spread = NormalizeDouble(CSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
profitpips = NormalizeDouble((OrderClosePrice() - OrderOpenPrice()) / xpoint, 1);
|
||
|
||
FileWriteing(); // 書き込み処理
|
||
}
|
||
}
|
||
|
||
// 売り
|
||
double CSpread = Ask - Bid; // スプレッド計測
|
||
uint OrderCloseTimestamp = GetTickCount(); // レイテンシー計測
|
||
Close_Price = Ask; // 決済買い注文を入れる価格
|
||
res = OrderClose(OrderTicket(), OrderLots(), Ask, NULL, Green);
|
||
|
||
if (res == true && Measurement == true)
|
||
{
|
||
CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー計測
|
||
|
||
if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==false) // 履歴を選択
|
||
{
|
||
Print("Access to history failed with error (",GetLastError(),")");
|
||
return;
|
||
}
|
||
// オーダー確認(通貨ペアとマジックナンバーが一致した場合は、次の処理へ進む
|
||
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
|
||
{
|
||
Close_Price = NormalizeDouble(Close_Price , Digits); // 買い注文価格を正規化
|
||
Close_Yakujou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格
|
||
Close_Slippage = NormalizeDouble(Close_Price - Close_Yakujou_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Close_Spread = NormalizeDouble(CSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
profitpips = NormalizeDouble((OrderOpenPrice() - OrderClosePrice()) / xpoint, 1);
|
||
|
||
FileWriteing(); // 書き込み処理
|
||
}
|
||
}
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ポジションのオープン |
|
||
//+------------------------------------------------------------------+
|
||
// ticketの前後を挟む
|
||
// 買い
|
||
double OSpread = Ask - Bid; // スプレッド計測
|
||
uint StartOrderTimestamp = GetTickCount(); // レイテンシー計測
|
||
Order_Price = Ask; // 買い注文を入れる価格
|
||
ticket = OrderSend(Symbol(),
|
||
OP_BUY,
|
||
CalculateLots(MM_Risk, MaxStopLoss_pips),
|
||
Ask,
|
||
Slippage,
|
||
Ask - StopLoss_pips * xpoint,
|
||
Ask + TakeProfit_pips * xpoint,
|
||
_Comment,
|
||
MagicNumber,
|
||
0,
|
||
Blue);
|
||
|
||
if (ticket != -1)
|
||
{
|
||
// チケットを使ってオーダーを選択(エラーを生じた場合、何もしない)
|
||
if( OrderSelect( ticket, SELECT_BY_TICKET ) == true )
|
||
{
|
||
OpenLatency = GetTickCount() - StartOrderTimestamp; // レイテンシー計測
|
||
Order_Price = NormalizeDouble(Order_Price , Digits); // 買い注文価格を正規化
|
||
Open_Yakujyou_Price = NormalizeDouble(OrderOpenPrice(), Digits); // 実際約定した価格、正規化
|
||
Open_Slippage = NormalizeDouble(Order_Price - Open_Yakujyou_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Open_Spread = NormalizeDouble(OSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
}
|
||
}
|
||
|
||
// 売り
|
||
double OSpread = Ask - Bid; // スプレッド計測
|
||
uint StartOrderTimestamp = GetTickCount(); // レイテンシー計測
|
||
Order_Price = Bid; // 売り注文を入れる価格
|
||
ticket = OrderSend(Symbol(),
|
||
OP_SELL,
|
||
CalculateLots(MM_Risk, MaxStopLoss_pips),
|
||
Bid,
|
||
Slippage,
|
||
Bid + StopLoss_pips * xpoint,
|
||
Bid - TakeProfit_pips * xpoint,
|
||
_Comment,
|
||
MagicNumber,
|
||
0,
|
||
Red);
|
||
|
||
if (ticket != -1)
|
||
{
|
||
// チケットを使ってオーダーを選択(エラーを生じた場合、何もしない)
|
||
if( OrderSelect( ticket, SELECT_BY_TICKET ) == true )
|
||
{
|
||
OpenLatency = GetTickCount() - StartOrderTimestamp; // レイテンシー計測
|
||
Order_Price = NormalizeDouble(Order_Price , Digits); // 買い注文価格を正規化
|
||
Open_Yakujyou_Price = NormalizeDouble(OrderOpenPrice(), Digits); // 実際約定した価格、正規化
|
||
Open_Slippage = NormalizeDouble(Open_Yakujyou_Price - Order_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Open_Spread = NormalizeDouble(OSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
}
|
||
}
|
||
|
||
// 以下適当な空いてる場所に挿入
|
||
//+------------------------------------------------------------------+
|
||
//| 実行スプレッド・スリッページ・実行スプレッド計測 |
|
||
//+------------------------------------------------------------------+
|
||
// ファイル初期化
|
||
int FileInit()
|
||
{
|
||
filename = AccountCompany() + "_スリッページログ.csv";// ファイル名を決める
|
||
|
||
fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)
|
||
if(fp==INVALID_HANDLE)
|
||
{
|
||
err = GetLastError();
|
||
printf("Error occured: [%d] %s", err, ErrorDescription(err));
|
||
return(0.0);
|
||
}
|
||
FileWrite(fp, "注文時間", "注文価格", "約定価格", "買/売", "ロット",
|
||
"OpenSpread", "OpenSlippage", "OpenLatency",
|
||
"決済時間", "決済注文価格", "決済約定価格",
|
||
"CloseSpread", "CloseSlippage", "CloseLatency",
|
||
"損益pips", "通貨ペア", "時間足", "EA名");
|
||
// ファイルを閉じる
|
||
FileClose(fp);
|
||
|
||
return(0);
|
||
}
|
||
// ファイル書き込み
|
||
void FileWriteing()
|
||
{
|
||
fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)
|
||
string Timeframe = (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");
|
||
|
||
if (fp != INVALID_HANDLE)
|
||
{
|
||
FileSeek(fp, 0, SEEK_END);
|
||
FileWrite(fp, OrderOpenTime(), Order_Price, Open_Yakujyou_Price,
|
||
OrderType()==0? "Buy": "Sell", CalculateLots(MM_Risk, MaxStopLoss_pips),
|
||
Open_Spread, Open_Slippage, OpenLatency,
|
||
OrderCloseTime(), Close_Price, Close_Yakujou_Price,
|
||
Close_Spread, Close_Slippage, CloseLatency,
|
||
profitpips, Symbol(), Timeframe, WindowExpertName());
|
||
FileClose(fp);
|
||
}
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// 以下サンプルEA
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| AMX-USDJPY.mq4 |
|
||
//| Copyright 2021, TNK.Co.,Ltd.|
|
||
//| https://www.mql5.com |
|
||
//+------------------------------------------------------------------+
|
||
#property copyright "Copyright 2021, TNK"
|
||
#property link "https://note.com/tnk_system"
|
||
//#property version "2.2" //スリッページ・レイテンシー計測
|
||
#property strict
|
||
#include <stdlib.mqh>
|
||
|
||
//ユーザー入力用パラメーター
|
||
input double Lots = 0.28; // ロット(単利運用時)
|
||
input double MaxSpread_pips = 3.0; // 許容スプレッド(Pips)
|
||
input int TakeProfit_pips = 130; // 利確指値(Pips)
|
||
input int StopLoss_pips = 90; // 損切逆指値(Pips)
|
||
input int GMT = 2; // GMT(冬時間)
|
||
input int Summertime = 1; // サマータイム(1:米/2:英/0:無し)
|
||
input int MagicNumber = 8691310; // マジックナンバー(他EAと重複不可)
|
||
input string _Comment = "AMX-USDJPY_2.2"; // 通知用コメント
|
||
//input bool MM_ON = false; // 複利機能
|
||
enum MM_Select{
|
||
Fixed, // 0:単利/固定
|
||
FreeMargin, // 1:複利/余剰証拠金
|
||
Balance, // 2:複利/残高
|
||
};
|
||
input MM_Select MM_ON = Fixed; // 複利機能(0:固定/1:余剰証拠金/2:残高)
|
||
input double MM_Risk = 1.0; // リスク%(余剰証拠金/残高の何%か)
|
||
|
||
//内部設定
|
||
int Maxposition = 1; // 最大ポジション
|
||
int Slippage = 10; // 許容スリッページ(Point)
|
||
bool Tokyo = true; // エントリー(東京時間)
|
||
bool London = true; // エントリー(ロンドン時間)
|
||
bool WeekendClose = true; // 週末クローズ
|
||
bool YearendClose = true; // 12/25~1/3クローズ
|
||
|
||
//ローソク足始値のみで稼働:「true」
|
||
bool CandleStartStartingEntry = true; // エントリー
|
||
bool CandleStartStartingTrailing = true; // トレイリング
|
||
bool CandleStartStartingExit = false; // 決済
|
||
|
||
//バーカウント・桁合わせ用
|
||
int xBarsEntry = 0, xBarsExit = 0, xBarsTrailing = 0;
|
||
int xBars=0, xxBars=0;
|
||
double xpoint;
|
||
|
||
//決済ルールの各変数
|
||
//成行決済
|
||
int Rikaku_pips = 9000; // 成行利確シグナルPips
|
||
int Songiri_pips = 12000; // 成行損切シグナルPips
|
||
|
||
//トレーリング
|
||
/*input bool Modify = false; // トレーリングストップ
|
||
input int TrailingStopLossStart_pips = 40; // トレール開始損益Pips
|
||
input int TrailingStopLoss_pips = 100; // トレール時のBid/Askからの値幅Pips
|
||
*/
|
||
|
||
//エントリーフィルター
|
||
int MA_PERIOD = 100; // 移動平均線の計算期間
|
||
int CandleCheckCount1 = 40; // HLマージンチェック/ローソク足何本前まで?(買い)
|
||
int HL_margin1 = 30; // HLマージンチェック/高値安値の差pips(買い)
|
||
int CandleCheckCount2 = 40; // HLマージンチェック/ローソク足何本前まで?(売り)
|
||
int HL_margin2 = 40; // HLマージンチェック/高値安値の差pips(売り)
|
||
int CandleCheckCount_H = 20; // HCマージンチェック/ローソク足何本前まで?(買い)
|
||
int HC_margin = 50; // HCマージンチェック/高値終値の差pips(買い)
|
||
int CandleCheckCount_L = 32; // LCマージンチェック/ローソク足何本前まで?(売り)
|
||
int LC_margin = 180; // LCマージンチェック/安値終値の差pips(売り)
|
||
int Day_Buy = 22; // 買い開始日
|
||
int Day_Sell = 10; // 売り開始日
|
||
|
||
//エントリー時間(サーバー時間)
|
||
bool GMT_Kadou_OK1 = false; // エントリー時間(買い)
|
||
bool GMT_Kadou_OK1_noFilter = false; // エントリー時間(買い)
|
||
bool GMT_Kadou_OK2 = false; // エントリー時間(売り)
|
||
bool GMT_Kadou_OK2_noFilter = false; // エントリー時間(売り)
|
||
|
||
//ポジション決済(サーバー時間)
|
||
bool PositionClose1 = false; // ポジション決済(買い)
|
||
bool PositionClose2 = false; // ポジション決済(売り)
|
||
|
||
//計測用パラメータ
|
||
input bool Measurement = false; // 計測スイッチ
|
||
int err, fp;
|
||
double Yakujyou_Price;
|
||
double Open_Spread, Close_Spread;
|
||
double Open_Slippage, Close_Slippage;
|
||
uint OpenLatency, CloseLatency;
|
||
string filename;
|
||
double profitpips;
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| tester function |
|
||
//+------------------------------------------------------------------+
|
||
/*double OnTester()
|
||
{
|
||
// リカバリーファクター
|
||
return(NormalizeDouble(TesterStatistics(STAT_PROFIT) / TesterStatistics(STAT_EQUITY_DD), 2));
|
||
|
||
// 勝率
|
||
// return(NormalizeDouble(100*TesterStatistics(STAT_PROFIT_TRADES) / TesterStatistics(STAT_TRADES), 2));
|
||
}*/
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| expert initialization function |
|
||
//+------------------------------------------------------------------+
|
||
int OnInit()
|
||
{
|
||
// 小数点以下の桁数に応じてPipsの値を調整する
|
||
xpoint = Point();
|
||
if (Digits() == 3 || Digits() == 5)
|
||
{
|
||
xpoint = xpoint * 10;
|
||
}
|
||
|
||
// チャート表示コメント
|
||
string LotsComment;
|
||
if (MM_ON == Fixed) LotsComment = DoubleToStr(Lots,2);
|
||
else LotsComment = //DoubleToStr(CalculateLots(MM_Risk, StopLoss_pips),1)
|
||
" (" + DoubleToStr(MM_Risk,1) +"%)";
|
||
Comment("MagicNo.:" + DoubleToStr(MagicNumber,0) +
|
||
"\n" +
|
||
"Lots:" + LotsComment +
|
||
" MM_Mode:" + (string)MM_ON +
|
||
"\n" +
|
||
"Sp:" + DoubleToStr(MaxSpread_pips, 1) +
|
||
" TP/SL:" + DoubleToStr(TakeProfit_pips,0) + "/" + DoubleToStr(StopLoss_pips,0)
|
||
);
|
||
|
||
// 使用しているインジケータを非表示にする
|
||
HideTestIndicators(true);
|
||
|
||
// ファイル出力初期化処理
|
||
if (Measurement == true)
|
||
{
|
||
filename = AccountCompany() + "_SlippageLog.csv";// ファイル名を決める
|
||
|
||
fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)
|
||
if(fp==INVALID_HANDLE)
|
||
{
|
||
err = GetLastError();
|
||
printf("Error occured: [%d] %s", err, ErrorDescription(err));
|
||
return(0.0);
|
||
}
|
||
FileWrite(fp, "OpenTime", "CloseTime", "OpenPrice", "ClosePrice", "OrderType", "ProfitPips",
|
||
"OpenSpread", "OpenSlippage", "OpenLatency",
|
||
"CloseSpread", "CloseSlippage", "CloseLatency", "CurrencyPair", "ExpertName");
|
||
// ファイルを閉じる
|
||
FileClose(fp);
|
||
}
|
||
|
||
return(0);
|
||
}
|
||
|
||
//+------------------------------------------------------------------+
|
||
void OnDeinit(const int reason)
|
||
{
|
||
Comment("");
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| Expert tick function |
|
||
//+------------------------------------------------------------------+
|
||
void OnTick()
|
||
{
|
||
// サマータイム調整・時間制御
|
||
GetSummertimeShift();
|
||
|
||
// ポジションをクローズ
|
||
PositionClose();
|
||
|
||
// トレーリング
|
||
//Trailing();
|
||
|
||
// ポジションのエントリー
|
||
PositionOpen();
|
||
|
||
// TP, SLの再設定
|
||
SetTPSL();
|
||
|
||
// チャート表示コメント
|
||
string LotsComment;
|
||
if (MM_ON == Fixed) LotsComment = DoubleToStr(Lots,2);
|
||
else LotsComment = DoubleToStr(CalculateLots(MM_Risk, StopLoss_pips),2)
|
||
+ " (" + DoubleToStr(MM_Risk,1) +"%)";
|
||
Comment("MagicNo.:" + DoubleToStr(MagicNumber,0) +
|
||
"\n" +
|
||
"Lots:" + LotsComment +
|
||
" MM_Mode:" + (string)MM_ON +
|
||
"\n" +
|
||
"Sp:" + DoubleToStr(MaxSpread_pips, 1) +
|
||
" TP/SL:" + DoubleToStr(TakeProfit_pips,0) + "/" + DoubleToStr(StopLoss_pips,0)
|
||
);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 補正関数 |
|
||
//+------------------------------------------------------------------+
|
||
void GetSummertimeShift()
|
||
{
|
||
int MON, SUN_day, xGMT, xTime, xxTime;
|
||
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); // サーバー時間(サマータイム計算なし)
|
||
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 (xxTime == 1 || xxTime == 18)
|
||
{
|
||
PositionClose1 = true;
|
||
}
|
||
else
|
||
{
|
||
PositionClose1 = false;
|
||
}
|
||
// エントリー時間(買い_サーバー時間)
|
||
if (Minute() == 0 && ((Day() >= Day_Buy && Day() <= 24) || Day() == 31) && // 00分、10~24,31日
|
||
TimeDayOfWeek(TimeCurrent()) != 1 && // 月曜日を除く
|
||
xxTime == 9 && London == true) // 9時に買い
|
||
{
|
||
GMT_Kadou_OK1 = true;
|
||
}
|
||
else
|
||
{
|
||
GMT_Kadou_OK1 = false;
|
||
}
|
||
// エントリー時間フィルターなし用(買い_サーバー時間)
|
||
if (Minute() == 0 && Day() >= 25 && Day() <= 30 && // 00分、25~30日
|
||
xxTime == 9 && London == true) // 9時に買い
|
||
{
|
||
GMT_Kadou_OK1_noFilter = true;
|
||
}
|
||
else
|
||
{
|
||
GMT_Kadou_OK1_noFilter = false;
|
||
}
|
||
|
||
// ポジションクローズ時間(売り_サーバー時間)
|
||
if (xxTime == 1 || xxTime == 9)
|
||
{
|
||
PositionClose2 = true;
|
||
}
|
||
else
|
||
{
|
||
PositionClose2 = false;
|
||
}
|
||
// エントリー時間(売り_サーバー時間)
|
||
if (Minute() == 0 && Day() >= Day_Sell && Day() <= 22 && // 00分、10~22日
|
||
xxTime == 3 && Tokyo == true) // 3時に売り
|
||
{
|
||
GMT_Kadou_OK2 = true;
|
||
}
|
||
else
|
||
{
|
||
GMT_Kadou_OK2 = false;
|
||
}
|
||
// エントリー時間フィルターなし用(売り_サーバー時間)
|
||
if (Minute() == 0 && Day() >= 23 && // 00分、23~31日
|
||
xxTime == 3 && Tokyo == true) // 3時に売り
|
||
{
|
||
GMT_Kadou_OK2_noFilter = true;
|
||
}
|
||
else
|
||
{
|
||
GMT_Kadou_OK2_noFilter = false;
|
||
}
|
||
|
||
// ここまで、エグジットとトレーリングは、取引時間に関係なく実施する
|
||
//---- トレード許可時間の判定(ココマデ) ----
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ポジションのクローズ |
|
||
//+------------------------------------------------------------------+
|
||
void PositionClose()
|
||
{
|
||
int i;
|
||
double profit;
|
||
bool res;
|
||
|
||
//ローソク足始値のみ稼働(選択式)の場合、ココカラ
|
||
if(Bars != xBars || CandleStartStartingExit == false)
|
||
{
|
||
xBars = Bars;
|
||
|
||
// 所有しているポジションをクローズする
|
||
for(i=OrdersTotal()-1; i>=0; i--)
|
||
{
|
||
//オーダー選択(エラーを生じた場合、ループから抜け出す)
|
||
if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false)
|
||
{
|
||
Print("OrderSelect returned the error of ", GetLastError() );
|
||
break;
|
||
}
|
||
|
||
//オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る)
|
||
if (OrderSymbol() != Symbol()) continue;
|
||
|
||
//マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る)
|
||
if (OrderMagicNumber() != MagicNumber) continue;
|
||
|
||
if (OrderType() == OP_BUY)
|
||
{
|
||
profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する
|
||
|
||
if (profit >= Rikaku_pips * xpoint
|
||
|| profit <= -Songiri_pips * xpoint
|
||
|| Exit2(false) == 2
|
||
|| PositionClose1 == true)
|
||
{
|
||
double CSpread = Ask - Bid;// スプレッド計測
|
||
uint OrderCloseTimestamp = GetTickCount();// レイテンシー計測
|
||
double Close_Price = Bid;// 決済売り注文を入れる価格
|
||
res = OrderClose(OrderTicket(), OrderLots(), Bid, NULL, Green);
|
||
|
||
if (res == true && Measurement == true)
|
||
{
|
||
CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー計測
|
||
|
||
if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==false) //履歴を選択
|
||
{
|
||
Print("Access to history failed with error (",GetLastError(),")");
|
||
return;
|
||
}
|
||
//オーダー確認(通貨ペアが一致した場合は、次の処理へ進む
|
||
if (OrderSymbol() == Symbol())
|
||
{
|
||
//マジックナンバー確認(マジックナンバーが一致した場合は、次の処理へ進む
|
||
if (OrderMagicNumber() == MagicNumber)
|
||
{
|
||
Close_Price = NormalizeDouble(Close_Price, Digits); // 売り注文価格を正規化
|
||
Yakujyou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格
|
||
Close_Slippage = NormalizeDouble(Yakujyou_Price - Close_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Close_Spread = NormalizeDouble(CSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
profitpips = NormalizeDouble((OrderClosePrice() - OrderOpenPrice()) / xpoint, 1);
|
||
|
||
/*Print("Slippage = ", DoubleToString(Close_Slippage, Digits),
|
||
" Latency = ", CloseLatency,
|
||
" OOT = ", OrderOpenTime(),
|
||
" OCT = ", OrderCloseTime(),
|
||
" OOP = ", OrderOpenPrice(),
|
||
" YJP = ", Yakujyou_Price,
|
||
" OSp = ", Open_Spread,
|
||
" OSl = ", Open_Slippage,
|
||
" CSp = ", Close_Spread,
|
||
" CSl = ", Close_Slippage);
|
||
*/
|
||
|
||
fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)
|
||
if (fp != INVALID_HANDLE)
|
||
{
|
||
FileSeek(fp, 0, SEEK_END);
|
||
FileWrite(fp, OrderOpenTime(), OrderCloseTime(), OrderOpenPrice(), Yakujyou_Price,
|
||
"buy", profitpips, Open_Spread, Open_Slippage, OpenLatency,
|
||
Close_Spread, Close_Slippage, CloseLatency, Symbol(), WindowExpertName());
|
||
FileClose(fp);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (OrderType() == OP_SELL)
|
||
{
|
||
profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の、含み損益を計算する
|
||
|
||
if (profit >= Rikaku_pips * xpoint
|
||
|| profit <= -Songiri_pips * xpoint
|
||
|| Exit1(true) == 1
|
||
|| PositionClose2 == true)
|
||
{
|
||
double CSpread = Ask - Bid;// スプレッド計測
|
||
uint OrderCloseTimestamp = GetTickCount();// レイテンシー計測
|
||
double Close_Price = Ask;// 決済買い注文を入れる価格
|
||
res = OrderClose(OrderTicket(), OrderLots(), Ask, NULL, Green);
|
||
|
||
if (res == true && Measurement == true)
|
||
{
|
||
CloseLatency = GetTickCount() - OrderCloseTimestamp; // レイテンシー計測
|
||
|
||
if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY)==false) //履歴を選択
|
||
{
|
||
Print("Access to history failed with error (",GetLastError(),")");
|
||
return;
|
||
}
|
||
//オーダー確認(通貨ペアが一致した場合は、次の処理へ進む
|
||
if (OrderSymbol() == Symbol())
|
||
{
|
||
//マジックナンバー確認(マジックナンバーが一致した場合は、次の処理へ進む
|
||
if (OrderMagicNumber() == MagicNumber)
|
||
{
|
||
Close_Price = NormalizeDouble(Close_Price , Digits); // 買い注文価格を正規化
|
||
Yakujyou_Price = NormalizeDouble(OrderClosePrice(), Digits); // 実際約定した価格
|
||
Close_Slippage = NormalizeDouble(Close_Price - Yakujyou_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Close_Spread = NormalizeDouble(CSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
profitpips = NormalizeDouble((OrderOpenPrice() - OrderClosePrice()) / xpoint, 1);
|
||
|
||
/*Print("Slippage = ", DoubleToString(Close_Slippage, Digits),
|
||
" Latency = ", CloseLatency,
|
||
" OOT = ", OrderOpenTime(),
|
||
" OCT = ", OrderCloseTime(),
|
||
" OOP = ", OrderOpenPrice(),
|
||
" YJP = ", Yakujyou_Price,
|
||
" OSp = ", Open_Spread,
|
||
" OSl = ", Open_Slippage,
|
||
" CSp = ", Close_Spread,
|
||
" CSl = ", Close_Slippage);
|
||
*/
|
||
|
||
fp = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_CSV, ',');// ファイルオープン(csv)
|
||
if (fp != INVALID_HANDLE)
|
||
{
|
||
FileSeek(fp, 0, SEEK_END);
|
||
FileWrite(fp, OrderOpenTime(), OrderCloseTime(), OrderOpenPrice(), OrderClosePrice(),
|
||
"sell", profitpips, Open_Spread, Open_Slippage, OpenLatency,
|
||
Close_Spread, Close_Slippage, CloseLatency, Symbol(), WindowExpertName());
|
||
FileClose(fp);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} // 所有しているポジションをクローズする(ココマデ)
|
||
} //ローソク足始値のみ稼働(ココマデ)
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| トレーリング |
|
||
//+------------------------------------------------------------------+
|
||
/*void Trailing()
|
||
{
|
||
int i;
|
||
double profit;
|
||
bool res;
|
||
|
||
// トレーリングのローソク足始値のみ稼働(選択式)
|
||
if(Bars != xBarsTrailing || CandleStartStartingTrailing == false)
|
||
{
|
||
xBarsTrailing = Bars;
|
||
|
||
// 所有しているポジションのストップをトレールする
|
||
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;
|
||
|
||
// トレイルON、OFF
|
||
if (Modify == true)
|
||
{
|
||
if (OrderType() == OP_BUY)
|
||
{
|
||
profit = Bid - OrderOpenPrice(); // 買いポジションだった場合の含み損益を計算する
|
||
|
||
// 含み益が一定値以上の場合、SLを引き上げる
|
||
if (profit >= TrailingStopLossStart_pips * xpoint
|
||
&& OrderStopLoss() < NormalizeDouble(Bid - TrailingStopLossStart_pips * xpoint, Digits()))
|
||
{
|
||
res = OrderModify(OrderTicket(),
|
||
OrderOpenPrice(),
|
||
Bid - TrailingStopLoss_pips * xpoint,
|
||
OrderTakeProfit(),
|
||
0,
|
||
MediumSeaGreen);
|
||
}
|
||
}
|
||
|
||
if (OrderType() == OP_SELL)
|
||
{
|
||
profit = OrderOpenPrice() - Ask; // 売りポジションだった場合の含み損益を計算する
|
||
|
||
// 含み益が一定値以上の場合、逆指値を引き上げる
|
||
if (profit >= TrailingStopLossStart_pips * xpoint
|
||
&& OrderStopLoss() > NormalizeDouble(Ask + TrailingStopLossStart_pips * xpoint, Digits()))
|
||
{
|
||
res = OrderModify(OrderTicket(),
|
||
OrderOpenPrice(),
|
||
Ask + TrailingStopLoss_pips * xpoint,
|
||
OrderTakeProfit(),
|
||
0,
|
||
MediumSeaGreen);
|
||
}
|
||
}
|
||
}
|
||
} // 所有しているポジションのストップをトレールする(ココマデ)
|
||
} // トレーリングのローソク足始値のみ稼働(ココマデ)
|
||
}*/
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| ポジションのオープン |
|
||
//+------------------------------------------------------------------+
|
||
void PositionOpen()
|
||
{
|
||
int i;
|
||
int ticket;
|
||
int CountBuy = 0,CountSell = 0;
|
||
bool res;
|
||
|
||
// エントリー判断のローソク足始値のみ稼働(選択式)
|
||
if(Bars != xBarsEntry || CandleStartStartingEntry == false)
|
||
{
|
||
xBarsEntry = Bars;
|
||
|
||
// ポジションの数をカウントする
|
||
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;
|
||
}
|
||
} // ポジションの数をカウントする(ココマデ)
|
||
|
||
// エントリー条件を確認し、成立していればエントリーを行う
|
||
if (Entry(true) == 1 // 買いエントリー
|
||
&& CountSell == 0
|
||
&& CountBuy < Maxposition
|
||
&& xxBars != Bars
|
||
&& (GMT_Kadou_OK1 == true || GMT_Kadou_OK1_noFilter == true))
|
||
{
|
||
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)
|
||
{
|
||
double OSpread = Ask - Bid;// スプレッド計測
|
||
uint StartOrderTimestamp = GetTickCount();// レイテンシー計測
|
||
double Order_Price = Ask;// 買い注文を入れる価格
|
||
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 )
|
||
{
|
||
OpenLatency = GetTickCount() - StartOrderTimestamp; // レイテンシー計測
|
||
Order_Price = NormalizeDouble(Order_Price , Digits); // 買い注文価格を正規化
|
||
Yakujyou_Price = NormalizeDouble(OrderOpenPrice(), Digits); // 実際約定した価格、正規化
|
||
Open_Slippage = NormalizeDouble(Order_Price - Yakujyou_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Open_Spread = NormalizeDouble(OSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
|
||
res = OrderModify(OrderTicket(),
|
||
OrderOpenPrice(),
|
||
OrderOpenPrice() - StopLoss_pips * xpoint,
|
||
OrderOpenPrice() + TakeProfit_pips * xpoint,
|
||
0, MediumSeaGreen);
|
||
|
||
//Print("Slippage = ", DoubleToString(Open_Slippage,Digits),
|
||
// " Latency= ", OpenLatency);
|
||
}
|
||
}
|
||
}
|
||
xxBars = Bars;
|
||
}
|
||
|
||
if (Entry(false) == 2 // 売りエントリー
|
||
&& CountBuy == 0
|
||
&& CountSell < Maxposition
|
||
&& xxBars != Bars
|
||
&& (GMT_Kadou_OK2 == true || GMT_Kadou_OK2_noFilter == true))
|
||
{
|
||
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)
|
||
{
|
||
double OSpread = Ask - Bid;// スプレッド計測
|
||
uint StartOrderTimestamp = GetTickCount();// レイテンシー計測
|
||
double Order_Price = Bid;// 売り注文を入れる価格
|
||
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 )
|
||
{
|
||
OpenLatency = GetTickCount() - StartOrderTimestamp; // レイテンシー計測
|
||
Order_Price = NormalizeDouble(Order_Price , Digits); // 買い注文価格を正規化
|
||
Yakujyou_Price = NormalizeDouble(OrderOpenPrice(), Digits); // 実際約定した価格、正規化
|
||
Open_Slippage = NormalizeDouble(Yakujyou_Price - Order_Price, Digits) / xpoint; // スリッページ、桁合わせ
|
||
Open_Spread = NormalizeDouble(OSpread, Digits) / xpoint; // スプレッド、桁合わせ
|
||
|
||
res = OrderModify(OrderTicket(),
|
||
OrderOpenPrice(),
|
||
OrderOpenPrice() + StopLoss_pips * xpoint,
|
||
OrderOpenPrice() - TakeProfit_pips * xpoint,
|
||
0, MediumSeaGreen);
|
||
|
||
//Print("Slippage = ", DoubleToString(Open_Slippage,Digits),
|
||
// " Latency= ", OpenLatency);
|
||
}
|
||
}
|
||
}
|
||
xxBars = Bars;
|
||
}
|
||
} // エントリー判断のローソク足始値のみ稼働(ココマデ)
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 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 tickvalue; // 1ロット1pip当たりの証拠金通貨相当額
|
||
double lotstep; // サーバのロット数の最小刻み制限
|
||
double maxlots; // サーバの最大ロット数制限
|
||
double minlots; // サーバの最小ロット数制限
|
||
double lotsize = Lots; // ロットサイズ
|
||
|
||
// 複利機能を使わない場合、Lotsを返す
|
||
if (MM_ON == Fixed) return(Lots);
|
||
|
||
freemargin = AccountFreeMargin();
|
||
balance = AccountBalance();
|
||
tickvalue = MarketInfo(NULL, MODE_TICKVALUE);
|
||
lotstep = MarketInfo(NULL, MODE_LOTSTEP);
|
||
maxlots = MarketInfo(NULL, MODE_MAXLOT);
|
||
minlots = MarketInfo(NULL, MODE_MINLOT);
|
||
|
||
// tickvalueはpipsではなくpointなので、小数点以下の桁数に応じて補正する
|
||
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にかかった時の金額
|
||
}
|
||
|
||
// サーバのロット数の刻みに合わせてロット数を修正
|
||
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 tickvalue; // 1ロット1pip当たりの証拠金通貨相当額
|
||
double lotstep; // サーバのロット数の最小刻み制限
|
||
double maxlots; // サーバの最大ロット数制限
|
||
double minlots; // サーバの最小ロット数制限
|
||
double lotamount; // 1ロットの通貨数
|
||
double lotsize = Lots; // ロットサイズ
|
||
double conv; // 口座通貨種類による補正係数
|
||
|
||
// 複利機能を使わない場合、Lotsを返す
|
||
if (MM_ON == Fixed) return(Lots);
|
||
|
||
freemargin = AccountFreeMargin();
|
||
balance = AccountBalance();
|
||
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);
|
||
|
||
// 1万通貨*1pips = $1 = 100円と仮定し、1ロット1pipの変動が口座通貨でいくらに相当するか計算
|
||
// 1 lot = 10万通貨
|
||
// 口座通貨 = JPY : tickvalue = 1000円/(lot・pip)
|
||
// 口座通貨 = USD : tickvalue = $10/(lot・pip)
|
||
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にかかった時の金額
|
||
}
|
||
|
||
// サーバのロット数の刻みに合わせてロット数を修正
|
||
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)
|
||
&& (Entry_Filter6(isbuy) == 1 || Entry_Filter6(isbuy) == 3)
|
||
&& (Entry_Filter7(isbuy) == 1 || Entry_Filter7(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)
|
||
&& (Entry_Filter6(isbuy) == 2 || Entry_Filter6(isbuy) == 3)
|
||
&& (Entry_Filter7(isbuy) == 2 || Entry_Filter7(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 (GMT_Kadou_OK1 == true || GMT_Kadou_OK1_noFilter == true)
|
||
{
|
||
return(1);
|
||
} // 買い
|
||
|
||
if (GMT_Kadou_OK2 == true || GMT_Kadou_OK2_noFilter == 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);
|
||
} // トレード不許可
|
||
|
||
else
|
||
{
|
||
return(3);
|
||
} // トレード許可
|
||
|
||
//エントリーフィルター1ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター2 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter2(bool isbuy)
|
||
{
|
||
//エントリーフィルター2
|
||
// 12/25~1/3まではエントリーしない
|
||
int NGMonth = Month();
|
||
int NGDay = Day();
|
||
if (YearendClose == true
|
||
&& ((NGMonth == 12 && NGDay >= 25) || (NGMonth == 1 && NGDay <= 3))
|
||
)
|
||
{
|
||
return(0);
|
||
} // エントリー出来ない
|
||
|
||
//エントリーフィルター2ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター3 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter3(bool isbuy)
|
||
{
|
||
//エントリーフィルター3
|
||
// 過去値動きによるエントリー制御
|
||
// 過去〇本の最高値、最安値を求める
|
||
double MostHigh1 = High[iHighest(NULL, PERIOD_H1, MODE_HIGH, CandleCheckCount1, 1)];
|
||
double MostLow1 = Low[iLowest(NULL, PERIOD_H1, MODE_LOW , CandleCheckCount1, 1)];
|
||
double MostHigh2 = High[iHighest(NULL, PERIOD_H1, MODE_HIGH, CandleCheckCount2, 1)];
|
||
double MostLow2 = Low[iLowest(NULL, PERIOD_H1, MODE_LOW , CandleCheckCount2, 1)];
|
||
|
||
// 過去◯本に◯◯pips以内の値動きだったらエントリー禁止
|
||
if (isbuy == true && MostHigh1 - MostLow1 < HL_margin1 * xpoint)
|
||
{
|
||
return(0);
|
||
} // エントリー出来ない
|
||
|
||
if (isbuy == false && MostHigh2 - MostLow2 < HL_margin2 * xpoint)
|
||
{
|
||
return(0);
|
||
} // エントリー出来ない
|
||
|
||
//エントリーフィルター3ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター4 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter4(bool isbuy)
|
||
{
|
||
//エントリーフィルター4
|
||
// 過去値動きによるエントリー制御
|
||
// 過去〇本の最高値、最安値を求める
|
||
double MostHigh = High[iHighest(NULL, PERIOD_H1, MODE_HIGH, CandleCheckCount_H, 1)];
|
||
double MostLow = Low[iLowest(NULL, PERIOD_H1, MODE_LOW , CandleCheckCount_L, 1)];
|
||
double HC = MostHigh - Close[1];
|
||
double LC = Close[1] - MostLow;
|
||
|
||
// 過去◯本の、高値と1本前終値の差が◯◯pips以上だったら買いエントリー禁止
|
||
if (isbuy == true && HC > HC_margin * xpoint)
|
||
{
|
||
return(0);
|
||
} // エントリー出来ない
|
||
|
||
// 過去◯本の、安値と1本前終値の差が◯◯pips以上だったら売りエントリー禁止
|
||
if (isbuy == false && LC > LC_margin * xpoint)
|
||
{
|
||
return(0);
|
||
} // エントリー出来ない
|
||
|
||
//エントリーフィルター4ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター5 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter5(bool isbuy)
|
||
{
|
||
//エントリーフィルター5
|
||
// MAを宣言
|
||
double MA_fast1 = iMA(NULL, PERIOD_H1, MA_PERIOD, 0, MODE_EMA, PRICE_CLOSE, 1); // 1本前の短期MA
|
||
|
||
// 価格が長期移動平均線より上なら「買い」、下なら「売り」
|
||
if (isbuy == true && GMT_Kadou_OK1 == true && Close[1] > MA_fast1)
|
||
{
|
||
return(1);
|
||
} // 買い
|
||
|
||
if (isbuy == false && GMT_Kadou_OK2 == true && Close[1] <MA_fast1)
|
||
{
|
||
return(2);
|
||
} // 売り
|
||
|
||
// フィルターなし
|
||
if (isbuy == true && GMT_Kadou_OK1_noFilter == true)
|
||
{
|
||
return(1);
|
||
} // 買い
|
||
|
||
if (isbuy == false && GMT_Kadou_OK2_noFilter == true)
|
||
{
|
||
return(2);
|
||
} // 売り
|
||
|
||
return(0);
|
||
|
||
//エントリーフィルター5ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター6 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter6(bool isbuy)
|
||
{
|
||
//エントリーフィルター6
|
||
// MAを宣言
|
||
double MA1 = iMA(NULL, PERIOD_M15, 20, 0, MODE_SMA, PRICE_CLOSE, 1);
|
||
|
||
// 価格が短期移動平均線の下なら「買い」、上なら「売り」
|
||
if (isbuy == true && GMT_Kadou_OK1 == true && MA1 > Close[1])
|
||
{
|
||
return(1);
|
||
} // 買い
|
||
|
||
if (isbuy == false && GMT_Kadou_OK2 == true && MA1 < Close[1])
|
||
{
|
||
return(2);
|
||
} // 売り
|
||
|
||
// フィルターなし
|
||
if (isbuy == true && GMT_Kadou_OK1_noFilter == true)
|
||
{
|
||
return(1);
|
||
} // 買い
|
||
|
||
if (isbuy == false && GMT_Kadou_OK2_noFilter == true)
|
||
{
|
||
return(2);
|
||
} // 売り
|
||
|
||
return(0); // エントリー出来ない
|
||
//エントリーフィルター6ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| エントリーフィルター7 |
|
||
//+------------------------------------------------------------------+
|
||
int Entry_Filter7(bool isbuy)
|
||
{
|
||
//エントリーフィルター7
|
||
|
||
//エントリーフィルター7ココマデ
|
||
return(3);
|
||
}
|
||
//+------------------------------------------------------------------+
|
||
|
||
//+------------------------------------------------------------------+
|
||
//| 決済ルール1 |
|
||
//+------------------------------------------------------------------+
|
||
int Exit_Rule1(bool isbuy)
|
||
{
|
||
// 決済ルール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);
|
||
}
|
||
//+------------------------------------------------------------------+ |