![見出し画像](https://assets.st-note.com/production/uploads/images/107704367/rectangle_large_type_2_c4dc4a8598214aaf32378d2453ef44ce.png?width=1200)
RSI逆張りEAが勝てない
不測の事態が起きた。
RSIのEAがまるで勝てない。
真相は定かではないが、今判明しているのはバックテストとフォワードの乖離が大きい。
あとは想定外のところでエントリーする。
それからデモ口座と本番口座とエントリーの差が出ている。
これはなぜか?
これも推論だが
RSIはワークするが、その分人気でエントリーが集中しやすくスプレッドが拡がる可能性、またスリッページが発生している可能性がある。
バックテストやデモ口座なら勝てるので、この問題に気付くのにかなり時間がかかってしまった。
皆さんもRSIのEAを使う場合はホソノがそんなことをぼやいてたこと留意してください。
最後にゴゴジャンにて販売を取り下げたRSIの逆張りEAのソースコードとバックテストを貼り付けてさようなら。
なお、現役で使っているEAはnoteのトップページから有料マガジン10000円で販売中です。朝スキャEAやアノマリーEA3個も入ってるのでお得です。
https://note.com/hosono_p/m/mc1ac74bca309
MT4 バックテスト結果 ドル円スプレッド15
![](https://assets.st-note.com/img/1686219796410-g9BqxmGyfl.png?width=1200)
MT4 ソースコード
//+------------------------------------------------------------------+
//| ProjectName |
//| Copyright 2018, CompanyName |
//| http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "Hosono_p"
#property strict
#property version "1.00"
#property description "RSI逆張りでエントリーします。ドル円5分足にセットしてください。"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool is_good_spread()
{
bool A,B;
A = iOpen(NULL,0,0) + 30 * _Point > iClose(NULL,0,0);
B = iOpen(NULL,0,0) - 30 * _Point < iClose(NULL,0,0);
return A && B;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double calc_martin_lots(int side)
{
double bairitu = input_martin_bairitu;
double position_lots_list[50];
double martin_lots=0;
ArrayInitialize(position_lots_list,0.0);
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
position_lots_list[i] = OrderLots();
}
}
}
}
}
double position_max_lots = position_lots_list[ArrayMaximum(position_lots_list,WHOLE_ARRAY,0)];
if(input_nanpin_on)
{
martin_lots = NormalizeDouble(position_max_lots * bairitu, 2);
}
if(input_nanpin_on==false)
{
martin_lots = position_max_lots;
}
return martin_lots;
}
enum use_times
{
GMT9, //WindowsPCの時間を使って計算する
GMT9_BACKTEST, // EAで計算された時間を使う(バックテスト用)
GMT_KOTEI// サーバータイムがGMT+0で固定されている(バックテスト用)
};
//EA設定
sinput string EA_settei = "";//ーーー注文情報ーーー
input int magic_number = 7771777;//マジックナンバー
bool GetTicketError =false;
input use_times set_time = GMT9;//時間取得方法
input int natu = 6;//夏加算時間(バックテスト用)
input int huyu = 7;//冬加算時間(バックテスト用)
enum lots_sitei
{
KOTEI,//固定ロット
HENDOU,//証拠金残高で変動(複利モード)
TORIMODOSI,//固定ロット+ドローダウンで倍率アップ
HENDOUTORIMODOSI//複利+ドローダウンで倍率アップ
};
//EA設定
input string LOTS_settei = "";//ーーーロット数の設定ーーー
input lots_sitei lots_houhou = KOTEI;//設定の選択
input int supu = 25 ;//スプレッド単位Point(0の場合は無制限)
input int Slippage=10; //スリップページ単位Point(0の場合は無制限)
input double ilots = 0.1; //固定ロットのロットサイズ
input string HUKURI_settei = "";//ーーー複利モードの設定ーーー
input string parameter0 ="↓ロット計算式(基準ロット÷証拠金)";//ロット数を証拠金残高で変動する計算用設定
input int syoukokin = 100000;//証拠金(ロット数計算用)
input double calc_lot_size = 0.01;//基準ロット
input string DROWDOWN_settei = "";//ーーードローダウンモードの設定ーーー
input string parameter1 ="↓ロット計算式(基準ロット÷ドローダウン金額)";//ロット数を証拠金残高で変動する計算用設定
input int drawdown_num = 100000;//ドローダウン金額(ロット数計算用)
input double drawdown_lot_size = 0.01;//基準ロット
input string RSI_settei = "";//ーーーRSIの設定ーーー
input int input_rsi_period = 14;//期間
input int input_rsi_shift = 1;//シフト
input int input_rsi_entry_high = 70;//エントリーRSI-HIGH
input int input_rsi_entry_low = 30;//エントリーRSI-LOW
input int input_rsi_close_high = 60;//決済RSI-HIGH
input int input_rsi_close_low = 40;//決済RSI-LOW
input string nanpin_settei = "";//ーーーナンピンマーチンの設定ーーー
input bool input_nanpin_on = true;//ナンピンマーチンの有効
input int input_nanpin_kaisuu = 1;//最大ナンピン回数
input double input_martin_bairitu = 1.5;//マーチンの倍率
input string songiri_settei = "";//ーーー損切の設定ーーー
input int input_songiri_pips = 150;//損切(単位:PIPS)
input string entry_interval_settei = "";//ーーーエントリーの間隔設定ーーー
input int input_entry_interval = 10;//エントリーの間隔(単位:ローソク足)
//エントリーモードの選択
enum entry_mode_list
{
NORMAL,
HYPER
};
input string entry_mode_settei = "";//ーーーエントリーのモードの設定ーーー
input entry_mode_list input_entry_mode = NORMAL;//エントリーモード選択
input string hyper_mode_settei = "";//ーーーHYPERモードの設定ーーー
input int input_limit = 30;//リミットエントリーの位置((Ask+Bid/2)±)単位Point
input int input_limit_off = 100;//リミットエントリーの解除Point
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
order_all_cancel();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double nehaba = 0;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit()
{
ObjectsDeleteAll();
create_label();
create_label2();
create_label3();
create_label4();
max_syoukokin = AccountEquity();
now_syoukokin = AccountEquity();
return 0;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTick()
{
if(input_entry_mode==NORMAL)
{
normal_mode();
}
else
{
hyper_mode();
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void normal_mode()
{
bool A,B,C,D,E,F,G,H,I,J,K,L,M;
int buy_position_count = position_count(OP_BUY);
int sell_position_count = position_count(OP_SELL);
int buy_limit_position_count = position_count(OP_BUYLIMIT);
int sell_limit_position_count = position_count(OP_SELLLIMIT);
entry_switch(buy_position_count,sell_position_count);
//limitが2個ある状態なら削除する
A = buy_limit_position_count > 1;
B = sell_limit_position_count > 1;
if(A)
{
order_cancel(OP_BUYLIMIT);
}
if(B)
{
order_cancel(OP_SELLLIMIT);
}
//土曜日じゃなければ動作する
A = is_close_time() == false;
bool res= ((supu * _Point) > (Ask - Bid));
bool kadou = TimeHour(calculate_time()) == 2||
TimeHour(calculate_time()) == 3||
TimeHour(calculate_time()) == 4||
TimeHour(calculate_time()) == 5||
TimeHour(calculate_time()) == 8||
TimeHour(calculate_time()) == 9||
TimeHour(calculate_time()) == 10||
TimeHour(calculate_time()) == 11||
TimeHour(calculate_time()) == 12||
TimeHour(calculate_time()) == 13||
TimeHour(calculate_time()) == 14||
TimeHour(calculate_time()) == 15||
TimeHour(calculate_time()) == 16;
bool kadou4 = true;
for(int i = 0; i<=10; i++)
{
if(80<iRSI(NULL,PERIOD_M15,14,PRICE_CLOSE,i) || 20>iRSI(NULL,PERIOD_M15,14,PRICE_CLOSE,i))
{
kadou4 =false;
}
}
if(((supu * _Point) > (Ask - Bid)) || (supu == 0))
{
if(A && kadou4 && kadou)
{
//エントリー
A = is_up_trend();
B = is_down_trend();
C = is_buy();
D = is_sell();
E = buy_position_count < (input_nanpin_on?input_nanpin_kaisuu:1);
F = sell_position_count < (input_nanpin_on?input_nanpin_kaisuu:1);
G = buy_limit_position_count == 0;
H = sell_limit_position_count == 0;
I = entry_on;
J = is_good_spread();
K = get_order_price(OP_BUYLIMIT) + _Point * input_limit_off < NormalizeDouble((Ask + Bid) / 2,_Digits);
L = get_order_price(OP_SELLLIMIT) - _Point * input_limit_off > NormalizeDouble((Ask + Bid) / 2,_Digits);
M = is_filter_sefe();
double price = NormalizeDouble((Ask + Bid) / 2,_Digits);
//ポジション0かつオーダー0
if(E && F && G && H && I && J && M)
{
if(A && C)
{
position_entry(OP_BUY);
}
if(B && D)
{
position_entry(OP_SELL);
}
}
//ポジション0かつbuyオーダー1
if(E && F && G == false)
{
if(K)
{
order_all_cancel();
}
}
//ポジション0かつsellオーダー1
if(E && F && H == false)
{
if(L)
{
order_all_cancel();
}
}
}
}
//決済
close_judge(buy_position_count,sell_position_count);
owarinodousa(buy_position_count,sell_position_count);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void hyper_mode()
{
bool A,B,C,D,E,F,G,H,I,J,K,L,M;
int buy_position_count = position_count(OP_BUY);
int sell_position_count = position_count(OP_SELL);
int buy_limit_position_count = position_count(OP_BUYLIMIT);
int sell_limit_position_count = position_count(OP_SELLLIMIT);
entry_switch(buy_position_count,sell_position_count);
//limitが2個ある状態なら削除する
A = buy_limit_position_count > 1;
B = sell_limit_position_count > 1;
if(A)
{
order_cancel(OP_BUYLIMIT);
}
if(B)
{
order_cancel(OP_SELLLIMIT);
}
//土曜日じゃなければ動作する
A = is_close_time() == false;
bool res= ((supu * _Point) > (Ask - Bid));
if(((supu * _Point) > (Ask - Bid)) || (supu == 0))
{
if(A)
{
//エントリー
A = is_up_trend();
B = is_down_trend();
C = is_buy();
D = is_sell();
E = buy_position_count < 5;
F = sell_position_count < 5;
G = buy_limit_position_count == 0;
H = sell_limit_position_count == 0;
I = entry_on;
J = is_good_spread();
K = get_order_price(OP_BUYLIMIT) + _Point * input_limit_off < NormalizeDouble((Ask + Bid) / 2,_Digits);
L = get_order_price(OP_SELLLIMIT) - _Point * input_limit_off > NormalizeDouble((Ask + Bid) / 2,_Digits);
M = is_filter_sefe();
double price = NormalizeDouble((Ask + Bid) / 2,_Digits);
//ポジション0かつオーダー0
if(E && F && G && H && I && J && M)
{
if(A && C)
{
position_entry_limit(OP_BUYLIMIT,Ask - input_limit * _Point);
}
if(B && D)
{
position_entry_limit(OP_SELLLIMIT,Bid + input_limit * _Point);
}
}
//ポジション0かつbuyオーダー1
if(E && F && G == false)
{
if(K)
{
order_all_cancel();
}
}
//ポジション0かつsellオーダー1
if(E && F && H == false)
{
if(L)
{
order_all_cancel();
}
}
}
}
//決済
close_judge(buy_position_count,sell_position_count);
owarinodousa(buy_position_count,sell_position_count);
}
input string safe_filter_settei = "";//ーーー価格の急変動時停止設定ーーー
input int input_safe_filter_num = 3;//過去ローソク足【ユーザー入力値】本
input double input_safe_filter_kyoyou_price_bairitu = 2.7;//(高値 - 安値)が ATR14 × 【ユーザー入力値】 を超えたら停止
bool is_filter_sefe()
{
double filter_price = iATR(NULL,0,14,0) * input_safe_filter_kyoyou_price_bairitu;
double base =0;
bool is_safe = true;
for(int i = 1; i<=input_safe_filter_num; i++)
{
base = iHigh(NULL,0,i) - iLow(NULL,0,i);
if(base > filter_price)
{
is_safe = false;
}
}
return is_safe;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool is_buy()
{
double rsi = iRSI(NULL,0,input_rsi_period,0,input_rsi_shift);
if(rsi < input_rsi_entry_low)
{
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool is_sell()
{
double rsi = iRSI(NULL,0,input_rsi_period,0,input_rsi_shift);
if(rsi > input_rsi_entry_high)
{
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool is_up_trend()
{
double close = iClose(NULL,0,0);
double close100 = iClose(NULL,0,100);
double close200 = iClose(NULL,0,200);
double mom100 = close - close100;
double mom200 = close - close200;
//「momが0超え」なら上昇トレンド
if(0 < mom100 && 0 < mom200)
{
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool is_down_trend()
{
double close = iClose(NULL,0,0);
double close100 = iClose(NULL,0,100);
double close200 = iClose(NULL,0,200);
double mom100 = close - close100;
double mom200 = close - close200;
//「momが0未満」なら下降トレンド
if(0 > mom100 && 0 > mom200)
{
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void owarinodousa(int buy_position_count,int sell_position_count)
{
//土曜日はどうすればいいのか
if(is_close_time())
{
if(!input_doyoubi_close)
{
order_all_cancel();
}
else
{
order_all_cancel();
if(buy_position_count>0)
{
position_close(OP_BUY);
}
if(sell_position_count>0)
{
position_close(OP_SELL);
}
}
}
//クレイジーシステム
now_syoukokin = AccountEquity();
if(max_syoukokin <= now_syoukokin)
{
max_syoukokin = now_syoukokin;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void close_judge(int buy_position_count,int sell_position_count)
{
double rsi = iRSI(NULL,0,input_rsi_period,0,input_rsi_shift);
if(buy_position_count > 0)
{
position_stop(OP_BUY);
if(rsi > input_rsi_close_high)
{
position_close(OP_BUY);
}
}
if(sell_position_count > 0)
{
position_stop(OP_SELL);
if(rsi < input_rsi_close_low)
{
position_close(OP_SELL);
}
}
}
//+------------------------------------------------------------------+
//|ポジション数カウント
//+------------------------------------------------------------------+
int position_count(int side)
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
count++;
}
}
}
}
}
return count;
}
//+------------------------------------------------------------------+
//|ポジションエントリー
//+------------------------------------------------------------------+
bool position_entry(int side)
{
double lot_size = 0.01;
int res = 0;
lot_size = lots_num();
if(position_count(side) > 0)
{
lot_size = calc_martin_lots(side);
}
if(lot_size > 100)
{
lot_size = 99.99;
}
if(side==0)
{
res= OrderSend(NULL,side,lot_size,Ask,0,0,0,"RSI逆張り",magic_number,0);
}
if(side==1)
{
res= OrderSend(NULL,side,lot_size,Bid,0,0,0,"RSI逆張り",magic_number,0);
}
if(res == -1)
{
int error = GetLastError();
if(error==131)
{
Alert("注文時エラー:",Symbol(),"通貨ペアの設定可能なロット数を下回っています。");
}
else
if(error==130)
{
//何もしない
}
else
{
Alert("注文時エラー:",error);
}
Sleep(1000);
Print("注文時エラー:",error,"再試行");
return false;
}
return true;
}
//+------------------------------------------------------------------+
//|ポジションエントリーlimit
//+------------------------------------------------------------------+
bool position_entry_limit(int side,double price)
{
int entry_side = side==OP_BUYLIMIT?0:1;
double lot_size = 0.01;
lot_size = lots_num();
if(position_count(entry_side) > 0)
{
lot_size = calc_martin_lots(entry_side);
}
if(lot_size > 100)
{
lot_size = 99.99;
}
int res= OrderSend(NULL,side,lot_size,price,0,0,0,"RSI逆張り",magic_number,0);
if(res == -1)
{
int error = GetLastError();
if(error==131)
{
Alert("注文時エラー:",Symbol(),"通貨ペアの設定可能なロット数を下回っています。");
}
else
if(error==130)
{
//何もしない
}
else
{
Alert("注文時エラー:",error);
}
Sleep(1000);
Print("注文時エラー:",error,"再試行");
return false;
}
return true;
}
//+------------------------------------------------------------------+
//|ポジション決済
//+------------------------------------------------------------------+
void position_close(int side)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
bool res= OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0, clrBlue);
Sleep(1000);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|ポジションのストップ変更
//+------------------------------------------------------------------+
void position_stop(int side)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
if(OrderStopLoss()==0 && side==0)
{
if(input_songiri_pips <= 0)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),0,0,0);
}
else
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),Close[0] - input_songiri_pips * 10 * _Point,0,0);
}
}
if(OrderStopLoss()==0 && side==1)
{
if(input_songiri_pips <= 0)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),0,0,0);
}
else
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),Close[0] + input_songiri_pips * 10 * _Point,0,0);
}
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|ポジションのストップ変更
//+------------------------------------------------------------------+
void position_modify(int side,double price)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),price,0,0);
Sleep(1000);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|ポジションのリミット変更
//+------------------------------------------------------------------+
void position_modify_limit(int side,double price)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),0,price,0);
Sleep(1000);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|ポジションのSLTP変更
//+------------------------------------------------------------------+
void position_modify_SLTP(int side,double price,double price2)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
bool res=OrderModify(OrderTicket(),OrderOpenPrice(),price,price2,0);
Sleep(1000);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|オーダー変更
//+------------------------------------------------------------------+
void order_modify(int side,double price)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
bool res=OrderModify(OrderTicket(),price,0,0,0);
Sleep(1000);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|オーダー変更limit
//+------------------------------------------------------------------+
void order_modify_limit(int side,double price)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
bool res=OrderModify(OrderTicket(),0,price,0,0);
Sleep(1000);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|注文のキャンセル
//+------------------------------------------------------------------+
void order_all_cancel()
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == 2 || OrderType() == 3 || OrderType() == 4 || OrderType() == 5)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
bool res=OrderDelete(OrderTicket());
Sleep(1000);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|注文のキャンセル
//+------------------------------------------------------------------+
void order_cancel(int side)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
bool res=OrderDelete(OrderTicket());
Sleep(1000);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|ゲットオーダープライス
//+------------------------------------------------------------------+
double get_order_price(int side)
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == side)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
return OrderOpenPrice();
}
}
}
}
}
return 0;
}
//+------------------------------------------------------------------+
//|トレーリングストップ注文
//+------------------------------------------------------------------+
void trailing_stop(double offset)
{
double trailing_stop_price=0;
bool A;
bool B;
//ポジションを調べる
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
//ロングポジション
if(OrderType()==OP_BUY)
{
trailing_stop_price = iClose(NULL,0,0) - offset;
//A ストップが0に設定されている
A = OrderStopLoss() == 0;
//B ストップ+ストップ値幅 < 現在価格
B = (OrderStopLoss() + offset) < iClose(NULL,0,0) - _Point;
//もしも A or B なら
if(A || B)
{
position_modify(OP_BUY,trailing_stop_price);//ポジションのストップ変更
}
}
//ショートポジション
if(OrderType()==OP_SELL)
{
trailing_stop_price = iClose(NULL,0,0) + offset;
//A ストップが0に設定されている
A = OrderStopLoss() == 0;
//B ストップ ー ストップ値幅 > 現在価格
B = (OrderStopLoss() - offset) > iClose(NULL,0,0) + _Point;
//もしも A or B なら
if(A || B)
{
position_modify(OP_SELL,trailing_stop_price);//ポジションのストップ変更
}
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//|トレーリングストップの値幅計算
//+------------------------------------------------------------------+
string toresuto_settei = "";//ーーートレーリングストップの設定ーーー
double toresuto_settei_atai =2.0;//(高値 - 安値)÷【入力値】
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
// 日本時間の取得
datetime getJapanTime()
{
datetime present = TimeCurrent();
datetime summer = present + 60 * 60 * natu;
datetime winter = present + 60 * 60 * huyu;
switch(Year())
{
case 2000:
if(StringToTime("2000.3.12")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2000.11.5"))
return summer;
break;
case 2001:
if(StringToTime("2001.3.11")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2001.11.4"))
return summer;
break;
case 2002:
if(StringToTime("2002.3.10")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2002.11.3"))
return summer;
break;
case 2003:
if(StringToTime("2003.3.9") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2003.11.2"))
return summer;
break;
case 2004:
if(StringToTime("2004.3.14")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2004.11.7"))
return summer;
break;
case 2005:
if(StringToTime("2005.3.13")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2005.11.6"))
return summer;
break;
case 2006:
if(StringToTime("2006.3.12")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2006.11.5"))
return summer;
break;
case 2007:
if(StringToTime("2007.3.11")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2007.11.4"))
return summer;
break;
case 2008:
if(StringToTime("2008.3.9") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2008.11.2"))
return summer;
break;
case 2009:
if(StringToTime("2009.3.8") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2009.11.1"))
return summer;
break;
case 2010:
if(StringToTime("2010.3.14")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2010.11.7"))
return summer;
break;
case 2011:
if(StringToTime("2011.3.13")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2011.11.6"))
return summer;
break;
case 2012:
if(StringToTime("2012.3.11")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2012.11.4"))
return summer;
break;
case 2013:
if(StringToTime("2013.3.10")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2013.11.3"))
return summer;
break;
case 2014:
if(StringToTime("2014.3.9") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2014.11.2"))
return summer;
break;
case 2015:
if(StringToTime("2015.3.8") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2015.11.1"))
return summer;
break;
case 2016:
if(StringToTime("2016.3.13")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2016.11.6"))
return summer;
break;
case 2017:
if(StringToTime("2017.3.12")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2017.11.5"))
return summer;
break;
case 2018:
if(StringToTime("2018.3.11")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2018.11.4"))
return summer;
break;
case 2019:
if(StringToTime("2019.3.10")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2019.11.3"))
return summer;
break;
case 2020:
if(StringToTime("2020.3.8") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2020.11.1"))
return summer;
break;
case 2021:
if(StringToTime("2021.3.14")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2021.11.7"))
return summer;
break;
case 2022:
if(StringToTime("2022.3.13")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2022.11.6"))
return summer;
break;
case 2023:
if(StringToTime("2023.3.12")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2023.11.5"))
return summer;
break;
case 2024:
if(StringToTime("2024.3.10")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2024.11.3"))
return summer;
break;
case 2025:
if(StringToTime("2025.3.9") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2025.11.2"))
return summer;
break;
case 2026:
if(StringToTime("2026.3.8") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2026.11.1"))
return summer;
break;
case 2027:
if(StringToTime("2027.3.14")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2027.11.7"))
return summer;
break;
case 2028:
if(StringToTime("2028.3.12")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2028.11.5"))
return summer;
break;
case 2029:
if(StringToTime("2029.3.11")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2029.11.4"))
return summer;
break;
case 2030:
if(StringToTime("2030.3.10")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2030.11.3"))
return summer;
break;
case 2031:
if(StringToTime("2031.3.9") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2031.11.2"))
return summer;
break;
case 2032:
if(StringToTime("2032.3.14")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2032.11.7"))
return summer;
break;
case 2033:
if(StringToTime("2033.3.13")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2033.11.6"))
return summer;
break;
case 2034:
if(StringToTime("2034.3.12")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2034.11.5"))
return summer;
break;
case 2035:
if(StringToTime("2035.3.11")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2035.11.4"))
return summer;
break;
case 2036:
if(StringToTime("2magic_number.3.9") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2036.11.2"))
return summer;
break;
case 2037:
if(StringToTime("2037.3.8") <=TimeCurrent()&&TimeCurrent()<=StringToTime("2037.11.1"))
return summer;
break;
case 2038:
if(StringToTime("2038.3.14")<=TimeCurrent()&&TimeCurrent()<=StringToTime("2038.11.7"))
return summer;
break;
}
return winter;
}
//+------------------------------------------------------------------+
//| position_close
//+------------------------------------------------------------------+
void position_close(string side)
{
if(side=="buy_close")
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
GetTicketError=false;
}
else
{
GetTicketError=true;
}
if(OrderType() == OP_BUY)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
if(((supu * _Point) > (Ask - Bid)) || (supu == 0))
{
bool cl = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, clrBlue);
}
}
}
}
}
}
if(side=="sell_close")
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
GetTicketError=false;
}
else
{
GetTicketError=true;
}
if(OrderType() == OP_SELL)
{
if(OrderSymbol()==Symbol())
{
if(OrderMagicNumber()==magic_number)
{
if(((supu * _Point) > (Ask - Bid)) || (supu == 0))
{
bool cl = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, clrBlue);
}
}
}
}
}
}
}
input string doyoubi_settei = "";//ーーー土曜日の強制決済の設定ーーー
input bool input_doyoubi_close = true;//土日前に強制決済
input int close_time = 5;//土曜日の強制決済時間
bool is_close_time()
{
datetime pc_time = calculate_time();
int day = TimeDay(pc_time);
int youbi = TimeDayOfWeek(pc_time);
int hour = TimeHour(pc_time);
if(youbi!=SATURDAY)
{
return false;
}
if(youbi==SATURDAY)
{
if(close_time <= hour)
{
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
datetime calculate_time()
{
if(set_time == GMT9)
{
return TimeGMT() + 60 * 60 * 9;
}
if(set_time == GMT9_BACKTEST)
{
return getJapanTime();
}
if(set_time == GMT_KOTEI)
{
return TimeCurrent() + 60 * 60 * 9;
}
return 0;
}
//+------------------------------------------------------------------+
void create_label()
{
string obj_name = "ea_name";
int chart_id = 0;
// オブジェクト全削除
ObjectCreate(chart_id,obj_name, // オブジェクト作成
OBJ_LABEL, // オブジェクトタイプ
0, // サブウインドウ番号
0, // 1番目の時間のアンカーポイント
0 // 1番目の価格のアンカーポイント
);
ObjectSetInteger(chart_id,obj_name,OBJPROP_COLOR,clrWhite); // 色設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_BACK,false); // オブジェクトの背景表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTABLE,false); // オブジェクトの選択可否設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTED,false); // オブジェクトの選択状態
ObjectSetInteger(chart_id,obj_name,OBJPROP_HIDDEN,true); // オブジェクトリスト表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_ZORDER,0); // オブジェクトのチャートクリックイベント優先順位
// 角度
string txt = "RSI逆張りEA";
ObjectSetString(chart_id,obj_name,OBJPROP_TEXT,txt); // 表示するテキスト
ObjectSetString(chart_id,obj_name,OBJPROP_FONT,"MS ゴシック"); // フォント
ObjectSetInteger(chart_id,obj_name,OBJPROP_FONTSIZE,14); // フォントサイズ
ObjectSetInteger(chart_id,obj_name,OBJPROP_CORNER,CORNER_LEFT_UPPER); // コーナーアンカー設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_XDISTANCE,10); // X座標
ObjectSetInteger(chart_id,obj_name,OBJPROP_YDISTANCE,30); // Y座標
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void create_label2()
{
string obj_name = "lot_mode";
int chart_id = 0;
ObjectCreate(chart_id,obj_name, // オブジェクト作成
OBJ_LABEL, // オブジェクトタイプ
0, // サブウインドウ番号
0, // 1番目の時間のアンカーポイント
0 // 1番目の価格のアンカーポイント
);
ObjectSetInteger(chart_id,obj_name,OBJPROP_COLOR,clrWhite); // 色設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_BACK,false); // オブジェクトの背景表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTABLE,false); // オブジェクトの選択可否設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTED,false); // オブジェクトの選択状態
ObjectSetInteger(chart_id,obj_name,OBJPROP_HIDDEN,true); // オブジェクトリスト表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_ZORDER,0); // オブジェクトのチャートクリックイベント優先順位
// 角度
string txt = "";
string lot_txt =DoubleToStr(lots_num(),2);;
if(lots_houhou==0)
{
txt = "LOT MODE : 固定LOT " + lot_txt;
}
if(lots_houhou==1)
{
txt = "LOT MODE : 複利 "+ lot_txt;
}
if(lots_houhou==2)
{
txt = "LOT MODE : 固定+取り戻し "+ lot_txt;
}
if(lots_houhou==3)
{
txt = "LOT MODE : 複利+取り戻し "+ lot_txt;
}
ObjectSetString(chart_id,obj_name,OBJPROP_TEXT,txt); // 表示するテキスト
ObjectSetString(chart_id,obj_name,OBJPROP_FONT,"MS ゴシック"); // フォント
ObjectSetInteger(chart_id,obj_name,OBJPROP_FONTSIZE,14); // フォントサイズ
ObjectSetInteger(chart_id,obj_name,OBJPROP_CORNER,CORNER_LEFT_UPPER); // コーナーアンカー設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_XDISTANCE,10); // X座標
ObjectSetInteger(chart_id,obj_name,OBJPROP_YDISTANCE,55); // Y座標
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void create_label3()
{
string obj_name = "entry_mode";
int chart_id = 0;
// オブジェクト全削除
ObjectCreate(chart_id,obj_name, // オブジェクト作成
OBJ_LABEL, // オブジェクトタイプ
0, // サブウインドウ番号
0, // 1番目の時間のアンカーポイント
0 // 1番目の価格のアンカーポイント
);
ObjectSetInteger(chart_id,obj_name,OBJPROP_COLOR,clrWhite); // 色設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_BACK,false); // オブジェクトの背景表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTABLE,false); // オブジェクトの選択可否設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTED,false); // オブジェクトの選択状態
ObjectSetInteger(chart_id,obj_name,OBJPROP_HIDDEN,true); // オブジェクトリスト表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_ZORDER,0); // オブジェクトのチャートクリックイベント優先順位
// 角度
string txt = input_entry_mode==0?"ENTRY MODE : NORMAL":"ENTRY MODE : HYPER";
ObjectSetString(chart_id,obj_name,OBJPROP_TEXT,txt); // 表示するテキスト
ObjectSetString(chart_id,obj_name,OBJPROP_FONT,"MS ゴシック"); // フォント
ObjectSetInteger(chart_id,obj_name,OBJPROP_FONTSIZE,14); // フォントサイズ
ObjectSetInteger(chart_id,obj_name,OBJPROP_CORNER,CORNER_LEFT_UPPER); // コーナーアンカー設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_XDISTANCE,10); // X座標
ObjectSetInteger(chart_id,obj_name,OBJPROP_YDISTANCE,80); // Y座標
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void create_label4()
{
string obj_name = "doniti";
int chart_id = 0;
// オブジェクト全削除
ObjectCreate(chart_id,obj_name, // オブジェクト作成
OBJ_LABEL, // オブジェクトタイプ
0, // サブウインドウ番号
0, // 1番目の時間のアンカーポイント
0 // 1番目の価格のアンカーポイント
);
ObjectSetInteger(chart_id,obj_name,OBJPROP_COLOR,clrWhite); // 色設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_BACK,false); // オブジェクトの背景表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTABLE,false); // オブジェクトの選択可否設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTED,false); // オブジェクトの選択状態
ObjectSetInteger(chart_id,obj_name,OBJPROP_HIDDEN,true); // オブジェクトリスト表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_ZORDER,0); // オブジェクトのチャートクリックイベント優先順位
// 角度
string txt = input_doyoubi_close==True?"土日決済 : ON":"土日決済 : OFF";
ObjectSetString(chart_id,obj_name,OBJPROP_TEXT,txt); // 表示するテキスト
ObjectSetString(chart_id,obj_name,OBJPROP_FONT,"MS ゴシック"); // フォント
ObjectSetInteger(chart_id,obj_name,OBJPROP_FONTSIZE,14); // フォントサイズ
ObjectSetInteger(chart_id,obj_name,OBJPROP_CORNER,CORNER_LEFT_UPPER); // コーナーアンカー設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_XDISTANCE,10); // X座標
ObjectSetInteger(chart_id,obj_name,OBJPROP_YDISTANCE,105); // Y座標
}
//+------------------------------------------------------------------+
//| ロット数 |
//+------------------------------------------------------------------+
double dd = 0;
double max_syoukokin = 0;
double now_syoukokin = 0;
double lots_num()
{
double lots_keisan_siki = calc_lot_size / syoukokin;
double drawdown_keisan_siki = drawdown_lot_size / drawdown_num;
if(lots_houhou==KOTEI)
{
return ilots;
}
if(lots_houhou==HENDOU)
{
if(syoukokin>AccountEquity())
{
return ilots;
}
return RoundUp(AccountEquity() * lots_keisan_siki,3);
}
if(lots_houhou==TORIMODOSI)
{
double n = max_syoukokin - now_syoukokin;
return ilots + RoundUp(n * drawdown_keisan_siki,3);
}
if(lots_houhou==HENDOUTORIMODOSI)
{
if(syoukokin>AccountEquity())
{
return ilots;
}
double n = max_syoukokin - now_syoukokin;
return RoundUp(AccountEquity() * lots_keisan_siki,3) + RoundUp(n * drawdown_keisan_siki,3);
}
return ilots;
}
//+------------------------------------------------------------------+
//| Function: round up |
//+------------------------------------------------------------------+
double RoundUp(double val, int digit)
{
double adjust = (val >= 0)? 0.9 : -0.9;
return ((double)(int)(val * MathPow(10, digit) + adjust)) / MathPow(10, digit);
}
//エントリーのinterval
//グローバルスコープ変数
bool entry_on = false;
int entry_on_num = 0;
void entry_switch(int buy_position_count,int sell_position_count)
{
static int prev_buy_position_count = 0;
static int prev_sell_position_count = 0;
static datetime prev_time = iTime(NULL,0,0);
if(prev_buy_position_count != buy_position_count || prev_sell_position_count != sell_position_count)
{
entry_on = false;
entry_on_num = input_entry_interval;
}
prev_buy_position_count = buy_position_count;
prev_sell_position_count = sell_position_count;
if(prev_time != iTime(NULL,0,0))
{
prev_time = iTime(NULL,0,0);
if(entry_on_num > 0)
{
entry_on_num = entry_on_num - 1;
}
else
if(entry_on_num <= 0)
{
entry_on = true;
}
}
}
//+------------------------------------------------------------------+
EAのダウンロード
ここから先は
0字
![](https://assets.st-note.com/production/uploads/images/71149891/profile_b8c50857341c8c1f4490cb8d0c98a074.jpg?fit=bounds&format=jpeg&quality=85&width=330)
このマガジンで読み放題です。
FX自動売買開発入門サンプルコードセット
10,000円
EA開発者のためのサンプルコード集
この記事が気に入ったらサポートをしてみませんか?