gryps2/EA-code/Yoritsugu/検討中/EA_Multi_Currency.mq4
super.admin ae3f0ebf03 convert
2025-05-30 14:58:21 +02:00

808 lines
49 KiB
MQL4

//+------------------------------------------------------------------+
//| TEST.mq4 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property strict
// 列挙型宣言
enum ENUM_ONOFF{
off = 0, //OFF
on = 1 //ON
};
enum ENUM_PERIOD{
Period_M1 = 1, //1分足
Period_M5 = 5, //5分足
Period_M15 = 15, //15分足
Period_M30 = 30, //30分足
Period_H1 = 60, //1時間足
Period_H4 = 240, //4時間足
Period_D1 = 1440, //日足
Period_W1 = 10080, //週足
Period_MN1 = 43200, //月足
};
//■■■■■■■■■■■■■■■■■■■■マルチ通貨用■■■■■■■■■■■■■■■■■■■■
input string TradeSymbol = "USDJPY,EURJPY,EURUSD,GBPUSD,GBPJPY,EURGBP,AUDUSD,AUDJPY";//トレードする通貨
input string Suffix = "";//通貨の付随文字
//内部グローバル変数
int SymbolSize;//通貨の数
string SymbolArray[];//通貨を格納する配列
string _symbol;//_Symbolの代替え
int _digits;//_Digitsの代替え
double _point;//_Pointの代替え
MqlTick _tick;//Ask Bidの代替え
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit()
{
//通貨をカンマ区切りで配列に格納
SymbolSize = StringSplit(TradeSymbol, ',', SymbolArray);
return(INIT_SUCCEEDED);
}
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
input int Slippage = 3; //Slippage_Point
input int MaxSpreadPips = 5; //Spread_Pips
double xspread;
input int MagicNumber = 12345;
input double Lots = 0.1;
input int TakeProfit_pips = 1000;
input int StopLoss_pips = 1000;
input int Rikaku_pips = 1000;
input int Songiri_pips = 1000;
extern ENUM_PERIOD EA_PERIOD = Period_M5;
//トレイリングストップのパラメータ
input int TrailingStopStartPips = 1000;
input int TrailingStopPips = 1000;
//指値切り下げのパラメータ
input int ReLimitActionPips = 1000;
input int ReLimitPips = 1000;
int xBars=0, xxBars=0;
//最大ポジション数を、下記で入力指定して下さい。
int maxposition = 1;
//ローソク足始値のみに稼働させる場合は、trueにして下さい。
bool CandleStartStarting = true;
//エントリールールの各変数を下記に貼りつけます。
extern int RSI_Gyakubari_period = 14; // RSIの計算期間
extern int RSI_Gyakubari_Line = 70; // 逆張りエントリーの基準となるライン
//エントリーフィルターの各変数を下記に貼りつけます。
//決済ルールの各変数を下記に貼りつけます。
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
int i;
int ticket;
double profit;
bool res;
double xpoint = Point;
// 小数点以下の桁数に応じてPipsの値を調整する
if (_digits == 3 || _digits == 5)
{
xpoint = xpoint * 10;
}
//ローソク足始値のみ稼働(選択式)の場合、ココカラ
if(Bars != xBars || CandleStartStarting == false)
{
xBars = Bars;
//■■■■■■■■■■■■■■■■■■■■マルチ通貨用■■■■■■■■■■■■■■■■■■■■
for(int j = 0 ; j < SymbolSize ; j++)
{
//通貨ペアを作成
_symbol = SymbolArray[j] + Suffix;
//通貨ペアの呼び出しと、値取得の確認
double close0 = iClose(_symbol, PERIOD_CURRENT, 0);
if(close0 == 0 || _symbol == "")
continue;
//通貨ペアの情報取得
_point = MarketInfo(_symbol, MODE_POINT);
_digits = (int)MarketInfo(_symbol, MODE_DIGITS);
SymbolInfoTick(_symbol, _tick);
if (StringSubstr(_symbol, 0, 6) == "EURUSD") {
//エントリールールの各変数を下記に貼りつけます。
RSI_Gyakubari_period = 14; // RSIの計算期間
RSI_Gyakubari_Line = 70; // 逆張りエントリーの基準となるライン
//エントリーフィルターの各変数を下記に貼りつけます。
//決済ルールの各変数を下記に貼りつけます。
}
else if (StringSubstr(_symbol, 0, 6) == "USDJPY") {
//エントリールールの各変数を下記に貼りつけます。
RSI_Gyakubari_period = 14; // RSIの計算期間
RSI_Gyakubari_Line = 50; // 逆張りエントリーの基準となるライン
//エントリーフィルターの各変数を下記に貼りつけます。
//決済ルールの各変数を下記に貼りつけます。
}
else if (StringSubstr(_symbol, 0, 6) == "GBPUSD") {
//エントリールールの各変数を下記に貼りつけます。
RSI_Gyakubari_period = 14; // RSIの計算期間
RSI_Gyakubari_Line = 60; // 逆張りエントリーの基準となるライン
//エントリーフィルターの各変数を下記に貼りつけます。
//決済ルールの各変数を下記に貼りつけます。
}
else if (StringSubstr(_symbol, 0, 6) == "AUDUSD") {
//エントリールールの各変数を下記に貼りつけます。
RSI_Gyakubari_period = 21; // RSIの計算期間
RSI_Gyakubari_Line = 70; // 逆張りエントリーの基準となるライン
//エントリーフィルターの各変数を下記に貼りつけます。
//決済ルールの各変数を下記に貼りつけます。
}
else if (StringSubstr(_symbol, 0, 6) == "AUDJPY") {
//エントリールールの各変数を下記に貼りつけます。
RSI_Gyakubari_period = 21; // RSIの計算期間
RSI_Gyakubari_Line = 60; // 逆張りエントリーの基準となるライン
//エントリーフィルターの各変数を下記に貼りつけます。
//決済ルールの各変数を下記に貼りつけます。
}
else if (StringSubstr(_symbol, 0, 6) == "EURJPY") {
//エントリールールの各変数を下記に貼りつけます。
RSI_Gyakubari_period = 21; // RSIの計算期間
RSI_Gyakubari_Line = 50; // 逆張りエントリーの基準となるライン
//エントリーフィルターの各変数を下記に貼りつけます。
//決済ルールの各変数を下記に貼りつけます。
}
else if (StringSubstr(_symbol, 0, 6) == "EURGBP") {
//エントリールールの各変数を下記に貼りつけます。
RSI_Gyakubari_period = 28; // RSIの計算期間
RSI_Gyakubari_Line = 70; // 逆張りエントリーの基準となるライン
//エントリーフィルターの各変数を下記に貼りつけます。
//決済ルールの各変数を下記に貼りつけます。
}
else if (StringSubstr(_symbol, 0, 6) == "GBPJPY") {
//エントリールールの各変数を下記に貼りつけます。
RSI_Gyakubari_period = 28; // RSIの計算期間
RSI_Gyakubari_Line = 60; // 逆張りエントリーの基準となるライン
//エントリーフィルターの各変数を下記に貼りつけます。
//決済ルールの各変数を下記に貼りつけます。
}
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
int CountBuy = 0,CountSell = 0;
//-------- ポジションのクローズ --------
// 所有しているポジションをクローズする
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 = _tick.bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する
// オーダーを成り行き決済する
if (profit >= Rikaku_pips * xpoint || profit <= -Songiri_pips * xpoint || Exit2() == 2)
{
res = OrderClose(OrderTicket(),
OrderLots(),
_tick.bid,
NULL,
Green);
}
}
if (OrderType() == OP_SELL)
{
profit = OrderOpenPrice() - _tick.ask; // 売りポジションだった場合の、含み損益を計算する
// オーダーを成り行き決済する
if (profit >= Rikaku_pips * xpoint || profit <= -Songiri_pips * xpoint || Exit1() == 1)
{
res = OrderClose(OrderTicket(),
OrderLots(),
_tick.ask,
NULL,
Green);
}
}
}
//-------- ポジションのクローズ(ココマデ) --------
//-------- ポジションのトレーリング --------
// 所有しているポジションのSL, TPをトレールする
for(i=OrdersTotal()-1; i>=0; i--)
{
//オーダー選択(エラーを生じた場合、ループから抜け出す)
if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false)
{
Print("OrderSelect returned the error of ", GetLastError() );
break;
}
//オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る)
if (OrderSymbol() != _symbol) continue;
//マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る)
if (OrderMagicNumber() != MagicNumber) continue;
if (OrderType() == OP_BUY)
{
profit = _tick.bid - OrderOpenPrice(); // 買いポジションだった場合の、含み損益を計算する
// TrailingStopを確認する
if (profit >= TrailingStopStartPips * xpoint && OrderStopLoss() < NormalizeDouble(_tick.bid - TrailingStopPips * xpoint, _digits))
{
res = OrderModify(OrderTicket(),
OrderOpenPrice(),
NormalizeDouble(_tick.bid - TrailingStopPips * xpoint, _digits),
OrderTakeProfit(),
0,
Green);
}
// 指値の置きなおしを確認する
else if (_tick.bid <= NormalizeDouble(OrderOpenPrice() - ReLimitActionPips * xpoint, _digits)
&& OrderTakeProfit() != NormalizeDouble(OrderOpenPrice() + ReLimitPips * xpoint, _digits))
{
res = OrderModify(OrderTicket(),
OrderOpenPrice(),
OrderStopLoss(),
OrderOpenPrice() + ReLimitPips * xpoint,
0,
Green);
}
}
if (OrderType() == OP_SELL)
{
profit = OrderOpenPrice() - _tick.ask; // 売りポジションだった場合の、含み損益を計算する
// TrailingStopを確認する
if (profit >= TrailingStopStartPips * xpoint && OrderStopLoss() > NormalizeDouble(_tick.ask + TrailingStopPips * xpoint, _digits))
{
res = OrderModify(OrderTicket(),
OrderOpenPrice(),
NormalizeDouble(_tick.ask + TrailingStopPips * xpoint, _digits),
OrderTakeProfit(),
0,
Green);
}
// 指値の置きなおしを確認する
else if (_tick.ask >= NormalizeDouble(OrderOpenPrice() + ReLimitActionPips * xpoint, _digits)
&& OrderTakeProfit() != NormalizeDouble(OrderOpenPrice() - ReLimitPips * xpoint, _digits))
{
res = OrderModify(OrderTicket(),
OrderOpenPrice(),
OrderStopLoss(),
OrderOpenPrice() - ReLimitPips * xpoint,
0,
Green);
}
}
}
//-------- ポジションのトレーリング(ココマデ) --------
//-------- 新規ポジションのエントリー --------
// ポジションの数をカウントする
for(i=OrdersTotal()-1; i>=0; i--)
{
//オーダー選択(エラーを生じた場合、ループから抜け出す)
if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false)
{
Print("OrderSelect returned the error of ", GetLastError() );
break;
}
//オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る)
if (OrderSymbol() != _symbol) continue;
//マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る)
if (OrderMagicNumber() != MagicNumber) continue;
if (OrderType() == OP_BUY)
{
CountBuy = CountBuy + 1;
}
if (OrderType() == OP_SELL)
{
CountSell = CountSell + 1;
}
}
//スプレッド確認
xspread = (_tick.ask - _tick.bid) / xpoint;
// エントリー条件を確認し、成立していればエントリーを行う
if (Entry() == 1 && CountBuy < maxposition && xxBars != Bars && xspread <= MaxSpreadPips)
{
ticket = OrderSend(_symbol,
OP_BUY,
Lots,
_tick.ask,
Slippage,
0,
0,
"Buy",
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);
}
}
xxBars = Bars;
}
else if (Entry() == 2 && CountSell < maxposition && xxBars != Bars && xspread <= MaxSpreadPips)
{
ticket = OrderSend(_symbol,
OP_SELL,
Lots,
_tick.bid,
Slippage,
0,
0,
"Sell",
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);
}
}
xxBars = Bars;
}
//-------- 新規ポジションのエントリー(ココマデ) --------
}
// ローソク足始値のみ稼働(選択式)の範囲は、ココマデ
//-------- ポジションのTP, SLのセット --------
// ポジションにTP, SLをセットする
for(i=OrdersTotal()-1; i>=0; i--)
{
//オーダー選択(エラーを生じた場合、ループから抜け出す)
if (OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false)
{
Print("OrderSelect returned the error of ", GetLastError() );
break;
}
//オーダー確認(通貨ペアが一致しない場合は、for文の先頭に戻る)
if (OrderSymbol() != _symbol) continue;
//マジックナンバー確認(マジックナンバーが一致しない場合は、for文の先頭に戻る)
if (OrderMagicNumber() != MagicNumber) continue;
// 買いポジションの場合
if (OrderType() == OP_BUY)
{
profit = _tick.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() - _tick.ask; // 売りポジションだった場合の、含み損益を計算する
// TP, SLがどちらも設定されていなければ、TP, SLを設定する
if (OrderStopLoss() == 0 && OrderTakeProfit() == 0)
{
res = OrderModify(OrderTicket(), OrderOpenPrice(),
OrderOpenPrice() + StopLoss_pips * xpoint,
OrderOpenPrice() - TakeProfit_pips * xpoint,
0, MediumSeaGreen);
}
}
}
//-------- ポジションのTP, SLのセット(ココマデ) --------
}}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリー総括 |
//+------------------------------------------------------------------+
int Entry()
{
if (Entry_Rule1() == 1 && (Entry_Filter1() == 1 || Entry_Filter1() == 3)
&& (Entry_Filter2() == 1 || Entry_Filter2() == 3)
&& (Entry_Filter3() == 1 || Entry_Filter3() == 3)
&& (Entry_Filter4() == 1 || Entry_Filter4() == 3)
&& (Entry_Filter5() == 1 || Entry_Filter5() == 3)
)
{
return(1);
}
else if (Entry_Rule1() == 2 && (Entry_Filter1() == 2 || Entry_Filter1() == 3)
&& (Entry_Filter2() == 2 || Entry_Filter2() == 3)
&& (Entry_Filter3() == 2 || Entry_Filter3() == 3)
&& (Entry_Filter4() == 2 || Entry_Filter4() == 3)
&& (Entry_Filter5() == 2 || Entry_Filter5() == 3)
)
{
return(2);
}
else
{
return(0);
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 売りポジションの決済総括 |
//+------------------------------------------------------------------+
int Exit1()
{
if (Exit_Rule1() == 3 && Exit_Rule2() == 3 && Exit_Rule3() == 3 && Exit_Rule4() == 3 && Exit_Rule5() == 3)
{
return(0);
}
else if (Exit_Rule1() == 1)
{
return(1);
}
else if( Exit_Rule2() == 1)
{
return(1);
}
else if (Exit_Rule3() == 1)
{
return(1);
}
else if( Exit_Rule4() == 1)
{
return(1);
}
else if (Exit_Rule5() == 1)
{
return(1);
}
else
{
return(0);
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 買いポジションの決済総括 |
//+------------------------------------------------------------------+
int Exit2()
{
if (Exit_Rule1() == 3 && Exit_Rule2() == 3 && Exit_Rule3() == 3 && Exit_Rule4() == 3 && Exit_Rule5() == 3)
{
return(0);
}
else if (Exit_Rule1() == 2)
{
return(2);
}
else if (Exit_Rule2() == 2)
{
return(2);
}
else if (Exit_Rule3() == 2)
{
return(2);
}
else if (Exit_Rule4() == 2)
{
return(2);
}
else if (Exit_Rule5() == 2)
{
return(2);
}
else
{
return(0);
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリールール1 |
//+------------------------------------------------------------------+
int Entry_Rule1()
{
//エントリールール1を差し替える時は、下記を差し替えて下さい。
//RSIが指定値以下になったら「買い」、指定値以上になったら「売り」
double RSI0 = iRSI(_symbol,EA_PERIOD, RSI_Gyakubari_period, PRICE_CLOSE, 1);
double RSI1 = iRSI(_symbol,EA_PERIOD, RSI_Gyakubari_period, PRICE_CLOSE, 2);
//「RSI_Gyakubari_Entry_Entry_Line=70」の場合、RSIが30以下になったら買い
if (RSI0 <= 100 - RSI_Gyakubari_Line && RSI1 > 100 - RSI_Gyakubari_Line)
{
return(1);
} // 買い
// 「RSI_Gyakubari_Entry_Entry_Line=70」の場合、RSIが70以上になったら売り
else if (RSI0 >= RSI_Gyakubari_Line && RSI1 < RSI_Gyakubari_Line)
{
return(2);
} // 売り
else
{
return(0);
}
//エントリールール1を差し替える時は、ココマデを差し替えて下さい。
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター1 |
//+------------------------------------------------------------------+
int Entry_Filter1()
{
//エントリーフィルター1を差し替える時は、下記を差し替えて下さい。
//エントリーフィルター1を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター2 |
//+------------------------------------------------------------------+
int Entry_Filter2()
{
//エントリーフィルター2を差し替える時は、下記を差し替えて下さい。
//エントリーフィルター2を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター3 |
//+------------------------------------------------------------------+
int Entry_Filter3()
{
//エントリーフィルター3を差し替える時は、下記を差し替えて下さい。
//エントリーフィルター3を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター4 |
//+------------------------------------------------------------------+
int Entry_Filter4()
{
//エントリーフィルター4を差し替える時は、下記を差し替えて下さい。
//エントリーフィルター4を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| エントリーフィルター5 |
//+------------------------------------------------------------------+
int Entry_Filter5()
{
//エントリーフィルター5を差し替える時は、下記を差し替えて下さい。
//エントリーフィルター5を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール1 |
//+------------------------------------------------------------------+
int Exit_Rule1()
{
// 決済ルール1を差し替える時は、下記を差し替えて下さい。
//RSIが指定値以下になったら「買い」、指定値以上になったら「売り」
double RSI0 = iRSI(_symbol,EA_PERIOD, RSI_Gyakubari_period, PRICE_CLOSE, 1);
double RSI1 = iRSI(_symbol,EA_PERIOD, RSI_Gyakubari_period, PRICE_CLOSE, 2);
//「RSI_Gyakubari_Entry_Entry_Line=70」の場合、RSIが30以下になったら買い
if (RSI0 <= 100 - RSI_Gyakubari_Line && RSI1 > 100 - RSI_Gyakubari_Line)
{
return(1);
} // 買い
// 「RSI_Gyakubari_Entry_Entry_Line=70」の場合、RSIが70以上になったら売り
else if (RSI0 >= RSI_Gyakubari_Line && RSI1 < RSI_Gyakubari_Line)
{
return(2);
} // 売り
else
{
return(0);
}
// 決済ルール1を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール2 |
//+------------------------------------------------------------------+
int Exit_Rule2()
{
// 決済ルール2を差し替える時は、下記を差し替えて下さい。
// 決済ルール2を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール3 |
//+------------------------------------------------------------------+
int Exit_Rule3()
{
// 決済ルール3を差し替える時は、下記を差し替えて下さい。
// 決済ルール3を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール4 |
//+------------------------------------------------------------------+
int Exit_Rule4()
{
// 決済ルール4を差し替える時は、下記を差し替えて下さい。
// 決済ルール4を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 決済ルール5 |
//+------------------------------------------------------------------+
int Exit_Rule5()
{
// 決済ルール5を差し替える時は、下記を差し替えて下さい。
// 決済ルール5を差し替える時は、ココマデを差し替えて下さい。
return(3);
}
//+------------------------------------------------------------------+
double iRCI(string symbol, int timeframe, int period, int shift){
double close[];
ArrayResize(close, period);
for (int i = 0; i < period; i++) {
close[i] = iClose(symbol, timeframe, shift + i);
}
ArraySort(close, WHOLE_ARRAY, 0, MODE_DESCEND);
double d = 0;
for (int i = 0; i < period; i++) {
int rank = ArrayBsearch(close, iClose(symbol, timeframe, shift + i), WHOLE_ARRAY, 0, MODE_DESCEND);
d += MathPow(i - rank, 2);
}
double rci = (1 - 6 * d / (period * (MathPow(period, 2) - 1))) * 100;
return rci;
}