Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #property copyright "2024, (c)hyrolean"
- #property link "https://pastebin.com/dJRkQMJp"
- #property version "1.09"
- #property strict
- //順張りピラミッティングするEAのサンプル
- //ver1.09
- //・常に利確出来る位置にピラミッテングを行う PyramidingKeepBorder オプションを追加
- //ver1.08
- //・デバッグ情報を表示するサンプル DEBUG MODE 機能を追加
- //ver1.07
- //・最後に利確または損切した金額をチャートに表示したままにしておく仕様に変更
- //ver1.06
- //・タイムコントロールのベース時間を"GMT/Local/Server"から選んで切替られる TimeBase オプションを追加
- //ver1.05
- //・TimeAction の Close All Positions 系の処理の動作が上手く働いていなかったバグを修正
- //ver1.04
- //・活動時間を制御するタイムコントロール機能を追加
- //ver1.03
- //・PyramidingScaleに1.0よりも大きい値を設定するとピラミッティングしないバグを修正
- //・自動注文 2RSI Detector 機能を追加
- //ver1.02
- //・MoveStoploss有効時にショートしか機能が働かなくなっていたバグを修正
- //ver1.01
- //・MoveStoploss有効時に機能がまったく働かなくなっていたバグを修正
- /*
- このEAを、指標で使う場合には、以下のように設定してください。
- 1) Active Entry Positions を Stop にします。EAの自動ポジション打ちを止めることができます。
- 2) Auto Move stop loss to safe position を false にして、sl値の自動更新を止めます。
- 3) Pyramiding lots Multiplier を 1.0 より多少大きな値にします。
- 次に、左上の|SELL|BUY|ボタンを選んでポジションを自分で打ちます。
- ポジションを打ったら、sl(ストップロス)のBARを自分の好みの場所に移動させます。
- 以降、ピラミッティングのslはこのsl値の位置に統一されて張られていきます。
- 指標の動きが止まったら、|CLOSE ALL|で利確すれば完了です。
- tpの値の計算式は、PyramidingStrideが40、PyramidingTimesが20、Takeprofitの値が100の場合、
- tp=40*20+100=900points(90.0pips)になります。自動利確を的確に予測して確実のものとするには、
- この計算式を参考にしてください。(PyramidingStrideが40だからといって、必ず40pointsごとに
- ピラミッティグされるのではなく、タイミングがズレるとマージン(空き)が発生します。実際には90pipsよりも
- 上の値にtpが来ることになります。)
- */
- enum ENUM_POSI {
- POSI_STOP, // Stop
- POSI_LONG_ONLY, // Only Long
- POSI_SHORT_ONLY, // Only Short
- POSI_HALF_LONG_AND_SHORT, // Long & Short (Half duplex)
- POSI_FULL_LONG_AND_SHORT // Long & Short (Full duplex)
- };
- enum ENUM_TIMEBASE {
- TIMEBASE_GMT, // Greenwich Mean Time (GMT)
- TIMEBASE_LOCAL, // Local Time
- TIMEBASE_SERVER // Server Time
- };
- enum ENUM_TIMEACT {
- TIMEACT_NONE, // None
- TIMEACT_FORCE_CLOSE_ALL, // Force Close All positions
- TIMEACT_FORCE_CLOSE_LONG, // Force Close Long positions
- TIMEACT_FORCE_CLOSE_SHORT, // Force Close Short positions
- TIMEACT_SOFT_CLOSE_ALL, // Close All positions if profits are Positive
- TIMEACT_SOFT_CLOSE_LONG, // Close Long positions if profits are Positive
- TIMEACT_SOFT_CLOSE_SHORT // Close Short positions if profits are Positive
- };
- input ENUM_POSI ActivePositions = POSI_FULL_LONG_AND_SHORT; // Active Entry Positions
- input int MAGICMA = 35853; // Magic Number
- input bool TimeControl = false; // Time Control
- input ENUM_TIMEBASE TimeBase = TIMEBASE_LOCAL; // Time Base
- input string TimeStart = "09:00"; // Time Start
- input string TimeEnd = "15:00"; // Time End
- input ENUM_TIMEACT TimeAction = TIMEACT_NONE; // Time Action when time end reached
- input int Slippage = 10; // Max slippage
- input double Spread = 50; // Max spread in points
- input double BaseLots = 0.06; // Base lots
- input double MinLots = 0.01; // Minimum lots
- input double MaxLots = 1000.0; // Maximum lots
- input double Takeprofit = 100; // Take profit in points
- input double Stoploss = 500; // Stop loss in points
- input double ProfitRatePer = 50.0; // Profit Rate in percentage
- input bool MoveStoploss = true; // Auto Move stop loss to safe position
- input double StoplossPadding = 100.0; // Auto move stop loss safe Padding in points
- input double PyramidingStride= 40.0; // Pyramiding price Stride in points
- input double PyramidingScale = 0.9; // Pyramiding lots Multiplier
- input int PyramidingTimes = 20; // Pyramiding max Positions (0=infinite)
- input int PyramidingInterval=0; // Pyramiding Interval in sec (0=continuous)
- input bool PyramidingKeepBorder=false;// Pyramiding to Keep Border of over profit+padding
- input bool RSI2Detector = true; // Detector 2RSI Enabled
- input ENUM_TIMEFRAMES RSI2TimeFrame=PERIOD_M5; // Detector 2RSI Time Frame
- input int RSI2FastPeriod = 13; // Detector 2RSI Fast period
- input int RSI2SlowPeriod = 42; // Detector 2RSI Slow period
- input int RSI2Duration = 5; // Detector 2RSI Duration
- input double RSI2Distance = 20; // Detector 2RSI Distance
- input double RSI2UpBorder = 90; // Detector 2RSI Up border
- input double RSI2DownBorder = 10; // Detector 2RSI Down border
- input ENUM_APPLIED_PRICE RSI2PriceType = PRICE_CLOSE; // Detector 2RSI Price type
- input bool ShowUserEntry = true; // Show user entry SELL/BUY buttons
- input bool ShowCloseAll = true; // Show a CLOSE ALL button
- input bool ShowCloseLong = false; // Show a CLOSE LONG button
- input bool ShowCloseShort = false; // Show a CLOSE SHORT button
- input bool ShowAmount = true; // Show Current Amount
- input int AmountDig = 0; // Amount Number of decimal places
- input bool DBGMODE = false; // DEBUG MODE
- double Lots;
- bool PmdTiming=false;
- datetime CurTime, CurPmdInt, TimeTick, StartTime, CancelTime, UserTime;
- #define ORDER_RETRY 10
- #define FLAG_BUY 1
- #define FLAG_SELL 2
- #define FLAG_DUPLEX 4
- int PositionFlag = FLAG_BUY | FLAG_SELL | FLAG_DUPLEX ;
- int UserEntry = 0 ;
- #define SELLBTN_NAME "EntrySell"
- #define BUYBTN_NAME "EntryBuy"
- #define CLOSEALLBTN_NAME "CloseAll"
- #define CLOSELONGBTN_NAME "CloseLong"
- #define CLOSESHORTBTN_NAME "CloseShort"
- #define BUYBORDER_NAME "LONG BORDER"
- #define SELLBORDER_NAME "SHORT BORDER"
- bool BuyBorderLined = false, SellBorderLined = false ;
- #define OFFTIME_NAME "OFF TIME"
- bool OffTimeVisible = false ;
- #define AMOUNT_NAME "AMOUNT"
- #define AMOUNT_CLR_NEGA clrLightPink
- #define AMOUNT_CLR_POSI clrLightGoldenrod
- #define DBGINFO_NAME "DEBUG INFO"
- //---------------------------------------------------------------------------
- int OnInit()
- {
- CurTime = Time[0];
- CurPmdInt = TimeTick = CancelTime = StartTime = UserTime = BaseTime();
- Lots = BaseLots ;
- if(Lots<MinLots) Lots = MinLots ;
- if(Lots>MaxLots) Lots = MaxLots ;
- DeleteBorderLines() ;
- DrawBorderLine(OP_BUY);
- DrawBorderLine(OP_SELL);
- // エントリできるポジションの確認
- switch(ActivePositions) {
- case POSI_STOP: // Stop
- PositionFlag = 0 ;
- break;
- case POSI_LONG_ONLY: // Only Long
- PositionFlag = FLAG_BUY ;
- break;
- case POSI_SHORT_ONLY: // Only Short
- PositionFlag = FLAG_SELL ;
- break;
- case POSI_HALF_LONG_AND_SHORT: // Long & Short (Half Duplex)
- PositionFlag = FLAG_BUY | FLAG_SELL ;
- break;
- case POSI_FULL_LONG_AND_SHORT: // Long & Short (Full Duplex)
- PositionFlag = FLAG_BUY | FLAG_SELL | FLAG_DUPLEX ;
- break;
- }
- //DEBUG INFO
- if(DBGMODE) {
- ObjectCreate(DBGINFO_NAME, OBJ_LABEL, 0, 0, 0);
- ObjectSet(DBGINFO_NAME, OBJPROP_XDISTANCE, 10);
- ObjectSet(DBGINFO_NAME, OBJPROP_YDISTANCE, 15);
- ObjectSet(DBGINFO_NAME, OBJPROP_CORNER, 3);
- ObjectSetString(0, DBGINFO_NAME, OBJPROP_TEXT, "DEBUG INFO");
- ObjectSetString(0, DBGINFO_NAME, OBJPROP_FONT, "Verdana");
- ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_FONTSIZE, 8);
- ObjectSetInteger(0, DBGINFO_NAME, OBJPROP_COLOR, clrAquamarine);
- }
- //金額表示
- if(ShowAmount) {
- ObjectCreate(AMOUNT_NAME, OBJ_LABEL, 0, 0, 0);
- ObjectSet(AMOUNT_NAME, OBJPROP_XDISTANCE, 20);
- ObjectSet(AMOUNT_NAME, OBJPROP_YDISTANCE, 35);
- ObjectSet(AMOUNT_NAME, OBJPROP_CORNER, 3);
- ObjectSetString(0, AMOUNT_NAME, OBJPROP_TEXT, "0-");
- ObjectSetString(0, AMOUNT_NAME, OBJPROP_FONT, "Verdana");
- ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_FONTSIZE, 15);
- ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_COLOR, AMOUNT_CLR_POSI);
- }
- //ユーザーエントリ用ボタン
- if(ShowUserEntry) {
- //SELLボタン
- ObjectCreate(SELLBTN_NAME, OBJ_BUTTON, 0, 0, 0);
- ObjectSet(SELLBTN_NAME, OBJPROP_XDISTANCE, 10);
- ObjectSet(SELLBTN_NAME, OBJPROP_YDISTANCE, 20);
- ObjectSet(SELLBTN_NAME, OBJPROP_XSIZE, 58);
- ObjectSet(SELLBTN_NAME, OBJPROP_YSIZE, 32);
- ObjectSet(SELLBTN_NAME, OBJPROP_CORNER, 0);
- ObjectSet(SELLBTN_NAME, OBJPROP_FONTSIZE, 12);
- ObjectSet(SELLBTN_NAME, OBJPROP_COLOR, White);
- ObjectSet(SELLBTN_NAME, OBJPROP_BGCOLOR, clrFireBrick);
- ObjectSetString(0, SELLBTN_NAME, OBJPROP_TEXT, "SELL");
- ObjectSetString(0, SELLBTN_NAME, OBJPROP_FONT, "Verdana");
- //BUYボタン
- ObjectCreate(BUYBTN_NAME, OBJ_BUTTON, 0, 0, 0);
- ObjectSet(BUYBTN_NAME, OBJPROP_XDISTANCE, 70);
- ObjectSet(BUYBTN_NAME, OBJPROP_YDISTANCE, 20);
- ObjectSet(BUYBTN_NAME, OBJPROP_XSIZE, 58);
- ObjectSet(BUYBTN_NAME, OBJPROP_YSIZE, 32);
- ObjectSet(BUYBTN_NAME, OBJPROP_CORNER, 0);
- ObjectSet(BUYBTN_NAME, OBJPROP_FONTSIZE, 12);
- ObjectSet(BUYBTN_NAME, OBJPROP_COLOR, White);
- ObjectSet(BUYBTN_NAME, OBJPROP_BGCOLOR, clrRoyalBlue);
- ObjectSetString(0, BUYBTN_NAME, OBJPROP_TEXT, "BUY");
- ObjectSetString(0, BUYBTN_NAME, OBJPROP_FONT, "Verdana");
- }
- int btn_ofs_x = 0 ;
- const int btn_distance = 102 ;
- //全決済ボタン
- if(ShowCloseAll) {
- ObjectCreate(CLOSEALLBTN_NAME, OBJ_BUTTON, 0, 0, 0);
- ObjectSet(CLOSEALLBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x );
- ObjectSet(CLOSEALLBTN_NAME, OBJPROP_YDISTANCE, 35);
- ObjectSet(CLOSEALLBTN_NAME, OBJPROP_XSIZE, 100);
- ObjectSet(CLOSEALLBTN_NAME, OBJPROP_YSIZE, 25);
- ObjectSet(CLOSEALLBTN_NAME, OBJPROP_CORNER, 2);
- ObjectSet(CLOSEALLBTN_NAME, OBJPROP_FONTSIZE, 10);
- ObjectSet(CLOSEALLBTN_NAME, OBJPROP_COLOR, White);
- ObjectSet(CLOSEALLBTN_NAME, OBJPROP_BGCOLOR, /*clrDarkGreen*/clrDarkSlateGray);
- ObjectSetString(0, CLOSEALLBTN_NAME, OBJPROP_TEXT, "CLOSE ALL");
- ObjectSetString(0, CLOSEALLBTN_NAME, OBJPROP_FONT, "Verdana");
- btn_ofs_x += btn_distance ;
- }
- //LONG決済ボタン
- if(ShowCloseLong) {
- ObjectCreate(CLOSELONGBTN_NAME, OBJ_BUTTON, 0, 0, 0);
- ObjectSet(CLOSELONGBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x );
- ObjectSet(CLOSELONGBTN_NAME, OBJPROP_YDISTANCE, 35);
- ObjectSet(CLOSELONGBTN_NAME, OBJPROP_XSIZE, 100);
- ObjectSet(CLOSELONGBTN_NAME, OBJPROP_YSIZE, 25);
- ObjectSet(CLOSELONGBTN_NAME, OBJPROP_CORNER, 2);
- ObjectSet(CLOSELONGBTN_NAME, OBJPROP_FONTSIZE, 10);
- ObjectSet(CLOSELONGBTN_NAME, OBJPROP_COLOR, White);
- ObjectSet(CLOSELONGBTN_NAME, OBJPROP_BGCOLOR, clrRoyalBlue);
- ObjectSetString(0, CLOSELONGBTN_NAME, OBJPROP_TEXT, "CLOSE LONG");
- ObjectSetString(0, CLOSELONGBTN_NAME, OBJPROP_FONT, "Verdana");
- btn_ofs_x += btn_distance ;
- }
- //SHORT決済ボタン
- if(ShowCloseShort) {
- ObjectCreate(CLOSESHORTBTN_NAME, OBJ_BUTTON, 0, 0, 0);
- ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x );
- ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_YDISTANCE, 35);
- ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_XSIZE, 100);
- ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_YSIZE, 25);
- ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_CORNER, 2);
- ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_FONTSIZE, 10);
- ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_COLOR, White);
- ObjectSet(CLOSESHORTBTN_NAME, OBJPROP_BGCOLOR, clrFireBrick);
- ObjectSetString(0, CLOSESHORTBTN_NAME, OBJPROP_TEXT, "CLOSE SHORT");
- ObjectSetString(0, CLOSESHORTBTN_NAME, OBJPROP_FONT, "Verdana");
- btn_ofs_x += btn_distance ;
- }
- //ユーザーエントリをリセット
- UserEntry=0;
- return(INIT_SUCCEEDED);
- }
- //---------------------------------------------------------------------------
- void OnDeinit(const int reason)
- {
- if(ShowCloseShort) ObjectDelete(CLOSESHORTBTN_NAME) ;
- if(ShowCloseLong) ObjectDelete(CLOSELONGBTN_NAME) ;
- if(ShowCloseAll) ObjectDelete(CLOSEALLBTN_NAME) ;
- if(ShowUserEntry) {
- ObjectDelete(BUYBTN_NAME) ;
- ObjectDelete(SELLBTN_NAME) ;
- }
- if(OffTimeVisible) {
- ObjectDelete(OFFTIME_NAME) ;
- OffTimeVisible=false ;
- }
- if(ShowAmount) {
- ObjectDelete(AMOUNT_NAME) ;
- }
- if(DBGMODE) {
- ObjectDelete(DBGINFO_NAME) ;
- }
- DeleteBorderLines() ;
- }
- //---------------------------------------------------------------------------
- void OnTick()
- {
- datetime nextTime = Time[0] ;
- bool nextTimed = nextTime != CurTime ;
- CurTime = nextTime ;
- datetime nextTick = BaseTime() ;
- bool nextTicked = nextTick != TimeTick ;
- TimeTick = nextTick;
- // タイムコントロールチェック
- CheckTimeControl(nextTicked);
- // 動作チェック
- CheckBehavior(nextTimed);
- // デバッグ欄表示のサンプル
- if(DBGMODE) {
- double atr14 = iATR(NULL,0,14,0) ;
- double spread = Ask-Bid ;
- DBGOUT(
- // ATR in points
- StringFormat("ATR(14): %.3f",atr14/Point) + " | " +
- // SPREAD in points
- StringFormat("SPREAD: %g",spread/Point) + " | " +
- // 現在の値幅の変動倍率(ATR/SPREAD)
- StringFormat("ATR(14)/SPREAD: %.3f",atr14/spread)
- );
- }
- // エントリー処理
- int busy = AlreadyOrdered(FLAG_BUY|FLAG_SELL,MAGICMA) ;
- // ユーザーの注文
- if(UserEntry) {
- // ユーザーのエントリを確認
- if(TimeTick-UserTime<60) { // 発行されてから60秒以内の注文
- int user = UserEntry ;
- // 注文
- if(user&&!AlreadyOrdered(user,MAGICMA)) {
- int entry = user == FLAG_BUY ? OP_BUY : OP_SELL ;
- EntryPosition("USER", entry, Lots);
- busy |= user;
- }
- }
- UserEntry=0;
- }
- // 自動注文 開始時間調整
- if(StartTime>TimeTick||CancelTime>TimeTick)
- return ;
- // 自動注文 2RSI Detector
- if(RSI2Detector) EAEntryPosition("2RSI", CheckDetectorRSI2(), busy);
- }
- //---------------------------------------------------------------------------
- void OnChartEvent(
- const int id,
- const long &lparam,
- const double &dparam,
- const string &sparam
- )
- {
- if( ( sparam == CLOSEALLBTN_NAME ||
- sparam == CLOSELONGBTN_NAME ||
- sparam == CLOSESHORTBTN_NAME ) && id==CHARTEVENT_OBJECT_CLICK) {
- int orderFlag = 0 ;
- if(sparam == CLOSEALLBTN_NAME) orderFlag = FLAG_SELL | FLAG_BUY ;
- else if(sparam == CLOSELONGBTN_NAME) orderFlag = FLAG_BUY ;
- else if(sparam == CLOSESHORTBTN_NAME) orderFlag = FLAG_SELL ;
- CheckoutOrderAll(orderFlag);
- Sleep(100);
- ObjectSet(sparam, OBJPROP_STATE, False);
- // 60秒エントリーを停止する
- CancelTime = TimeTick + 60 ;
- }
- if(sparam == SELLBTN_NAME && id==CHARTEVENT_OBJECT_CLICK) {
- { UserEntry = FLAG_SELL ; CancelTime = UserTime = TimeTick ; CancelTime+=60 ; }
- Sleep(100);
- ObjectSet(SELLBTN_NAME, OBJPROP_STATE, False);
- }
- if(sparam == BUYBTN_NAME && id==CHARTEVENT_OBJECT_CLICK) {
- { UserEntry = FLAG_BUY ; CancelTime = UserTime = TimeTick ; CancelTime+=60 ; }
- Sleep(100);
- ObjectSet(BUYBTN_NAME, OBJPROP_STATE, False);
- }
- }
- //---------------------------------------------------------------------------
- //DBGOUT
- void DBGOUT(string text)
- {
- if(DBGMODE) {
- ObjectSetString(0, DBGINFO_NAME, OBJPROP_TEXT, text);
- }
- }
- //---------------------------------------------------------------------------
- //タイムコントロールチェック
- void CheckTimeControl(bool nextTicked)
- {
- if(!TimeControl) {
- if(OffTimeVisible) {
- ObjectDelete(OFFTIME_NAME);
- OffTimeVisible = false ;
- }
- return ;
- }
- if(!nextTicked) return ;
- datetime timStart = StringToTime(TimeStart);
- datetime timEnd = StringToTime(TimeEnd);
- MqlDateTime mqlTick, mqlStart, mqlEnd ;
- TimeToStruct(TimeTick, mqlTick);
- TimeToStruct(timStart, mqlStart);
- TimeToStruct(timEnd, mqlEnd);
- // 活動時間帯のチェック
- int ct = mqlTick.hour*60 + mqlTick.min ;
- int st = mqlStart.hour*60 + mqlStart.min ;
- int et = mqlEnd.hour*60 + mqlEnd.min ;
- if(et<=st) {
- if(st<=ct) et=24*60;
- if(ct<=et) st=0;
- }
- bool activeTime = st <= ct && ct <= et ;
- bool isActivated = StartTime<TimeTick ;
- // 現在活動時間帯
- if(activeTime) {
- if(!isActivated)
- StartTime = TimeTick ; // 現在時間を開始時間切り上げて完了
- if(OffTimeVisible) {
- ObjectDelete(OFFTIME_NAME);
- OffTimeVisible = false ;
- }
- return ;
- }
- // 活動時間を次の時間にセットする
- MqlDateTime mqlNextStart = mqlTick ;
- mqlNextStart.hour = mqlStart.hour ;
- mqlNextStart.min = mqlStart.min ;
- mqlNextStart.sec = 0 ;
- datetime timNextStart = StructToTime(mqlNextStart) ;
- while(timNextStart<TimeTick) timNextStart += 24*60*60 ;
- StartTime = timNextStart ;
- // 次の開始までの秒数
- datetime timOff = StartTime - TimeTick ;
- if(!OffTimeVisible) {
- // OFF TIME テキストを表示
- ObjectCreate(OFFTIME_NAME, OBJ_LABEL, 0, 0, 0);
- ObjectSet(OFFTIME_NAME, OBJPROP_XDISTANCE, 10);
- ObjectSet(OFFTIME_NAME, OBJPROP_YDISTANCE, 25);
- ObjectSet(OFFTIME_NAME, OBJPROP_CORNER, 1);
- ObjectSetString(0, OFFTIME_NAME, OBJPROP_TEXT, "OFF TIME");
- ObjectSetString(0, OFFTIME_NAME, OBJPROP_FONT, "Verdana");
- ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_FONTSIZE, 8);
- ObjectSetInteger(0, OFFTIME_NAME, OBJPROP_COLOR, clrYellow);
- OffTimeVisible = true ;
- }
- int orderFlag = AlreadyOrdered(FLAG_SELL|FLAG_BUY,MAGICMA);
- switch(TimeAction) {
- case TIMEACT_NONE:
- // None
- break;
- case TIMEACT_FORCE_CLOSE_ALL:
- // Force Close All positions
- if(orderFlag!=0)
- CheckoutOrderAll(orderFlag);
- break;
- case TIMEACT_FORCE_CLOSE_LONG:
- // Force Close Long positions
- if((orderFlag&FLAG_BUY)!=0)
- CheckoutOrderAll(FLAG_BUY);
- break;
- case TIMEACT_FORCE_CLOSE_SHORT:
- // Force Close Short positions
- if((orderFlag&FLAG_SELL)!=0)
- CheckoutOrderAll(FLAG_SELL);
- break;
- case TIMEACT_SOFT_CLOSE_ALL:
- // Close All positions if profits are Positive
- if(orderFlag!=0) {
- STATUS status_long, status_short;
- CheckStatus(OP_BUY,MAGICMA,status_long);
- CheckStatus(OP_SELL,MAGICMA,status_short);
- double total = status_long.GrossProfit+status_short.GrossProfit ;
- if(total>0) {
- CheckoutOrderAll(orderFlag);
- }
- }
- break;
- case TIMEACT_SOFT_CLOSE_LONG:
- // Close Long positions if profits are Positive
- if((orderFlag&FLAG_BUY)!=0) {
- STATUS status_long;
- CheckStatus(OP_BUY,MAGICMA,status_long);
- double total=status_long.GrossProfit;
- if(total>0) {
- CheckoutOrderAll(FLAG_BUY);
- }
- }
- break;
- case TIMEACT_SOFT_CLOSE_SHORT:
- // Close Short positions if profits are Positive
- if((orderFlag&FLAG_SELL)!=0) {
- STATUS status_short;
- CheckStatus(OP_SELL,MAGICMA,status_short);
- double total=status_short.GrossProfit;
- if(total>0) {
- CheckoutOrderAll(FLAG_SELL);
- }
- }
- break;
- }
- }
- //---------------------------------------------------------------------------
- //タイムコントロールの基軸時間を返す
- datetime BaseTime()
- {
- switch(TimeBase) {
- case TIMEBASE_GMT: // Greenwich Mean Time (GMT)
- return TimeGMT();
- case TIMEBASE_LOCAL: // Local Time
- return TimeLocal();
- case TIMEBASE_SERVER: // Server Time
- return TimeCurrent();
- }
- return 0;
- }
- //---------------------------------------------------------------------------
- //注文のタイミング検出のサンプル: 2RSI (池辺雪子流手法)
- int CheckDetectorRSI2()
- {
- double RSI2Fast0 = iRSI(Symbol(), RSI2TimeFrame, RSI2FastPeriod, RSI2PriceType, 0);
- double RSI2Slow0 = iRSI(Symbol(), RSI2TimeFrame, RSI2SlowPeriod, RSI2PriceType, 0);
- if(RSI2Fast0-RSI2Slow0 >= RSI2Distance && RSI2Fast0 <= RSI2UpBorder ) {
- bool valid = true ;
- double r1 = RSI2Slow0;
- for(int i=1;i<=RSI2Duration;i++) {
- double r2 = iRSI(Symbol(), RSI2TimeFrame, RSI2SlowPeriod, RSI2PriceType, i) ;
- if(r1<r2) { valid = false ; break ; }
- r1=r2 ;
- }
- if(valid) return FLAG_SELL ; // 逆張りの売りタイミング
- }
- if(RSI2Slow0-RSI2Fast0 >= RSI2Distance && RSI2Fast0 >= RSI2DownBorder ) {
- bool valid = true ;
- double r1 = RSI2Slow0;
- for(int i=1;i<=RSI2Duration;i++) {
- double r2 = iRSI(Symbol(), RSI2TimeFrame, RSI2SlowPeriod, RSI2PriceType, i) ;
- if(r1>r2) { valid = false ; break ; }
- r1=r2 ;
- }
- if(valid) return FLAG_BUY ; // 逆張りの買いタイミング
- }
- return 0;
- }
- //---------------------------------------------------------------------------
- //金額表示の更新
- void UpdateAmount(double amount, int positions)
- {
- if(ShowAmount) {
- if(positions>0) {
- string s = DoubleToStr(amount,AmountDig) ;
- if(amount>0) s = "+" + s ;
- ObjectSetString(0, AMOUNT_NAME, OBJPROP_TEXT, s);
- if(amount<0)
- ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_COLOR, AMOUNT_CLR_NEGA);
- else
- ObjectSetInteger(0, AMOUNT_NAME, OBJPROP_COLOR, AMOUNT_CLR_POSI);
- }else {
- string s = ObjectGetString(0, AMOUNT_NAME, OBJPROP_TEXT);
- int ln=StringLen(s);
- if(ln>0) {
- if(s[ln-1]!='-')
- ObjectSetString(0, AMOUNT_NAME, OBJPROP_TEXT, s+"-");
- }
- }
- }
- }
- //---------------------------------------------------------------------------
- //状態チェック
- //-----
- struct STATUS {
- int Positions, PyramidPositions;
- double MinPrice, MaxPrice, BorderPrice, ProfitPrice;
- double MinPriceLots, MaxPriceLots;
- double MinPriceProfit, MaxPriceProfit;
- int MinPriceTicket, MaxPriceTicket;
- double MinStoploss, MaxStoploss;
- double MinTakeprofit, MaxTakeprofit;
- double MaxLots, PyramidMaxLots, PyramidMinLots;
- double TotalPrices, TotalLots;
- double GrossProfit;
- double PositiveProfit;
- };
- //-----
- int CheckStatus(int type, int magic, STATUS &status)
- {
- status.Positions = 0 ;
- status.PyramidPositions = 0 ;
- status.MinPrice = DBL_MAX ;
- status.MaxPrice = 0.0 ;
- status.MinPriceLots = 0.0 ;
- status.MaxPriceLots = 0.0 ;
- status.MinPriceProfit = 0.0 ;
- status.MaxPriceProfit = 0.0 ;
- status.MinPriceTicket = 0 ;
- status.MaxPriceTicket = 0 ;
- status.MinStoploss = DBL_MAX ;
- status.MaxStoploss = 0.0 ;
- status.MinTakeprofit = DBL_MAX ;
- status.MaxTakeprofit = 0.0 ;
- status.MaxLots = 0.0 ;
- status.PyramidMinLots = DBL_MAX ;
- status.PyramidMaxLots = 0.0 ;
- status.BorderPrice = 0.0 ;
- status.ProfitPrice = 0.0 ;
- status.GrossProfit = 0.0 ;
- status.PositiveProfit = 0.0 ;
- double totalPrice=0, totalLots=0 ;
- for(int i=OrdersTotal()-1 ; i>=0 ; i--) {
- if( OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() ) {
- if(magic==OrderMagicNumber()) {
- if(type==OrderType()) {
- double orderPrice = OrderOpenPrice();
- double orderStoploss = OrderStopLoss();
- double orderTakeprofit = OrderTakeProfit();
- double orderLots = OrderLots();
- double orderProfit = OrderProfit() ;
- int orderTicket = OrderTicket() ;
- status.GrossProfit += orderProfit;
- if(orderProfit>0.0)
- status.PositiveProfit += orderProfit;
- if(orderPrice<status.MinPrice) {
- status.MinPrice = orderPrice ;
- status.MinPriceLots = orderLots ;
- status.MinPriceProfit = orderProfit ;
- status.MinPriceTicket = orderTicket ;
- }
- if(orderPrice>status.MaxPrice) {
- status.MaxPrice = orderPrice ;
- status.MaxPriceLots = orderLots ;
- status.MaxPriceProfit = orderProfit ;
- status.MaxPriceTicket = orderTicket ;
- }
- if(orderStoploss<status.MinStoploss) status.MinStoploss = orderStoploss;
- if(orderStoploss>status.MaxStoploss) status.MaxStoploss = orderStoploss;
- if(orderTakeprofit<status.MinTakeprofit) status.MinTakeprofit = orderTakeprofit;
- if(orderTakeprofit>status.MaxTakeprofit) status.MaxTakeprofit = orderTakeprofit;
- if(orderLots>status.MaxLots) status.MaxLots = orderLots;
- totalPrice += orderPrice*orderLots ;
- totalLots += orderLots;
- string orderComment = OrderComment();
- if(StringFind(orderComment,"PRMD")>=0) {
- if(orderLots>status.PyramidMaxLots)
- status.PyramidMaxLots = orderLots ;
- if(orderLots<status.PyramidMinLots)
- status.PyramidMinLots = orderLots ;
- status.PyramidPositions++;
- }
- status.Positions++;
- }
- }
- }
- }
- if(!status.PyramidPositions) {
- status.PyramidMaxLots = MaxLots ;
- status.PyramidMinLots = Lots ;
- }
- if(totalLots>0) {
- status.BorderPrice = totalPrice / totalLots ;
- switch(type) {
- case OP_BUY:
- status.ProfitPrice =
- (status.MaxPrice-status.BorderPrice) * (ProfitRatePer / 100.0)
- + status.BorderPrice ;
- break;
- case OP_SELL:
- status.ProfitPrice =
- (status.MinPrice-status.BorderPrice) * (ProfitRatePer / 100.0)
- + status.BorderPrice ;
- break;
- }
- }
- status.TotalPrices = totalPrice ;
- status.TotalLots = totalLots ;
- return status.Positions;
- }
- //---------------------------------------------------------------------------
- //動作チェック
- void CheckBehavior(bool nextTimed)
- {
- // 全体のステータスを取得
- STATUS BuyWholeStatus, SellWholeStatus ;
- CheckStatus(OP_BUY, MAGICMA, BuyWholeStatus);
- CheckStatus(OP_SELL, MAGICMA, SellWholeStatus);
- // 金額を更新
- UpdateAmount(
- BuyWholeStatus.GrossProfit+SellWholeStatus.GrossProfit,
- BuyWholeStatus.Positions+SellWholeStatus.Positions );
- // ボーダーライン更新
- if(!BuyWholeStatus.Positions) {
- if(BuyBorderLined) {
- ObjectDelete(BUYBORDER_NAME);
- BuyBorderLined=false;
- }
- }else if(nextTimed) {
- DrawBorderLine(OP_BUY);
- }
- if(!SellWholeStatus.Positions) {
- if(SellBorderLined) {
- ObjectDelete(SELLBORDER_NAME);
- SellBorderLined=false;
- }
- }else if(nextTimed) {
- DrawBorderLine(OP_SELL);
- }
- // オーダーの処理
- ProcessOrders(OP_BUY, MAGICMA, BuyWholeStatus);
- ProcessOrders(OP_SELL, MAGICMA, SellWholeStatus);
- // タイマー更新
- PmdTiming = false ;
- if(PyramidingInterval<=0) PmdTiming = true ;
- else {
- while(TimeTick-CurPmdInt>=PyramidingInterval) {
- CurPmdInt+=PyramidingInterval ;
- PmdTiming = true ;
- }
- }
- }
- //---------------------------------------------------------------------------
- //ボーダーラインを引く
- void DrawBorderLine(int orderType)
- {
- STATUS status;
- int pos = CheckStatus(orderType, MAGICMA, status);
- switch(orderType) {
- case OP_BUY:
- if(pos) {
- if(!BuyBorderLined) {
- ObjectCreate(BUYBORDER_NAME,OBJ_HLINE,0,0,status.ProfitPrice);
- BuyBorderLined = true ;
- }
- ObjectSet(BUYBORDER_NAME, OBJPROP_STYLE, STYLE_DOT);
- ObjectSet(BUYBORDER_NAME, OBJPROP_COLOR, clrDeepSkyBlue);
- ObjectSet(BUYBORDER_NAME, OBJPROP_PRICE1,status.ProfitPrice);
- }else if(BuyBorderLined) {
- ObjectDelete(BUYBORDER_NAME);
- BuyBorderLined = false ;
- }
- break;
- case OP_SELL:
- if(pos) {
- if(!SellBorderLined) {
- ObjectCreate(SELLBORDER_NAME,OBJ_HLINE,0,0, status.ProfitPrice);
- SellBorderLined = true ;
- }
- ObjectSet(SELLBORDER_NAME, OBJPROP_STYLE, STYLE_DOT);
- ObjectSet(SELLBORDER_NAME, OBJPROP_COLOR, clrViolet);
- ObjectSet(SELLBORDER_NAME, OBJPROP_PRICE1, status.ProfitPrice);
- }else if(SellBorderLined) {
- ObjectDelete(SELLBORDER_NAME);
- SellBorderLined = false ;
- }
- break;
- }
- }
- //---------------------------------------------------------------------------
- //ボーダーラインを消去
- void DeleteBorderLines()
- {
- if(BuyBorderLined) {
- ObjectDelete(BUYBORDER_NAME);
- BuyBorderLined = false ;
- }
- if(SellBorderLined) {
- ObjectDelete(SELLBORDER_NAME);
- SellBorderLined = false ;
- }
- }
- //---------------------------------------------------------------------------
- //オーダーの処理
- void ProcessOrders(int orderType, int magic, const STATUS &status)
- {
- if(status.Positions<=0) return ;
- double borderPrice = status.BorderPrice ;
- double profitPrice = status.ProfitPrice ;
- bool underPrice = false ;
- bool timeLimited = false ;
- switch(orderType) {
- case OP_BUY:
- if(profitPrice>Bid) underPrice = true;
- break;
- case OP_SELL:
- if(profitPrice<Ask) underPrice = true;
- break;
- }
- if(!underPrice) {
- //ピラミッティング
- if(PmdTiming) {
- if(!PyramidingTimes||status.PyramidPositions<PyramidingTimes) {
- bool canPyramid = false ;
- double lots = Lots ;
- int si=0;
- /*
- if(lots<status.PyramidMinLots&&PyramidingScale>1.0) {
- lots = status.PyramidMinLots; si = 1 ;
- }
- if(lots<status.PyramidMaxLots&&PyramidingScale<=1.0) {
- lots = status.PyramidMaxLots; si = 1 ;
- }
- */
- double scale = PyramidingScale;
- for(int i=si;i<=status.PyramidPositions;i++) {
- lots *= scale ;
- if(lots<MinLots) break;
- if(lots>MaxLots) break;
- }
- if(lots<MinLots) lots = MinLots ;
- if(lots>MaxLots) lots = MaxLots ;
- double totalLots = status.TotalLots ;
- double totalPrice = status.TotalPrices ;
- double sl = 0.0, tp =0.0 ;
- switch(orderType) {
- case OP_BUY: {
- if( Ask>=status.MaxPrice+PyramidingStride*Point ) {
- if(PyramidingKeepBorder) {
- double border = (Ask*lots+totalPrice) / (totalLots+lots);
- double profit = (Ask-border)*ProfitRatePer/100.0 + border ;
- if( Ask>=profit+StoplossPadding*Point )
- canPyramid = true ;
- }else
- canPyramid = true ;
- }
- if(canPyramid) {
- sl = Bid - (Stoploss * Point);
- if(MoveStoploss) {
- if(sl<status.MaxStoploss)
- sl = status.MaxStoploss ;
- }else {
- //if(sl>status.MinStoploss)
- sl = status.MinStoploss ;
- }
- if(Takeprofit!=0.0)
- tp = Ask + Takeprofit*Point ;
- }
- break;
- }
- case OP_SELL: {
- if( Bid<=status.MinPrice-PyramidingStride*Point ) {
- if(PyramidingKeepBorder) {
- double border = (Bid*lots+totalPrice) / (totalLots+lots);
- double profit = (Bid-border)*ProfitRatePer/100.0 + border ;
- if( Bid<=profit-StoplossPadding*Point )
- canPyramid = true ;
- }else
- canPyramid = true ;
- }
- if(canPyramid) {
- sl = Ask + (Stoploss * Point);
- if(MoveStoploss) {
- if(sl>status.MinStoploss)
- sl = status.MinStoploss ;
- }else {
- //if(sl<status.MaxStoploss)
- sl = status.MaxStoploss ;
- }
- if(Takeprofit!=0.0)
- tp = Bid - Takeprofit*Point ;
- }
- break;
- }
- }
- if(canPyramid) {
- if(MakeOrder(orderType,lots,sl,tp,"PRMD",magic)) {
- //tp値更新
- UpdateSlTp(orderType,magic,tp);
- //ボーダーライン更新
- DrawBorderLine(orderType);
- }
- }
- }
- }
- }
- if(PmdTiming) {
- if(MoveStoploss) {
- //sl値自動更新
- UpdateSlTp(orderType, magic);
- }
- }
- }
- //---------------------------------------------------------------------------
- bool InnerPoint(double v, double comp) {
- return comp-Point/2.0 < v && v < comp+Point/2.0 ;
- }
- //sl/tpの一括更新
- void UpdateSlTp(int orderType, int magic, double new_tp=0.0)
- {
- STATUS status ;
- //ステータス更新
- if(!CheckStatus(orderType, magic, status)) return ;
- double borderPrice = status.BorderPrice ;
- double profitPrice = status.ProfitPrice ;
- double padding = StoplossPadding*Point ;
- bool overBorder = orderType==OP_BUY ?
- Bid >= borderPrice+padding : borderPrice-padding >= Ask ;
- bool overProfit = orderType==OP_BUY ?
- Bid >= profitPrice+padding : profitPrice-padding >= Ask ;
- if(overBorder&&!overProfit) {
- // padding が borderPrice から profitPrice の範囲内にある
- switch(orderType) {
- case OP_BUY:
- profitPrice = Bid-padding ;
- break;
- case OP_SELL:
- profitPrice = Ask+padding ;
- break;
- }
- overProfit = true ;
- }
- // sl/tp 値をすべて更新する
- for(int i=OrdersTotal()-1 ; i>=0 ; i--) {
- if( OrderSelect(i, SELECT_BY_POS) ) {
- if( OrderSymbol() != Symbol() ) continue ;
- if( magic != OrderMagicNumber() ) continue ;
- if( orderType != OrderType() ) continue ;
- double sl, tp = new_tp ;
- double orderStoploss = OrderStopLoss();
- double orderTakeprofit = OrderTakeProfit();
- if( overProfit && MoveStoploss )
- sl = profitPrice;
- else
- sl = orderStoploss;
- switch(orderType) {
- case OP_BUY:
- if(sl<orderStoploss)
- sl = orderStoploss;
- break;
- case OP_SELL:
- if(sl>orderStoploss)
- sl = orderStoploss;
- break;
- }
- if(new_tp==0.0)
- tp = orderTakeprofit;
- if(InnerPoint(sl,orderStoploss)) sl = orderStoploss ;
- if(InnerPoint(tp,orderTakeprofit)) tp = orderTakeprofit ;
- if(sl!=orderStoploss||tp!=orderTakeprofit) {
- if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp,
- OrderExpiration(), orderType==OP_BUY?clrBlue:clrRed)) {
- Print(GetLastError());
- }
- }
- }
- }
- }
- //---------------------------------------------------------------------------
- //すでに注文済みかどうか
- int AlreadyOrdered(int orderFlag, int magic)
- {
- int flag = 0 ;
- for(int i=OrdersTotal()-1 ; i>=0 ; i--) {
- if( OrderSelect(i, SELECT_BY_POS) ) {
- int orderMagic = OrderMagicNumber() ;
- if( OrderSymbol() == Symbol() && magic==orderMagic ){
- if( OrderType() == OP_BUY && (orderFlag&FLAG_BUY)!=0 ){
- flag |= FLAG_BUY ; if(flag==orderFlag) break;
- }else if( OrderType() == OP_SELL && (orderFlag&FLAG_SELL)!=0 ){
- flag |= FLAG_SELL ; if(flag==orderFlag) break;
- }
- }
- }
- }
- return flag;
- }
- //---------------------------------------------------------------------------
- //EA用ポジションのエントリー
- bool EAEntryPosition(string detector, int orderFlag, int &busy)
- {
- // EAの注文を処理
- if((PositionFlag&orderFlag)!=0&&(busy&orderFlag)==0) {
- if(!busy||(PositionFlag&FLAG_DUPLEX)!=0) {
- int entry = orderFlag == FLAG_BUY ? OP_BUY : OP_SELL ;
- EntryPosition(detector, entry, Lots);
- busy |= orderFlag ;
- return true ;
- }
- }
- return false ;
- }
- //---------------------------------------------------------------------------
- //ポジションのエントリー(注文の発注簡易版)
- bool EntryPosition(string detector, int entryType, double lots, int magic=0, double sl=-1.0, double tp=-1.0)
- {
- switch(entryType) {
- case OP_BUY:
- if(sl<0.0) sl = Bid - (Stoploss * Point);
- if(tp<0.0) {
- tp=0.0;
- if(Takeprofit!=0.0)
- tp = Ask + (Takeprofit * Point);
- }
- break;
- case OP_SELL:
- if(sl<0.0) sl = Ask + (Stoploss * Point);
- if(tp<0.0) {
- tp = 0.0 ;
- if(Takeprofit!=0.0)
- tp = Bid - (Takeprofit * Point);
- }
- break;
- }
- return MakeOrder(entryType,lots,sl,tp,detector,magic) ;
- }
- //---------------------------------------------------------------------------
- //注文の発注
- bool MakeOrder(int entryType, double lots, double sl, double tp, string detector, int magic)
- {
- bool entried=false ;
- for(int retry=0; retry<ORDER_RETRY; retry++) {
- if(MarketInfo(NULL,MODE_SPREAD) > Spread) { Sleep(2000); continue ; }
- double entryPrice = 0.0 ;
- color orderColor = clrNONE;
- switch(entryType) {
- case OP_BUY:
- entryPrice = Ask ;
- orderColor = clrBlue ;
- break;
- case OP_SELL:
- entryPrice = Bid ;
- orderColor = clrRed ;
- break;
- }
- if(!entried) {
- if(MakeOrderSub(entryType,entryPrice,lots,sl,tp,"Pyramid("+detector+")",MAGICMA,orderColor))
- entried = true ;
- }
- if(entried) return true ;
- Sleep(2000);
- }
- return false;
- }
- //---------------------------------------------------------------------------
- //注文発注サブルーチン
- bool MakeOrderSub(int entryType, double entryPrice, double lots, double sl, double tp,
- string comment,int magicNumber,color orderColor)
- {
- int res = OrderSend(
- NULL,
- entryType,
- lots,
- entryPrice,
- Slippage,
- sl,
- tp,
- comment,
- magicNumber,
- 0,
- orderColor
- );
- if(res<0)
- Print(GetLastError());
- return res>=0;
- }
- //---------------------------------------------------------------------------
- //注文の決済
- bool CheckoutOrder( int orderType, int orderTicket, double orderLots)
- {
- for(int retry=0; retry<ORDER_RETRY; retry++) {
- double checkoutPrice = 0.0 ;
- color orderColor = clrNONE ;
- switch(orderType) {
- case OP_BUY:
- checkoutPrice = Bid ;
- orderColor = clrBlue ;
- break;
- case OP_SELL:
- checkoutPrice = Ask ;
- orderColor = clrRed ;
- break;
- }
- if(OrderClose(orderTicket, orderLots, checkoutPrice, Slippage, orderColor))
- return true;
- Sleep(100);
- }
- Print(GetLastError());
- return false ;
- }
- //---------------------------------------------------------------------------
- //注文の全決済
- bool CheckoutOrderAll(int orderFlag)
- {
- bool result = true ;
- for(int i = OrdersTotal() -1; i >= 0; i--){
- if(OrderSelect(i, SELECT_BY_POS)) {
- int magic = OrderMagicNumber();
- int orderType = OrderType() ;
- if( (orderType==OP_BUY&&(orderFlag&FLAG_BUY)!=0) ||
- (orderType==OP_SELL&&(orderFlag&FLAG_SELL)!=0) ) {
- if( OrderSymbol() == Symbol() && magic == MAGICMA ){
- double profit = OrderProfit();
- if(!CheckoutOrder(OrderType(),OrderTicket(),OrderLots())) {
- result = false ; break;
- }
- }
- }
- }
- }
- return result ;
- }
- //---------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment