Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #property copyright "2024-2025, (c)hyrolean"
- #property link "https://pastebin.com/6jvBeEfi"
- #property version "1.00"
- #property strict
- #include <stdlib.mqh>
- /*
- New 3EMA 手法 ( 状態遷移情報をターミナルに格納する変数を必要としないバージョン )
- ・ 建玉するときに、EMA50をストップロスに設定する(Stoploss=0の場合)
- ※ 現在価格がEMA50を下回るところでは、建玉を行わないようにする
- ・ ストップロスが玉の価格より下にあるものに的を絞り、EMA50を基準にトレーリングを行う
- ※ ただし、玉の価格がEMA50より下にある場合は、上記の操作を見送ることとする
- ・ ストップロスが玉の価格より下にあるものに的を絞り、ロウソク足が5期間経過後から、
- 現在のプライスが超えた時点でストップロスをエントリープライスに移動し、ロットの1/3を利確する
- ロウソク足の期間の出し方: (Time[0]-OrderOpenTime())/(Period()*60)>=5
- ※ 5期間経過後に未だ現価が下にある場合は、現価が上に来るまでこの試行は継続
- されることとし、現価がロウソク足1期間でも抜けたら即ストップロスをエントリープライスに移動
- し、ロットの1/3利確することとする
- ・ 現在価格がEMA10を下回った場合、ストップロスがエントリープライスに一致する玉を検出し、
- EMA20の位置にストップロスを移動し、ロットの1/2を利確する(この時点でEMA20も現在価格
- を突破している場合は、全ロットを利確することとする)
- ※ ただし、玉の価格がEMA20より上にある場合は、上記の操作を見送ることとする
- ・ ストップロスが玉の価格より上にあるものに的を絞り、EMA20を基準にトレーリングを行う
- */
- /*
- 使い方::
- 左上の|SELL|BUY|ボタンを選んでポジションを自分で打ちます。
- ポジションを打ったら、sl(ストップロス)のBARを自分の好みの場所に移動させます。
- 以降、3EMAの手法に従って自動的に利確されます。(逆行しなければですが…)
- 運悪く逆行してしまった場合は、損益の㌫、または、slに応じて自動損切されます。
- エントリーのコツとしては、上から現在価格,EMA10,EMA20,EMA50の順番で並んでいるときは、
- ロング(買い)、逆に、上からEMA50,EMA20,EMA10,現在価格の順番で並んでいるときは、
- ショート(売り)でエントリーすると上手くいくかもしれないです。
- (利確のタイミングを図りたい場合など、自動処理を一時的に中断したい場合は、Automate
- Processing Orders をfalseに設定すると無効に出来ます。)
- MT4を閉じてもslとエントリープライスの位置だけで状態を把握する為、万が一VPS等が停止し
- てしまってもサーバー側に建玉の情報さえ残っていればMT4を再度立ち上げてこのEAを有
- 効化するだけで状態復帰可能な仕様に仕上げています。
- youtubeで手法を解説している動画等::
- https://youtu.be/GsAAMgKXzic
- https://youtu.be/XUqDyupYGdk
- 以上ゞ
- */
- #define ENTRY_NAME "3MAUser"
- enum ENUM_POSI {
- POSI_STOP, // Stop
- POSI_ONLY_LONG, // Only Long
- POSI_ONLY_SHORT, // 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 ( EA closes positions automatically )
- 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 bool Automation = true; // Automate processing orders
- input ENUM_TIMEFRAMES MainTimeFrame = PERIOD_CURRENT; // Main Time Frame
- input int MAGICMA = 0; // 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 ENUM_MA_METHOD MAMode= MODE_EMA; // MA mode
- input ENUM_APPLIED_PRICE MAPriceType = PRICE_CLOSE; // MA price type
- input bool MA3 = true; // 3MA Enabled
- input int MA3FastPeriod = 10; // 3MA Fast period
- input int MA3MediumPeriod = 20; // 3MA Medium period
- input int MA3SlowPeriod = 50; // 3MA Slow period
- input int MA3TLPeriod = 5; // 3MA TL(TimeLimited) period
- input int Slippage = 10; // Max Slippage
- input int Spread = 50; // Max Spread in points
- input double BaseLots = 0.1; // Base Lots
- input double StepLots = 0.01; // Step Lots
- input double MinLots = 0.01; // Minimum Lots
- input double MaxLots = 50.0; // Maximum Lots
- input double LotsDenomTL = 3.0; // Lots denom of 3MA TL(TimeLimited)
- input double LotsDenomMAFast = 2.0; // Lots denom of 3MA Fast MA
- input double Takeprofit = 0; // Take profit in points (0 = unlimited)
- input double Stoploss = 200; // Stop loss in points (0 = Grossloss per or SlowMA trail)
- input double MaxGrosslossPer = 25; // Maximum Allowed Gross loss of Balance in percentage
- input bool Compounding = false; // Compounding interest Enabled
- input double CompoundingBase = 100000; // Compounding Base Balance (Lots=BaseLots*Balance/BaseBalance)
- input bool BalanceIncludeCredit= true; // Balance include Credit
- input bool Trailing = false; // Trailing Enabled
- input double TrailingStart = 300; // Trailing Start in points
- input double TrailingStop = 200; // Trailing Stop in points
- 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 ShowFlushTL = true; // Show a FLUSH TL button
- input bool ShowAmount = true; // Show Current Amount
- input int AmountDig = 0; // Amount Number of decimal places
- input color ClrAmountPosi = clrLightGoldenrod; // Amount Positive color
- input color ClrAmountNega = clrLightPink; // Amount Negative color
- input color ClrTimeControl = clrYellow; // Time Control Status color
- input color ClrLongArrow = clrBlue; // Long Arrow color
- input color ClrShortArrow = clrRed; // Short Arrow color
- input bool DBGMODE = true; // DEBUG MODE
- double Lots, PrevBid, PrevAsk;
- #define MAShift 0
- datetime CurTime, TimeTick, StartTime, CancelTime, UserTime;
- #define ORDER_RETRY 10
- #define FLAG_BUY 1
- #define FLAG_SELL 2
- #define FLAG_DUPLEX 4
- int UserEntry = 0 ;
- bool FlushTL = false ;
- #define SELLBTN_NAME "EntrySell"
- #define BUYBTN_NAME "EntryBuy"
- #define CLOSEALLBTN_NAME "CloseAll"
- #define CLOSELONGBTN_NAME "CloseLong"
- #define CLOSESHORTBTN_NAME "CloseShort"
- #define FLUSHTLBTN_NAME "FlushTL"
- #define OFFTIME_NAME "OFF TIME"
- bool OffTimeVisible = false ;
- #define AMOUNT_NAME "AMOUNT"
- #define AMOUNT_CLR_NEGA ClrAmountNega
- #define AMOUNT_CLR_POSI ClrAmountPosi
- #define DBGINFO_NAME "DEBUG INFO"
- bool InnerPoint(double v, double comp) {
- return comp-Point/2.0 < v && v < comp+Point/2.0 ;
- }
- double AdjLots(double lots) {
- double roundLots = MathRound( MathMax(lots,StepLots) / StepLots ) ;
- return MathMin(MathMax(roundLots*StepLots,MinLots),MaxLots) ;
- }
- //---------------------------------------------------------------------------
- //エラーログ出力
- void PrintLastError()
- {
- int lastError = GetLastError() ;
- printf(ENTRY_NAME"(%s): error(%d): %s",
- Symbol(),lastError,ErrorDescription(lastError));
- }
- //---------------------------------------------------------------------------
- //メッセージ出力
- void PrintMessage(string message)
- {
- printf(ENTRY_NAME"(%s): %s",Symbol(),message);
- }
- //---------------------------------------------------------------------------
- //オブジェクトのソート
- // ( https://youtu.be/ZRPiwUNLjiA )
- #include <Arrays/ArrayObj.mqh>
- #define ARRAY_SORT_ASCEND 1
- #define ARRAY_SORT_DESCEND 2
- template <typename T>
- class CSortable : public CObject {
- public:
- T key;
- int Compare(const CObject *node, const int mode=0) const {
- if(mode<=0) return 0;
- CSortable *comp= (CSortable*)node ;
- bool f = key<comp.key ;
- if(!f&&!(comp.key<key)) return 0;
- int result = f ? -1:+1 ;
- switch(mode) {
- case ARRAY_SORT_ASCEND: return +result;
- case ARRAY_SORT_DESCEND: return -result;
- }
- return 0;
- }
- };
- template <typename T>
- void AddToArray(CArrayObj &array, const T& key) {
- CSortable<T> *node = new CSortable<T>();
- node.key=key;
- array.Add(node);
- }
- //---------------------------------------------------------------------------
- int OnInit()
- {
- //テスターで表示されるインジケータを非表示にする
- HideTestIndicators(!DBGMODE);
- CurTime = MainTime();
- TimeTick = CancelTime = StartTime = UserTime = BaseTime();
- Lots = AdjLots(BaseLots) ; PrevBid = Bid ; PrevAsk = Ask ;
- //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 ;
- }
- //TLフラッシュ決算ボタン
- if(ShowFlushTL) {
- ObjectCreate(FLUSHTLBTN_NAME, OBJ_BUTTON, 0, 0, 0);
- ObjectSet(FLUSHTLBTN_NAME, OBJPROP_XDISTANCE, 10 + btn_ofs_x );
- ObjectSet(FLUSHTLBTN_NAME, OBJPROP_YDISTANCE, 35);
- ObjectSet(FLUSHTLBTN_NAME, OBJPROP_XSIZE, 100);
- ObjectSet(FLUSHTLBTN_NAME, OBJPROP_YSIZE, 25);
- ObjectSet(FLUSHTLBTN_NAME, OBJPROP_CORNER, 2);
- ObjectSet(FLUSHTLBTN_NAME, OBJPROP_FONTSIZE, 10);
- ObjectSet(FLUSHTLBTN_NAME, OBJPROP_COLOR, White);
- ObjectSet(FLUSHTLBTN_NAME, OBJPROP_BGCOLOR, clrDarkSlateBlue);
- ObjectSetString(0, FLUSHTLBTN_NAME, OBJPROP_TEXT, "FLUSH TL");
- ObjectSetString(0, FLUSHTLBTN_NAME, OBJPROP_FONT, "Verdana");
- btn_ofs_x += btn_distance ;
- }
- //ユーザーエントリをリセット
- UserEntry=0;
- return(INIT_SUCCEEDED);
- }
- //---------------------------------------------------------------------------
- void OnDeinit(const int reason)
- {
- if(ShowFlushTL) ObjectDelete(FLUSHTLBTN_NAME);
- 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) ;
- }
- }
- //---------------------------------------------------------------------------
- void OnTick()
- {
- datetime nextTime = MainTime() ;
- bool nextTimed = nextTime != CurTime ;
- CurTime = nextTime ;
- datetime nextTick = BaseTime() ;
- bool nextTicked = nextTick != TimeTick ;
- TimeTick = nextTick;
- // タイムコントロールチェック
- CheckTimeControl(nextTicked);
- // 動作チェック
- CheckBehavior(nextTimed);
- double atr14 = iATR(NULL,0,14,0) ;
- double spread = Ask-Bid ;
- // デバッグ欄表示のサンプル
- if(DBGMODE) {
- 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<=0?1:spread))
- );
- }
- // エントリー処理
- if(IsExpertEnabled()&&IsTradeAllowed()) {
- 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 ;
- if(EntryManualPosition("USER", entry, Lots)>=0)
- { busy |= user ; UserEntry = 0 ; }
- }
- }else { UserEntry=0; }
- }
- // MARK: 自動注文
- /*
- do {
- // 自動注文 開始時間調整
- if(StartTime>TimeTick||CancelTime>TimeTick)
- break ;
- // スプレッド幅のチェック
- if(MarketInfo(NULL,MODE_SPREAD) > Spread)
- break ;
- // 自動注文 XMA+ZigZag Detector
- if(nextTimed)
- EAEntryXMAZigZagPosition(busy,1);
- }while(0);
- */
- }else {
- if(StartTime-TimeTick<10)
- StartTime = TimeTick+10 ;
- }
- /*
- if(PmdTiming) {
- PmdPrevBid = (PmdPrevBid+Bid)/2.0 ; PmdPrevAsk = (PmdPrevAsk+Ask)/2.0 ;
- }*/
- PrevBid = Bid ; PrevAsk = Ask ;
- }
- //---------------------------------------------------------------------------
- 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 == FLUSHTLBTN_NAME && id==CHARTEVENT_OBJECT_CLICK) {
- FlushTL=true;
- Sleep(100);
- ObjectSet(FLUSHTLBTN_NAME, OBJPROP_STATE, False);
- }
- 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, ClrTimeControl);
- 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 MainTime(int shift=0)
- {
- return iTime(Symbol(), MainTimeFrame, shift);
- }
- //---------------------------------------------------------------------------
- //メインPERIODを返す
- int MainPeriod()
- {
- int period = MainTimeFrame ;
- if(!period) period = Period();
- return period ;
- }
- //---------------------------------------------------------------------------
- //タイムコントロールの基軸時間を返す
- 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;
- }
- //---------------------------------------------------------------------------
- //金額表示の更新
- void UpdateAmount(double amount, int positions)
- {
- if(ShowAmount) {
- if(positions>0) {
- string s = DoubleToAmount(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 ORDER_STATUS {
- int Ticket;
- double Price;
- double Stoploss;
- double Takeprofit;
- double Lots;
- double Profit;
- datetime OpenTime;
- string Comment;
- //-----
- ORDER_STATUS() {
- Ticket = -1 ;
- Price = Stoploss = Takeprofit = Lots = Profit = 0.0 ;
- OpenTime = 0 ;
- Comment = "" ;
- }
- ORDER_STATUS(
- int Ticket_,
- double Price_,
- double Stoploss_,
- double Takeprofit_,
- double Lots_,
- double Profit_,
- datetime OpenTime_,
- string Comment_ ) {
- Ticket = Ticket_;
- Price = Price_;
- Stoploss = Stoploss_;
- Takeprofit = Takeprofit_;
- Lots = Lots_;
- Profit = Profit_;
- OpenTime = OpenTime_;
- Comment = Comment_;
- }
- bool operator <(const ORDER_STATUS &rhs) const {
- return Price<rhs.Price;
- }
- };
- //-----
- struct STATUS {
- int Type, Magic;
- int Positions, PyramidPositions, AveragePositions;
- double MinPrice, MaxPrice, BorderPrice;
- double MinPriceLots, MaxPriceLots;
- double MinPriceProfit, MaxPriceProfit;
- double MinPriceStoploss, MaxPriceStoploss;
- int MinPriceTicket, MaxPriceTicket;
- double MinStoploss, MaxStoploss;
- double MinTakeprofit, MaxTakeprofit;
- double MinLots, MaxLots;
- datetime MinOpenTime, MaxOpenTime;
- double PyramidMinLots, PyramidMaxLots;
- double AverageMinLots, AverageMaxLots;
- double TotalPrices, TotalLots;
- double CurrentPrices, MedianPrices;
- double GrossProfit;
- double PositiveProfit;
- CArrayObj *Orders;
- STATUS() {
- Orders = new CArrayObj();
- }
- ~STATUS() {
- delete Orders;
- }
- void Check(int type, int magic) {
- Type=type;
- Magic=magic;
- Positions = 0 ;
- PyramidPositions = 0 ;
- AveragePositions = 0 ;
- MinPrice = DBL_MAX ;
- MaxPrice = 0.0 ;
- MinPriceLots = 0.0 ;
- MaxPriceLots = 0.0 ;
- MinPriceProfit = 0.0 ;
- MaxPriceProfit = 0.0 ;
- MinPriceStoploss = 0.0 ;
- MaxPriceStoploss = 0.0 ;
- MinPriceTicket = 0 ;
- MaxPriceTicket = 0 ;
- MinStoploss = DBL_MAX ;
- MaxStoploss = 0.0 ;
- MinTakeprofit = DBL_MAX ;
- MaxTakeprofit = 0.0 ;
- MinLots = DBL_MAX ;
- MaxLots = 0.0 ;
- MinOpenTime = TimeCurrent() ;
- MaxOpenTime = 0 ;
- PyramidMinLots = DBL_MAX ;
- PyramidMaxLots = 0.0 ;
- AverageMinLots = DBL_MAX ;
- AverageMaxLots = 0.0 ;
- BorderPrice = 0.0 ;
- GrossProfit = 0.0 ;
- PositiveProfit = 0.0 ;
- CurrentPrices = 0.0 ;
- MedianPrices = 0.0 ;
- Orders.Clear();
- double halfSpread = (Ask-Bid)/2.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()) {
- int orderTicket = OrderTicket() ;
- double orderPrice = OrderOpenPrice();
- double orderStoploss = OrderStopLoss();
- double orderTakeprofit = OrderTakeProfit();
- double orderLots = OrderLots();
- double orderProfit = OrderProfit() ;
- datetime orderOpenTime = OrderOpenTime() ;
- string orderComment = OrderComment();
- AddToArray(Orders, ORDER_STATUS(
- orderTicket,
- orderPrice,
- orderStoploss,
- orderTakeprofit,
- orderLots,
- orderProfit,
- orderOpenTime,
- orderComment )
- );
- GrossProfit += orderProfit;
- if(orderProfit>0.0)
- PositiveProfit += orderProfit;
- if(orderPrice<MinPrice) {
- MinPrice = orderPrice ;
- MinPriceLots = orderLots ;
- MinPriceProfit = orderProfit ;
- MinPriceStoploss = orderStoploss ;
- MinPriceTicket = orderTicket ;
- }
- if(orderPrice>MaxPrice) {
- MaxPrice = orderPrice ;
- MaxPriceLots = orderLots ;
- MaxPriceProfit = orderProfit ;
- MaxPriceStoploss = orderStoploss ;
- MaxPriceTicket = orderTicket ;
- }
- if(orderStoploss<MinStoploss) MinStoploss = orderStoploss;
- if(orderStoploss>MaxStoploss) MaxStoploss = orderStoploss;
- if(orderTakeprofit<MinTakeprofit) MinTakeprofit = orderTakeprofit;
- if(orderTakeprofit>MaxTakeprofit) MaxTakeprofit = orderTakeprofit;
- if(orderLots<MinLots) MinLots = orderLots;
- if(orderLots>MaxLots) MaxLots = orderLots;
- totalPrice += orderPrice*orderLots ;
- totalLots += orderLots;
- if(type==OP_BUY) {
- CurrentPrices += (Bid - orderPrice) * orderLots ;
- MedianPrices += (orderPrice + halfSpread) * orderLots ;
- }
- else if(type==OP_SELL) {
- CurrentPrices += (orderPrice - Ask) * orderLots ;
- MedianPrices += (orderPrice - halfSpread) * orderLots ;
- }
- if(MaxOpenTime<orderOpenTime) MaxOpenTime=orderOpenTime;
- if(MinOpenTime>orderOpenTime) MinOpenTime=orderOpenTime;
- if(StringFind(orderComment,"PRMD")>=0) {
- if(orderLots>PyramidMaxLots)
- PyramidMaxLots = orderLots ;
- if(orderLots<PyramidMinLots)
- PyramidMinLots = orderLots ;
- PyramidPositions++;
- }
- if(StringFind(orderComment,"AVRG")>=0) {
- if(orderLots>AverageMaxLots)
- AverageMaxLots = orderLots ;
- if(orderLots<AverageMinLots)
- AverageMinLots = orderLots ;
- AveragePositions++;
- }
- Positions++;
- }
- }
- }
- }
- Orders.Sort(ARRAY_SORT_ASCEND);
- if(!PyramidPositions) {
- PyramidMinLots = Lots ;
- PyramidMaxLots = Lots ;
- }
- if(!AveragePositions) {
- AverageMinLots = Lots ;
- AverageMaxLots = Lots ;
- }
- if(totalLots>0) {
- BorderPrice = totalPrice / totalLots ;
- }
- TotalPrices = totalPrice ;
- TotalLots = totalLots ;
- }
- /*
- double ProfitPrice(double borderPrice=0.0) const {
- if(borderPrice==0.0) borderPrice = BorderPrice;
- if(borderPrice>0.0) {
- //double stride = PyramidingStride * Point ;
- switch(Type) {
- case OP_BUY: {
- double bar = MathMax(MaxPrice,BuyMaxPrice)-borderPrice ;
- if(bar>0.0) {
- return bar * (ProfitRatePer / 100.0) + borderPrice ;
- }
- break;
- }
- case OP_SELL: {
- double bar = MathMin(MinPrice,SellMinPrice)-borderPrice ;
- if(bar<0.0) {
- return bar * (ProfitRatePer / 100.0) + borderPrice ;
- }
- break;
- }
- }
- }
- return borderPrice ;
- }
- */
- double MedianBorderPrice(const STATUS &revStatus, double lossPrices=0.0) const
- {
- double medianLots = Type==OP_BUY ? TotalLots : -TotalLots ;
- medianLots += revStatus.Type==OP_BUY ? revStatus.TotalLots: -revStatus.TotalLots ;
- if(Type==OP_BUY?medianLots>0.0:medianLots<0.0) {
- double medianPrices = Type==OP_BUY ? MedianPrices-lossPrices : -MedianPrices+lossPrices ;
- medianPrices += revStatus.Type==OP_BUY ? revStatus.MedianPrices: -revStatus.MedianPrices ;
- double medianBorder = medianPrices/medianLots ;
- switch(Type) {
- case OP_BUY:
- medianBorder -= (Ask-Bid)/2.0;
- break;
- case OP_SELL:
- medianBorder += (Ask-Bid)/2.0;
- break;
- }
- return medianBorder ;
- }
- return 0.0;
- }
- };
- //-----
- int CheckStatus(int type, int magic, STATUS &status)
- {
- status.Check(type,magic);
- return status.Positions;
- }
- //---------------------------------------------------------------------------
- //MARK:動作チェック
- void CheckBehavior(bool nextTimed)
- {
- // 複利ロット計算
- if(Compounding) {
- double balance = AccountBalance();
- if(BalanceIncludeCredit) balance += AccountCredit();
- Lots = balance*BaseLots/CompoundingBase ;
- if(Lots<MinLots) Lots = MinLots ;
- if(Lots>MaxLots) Lots = MaxLots ;
- }
- // 全体のステータスを取得
- STATUS BuyWholeStatus, SellWholeStatus ;
- CheckStatus(OP_BUY, MAGICMA, BuyWholeStatus);
- CheckStatus(OP_SELL, MAGICMA, SellWholeStatus);
- // 金額を更新
- double CurAmount = BuyWholeStatus.GrossProfit+SellWholeStatus.GrossProfit ;
- int CurPositions = BuyWholeStatus.Positions+SellWholeStatus.Positions ;
- UpdateAmount(CurAmount,CurPositions);
- // 自動処理
- if(Automation) {
- // 最大損益のチェック
- if(CurAmount<0) {
- double balance = AccountBalance();
- if(BalanceIncludeCredit) balance += AccountCredit();
- if(balance*MaxGrosslossPer/100.0<-CurAmount) {
- //最大損益を超えた場合は、すべて決済する
- CheckoutOrderAll(FLAG_BUY|FLAG_SELL);
- PrintMessage("Check-out orders by over Maximum Gross Loss");
- return;
- }
- }
- // オーダーの処理
- ProcessOrders(nextTimed, OP_BUY, BuyWholeStatus, SellWholeStatus);
- ProcessOrders(nextTimed, OP_SELL, SellWholeStatus, BuyWholeStatus);
- }
- FlushTL=false;
- }
- //---------------------------------------------------------------------------
- //MARK:オーダーの処理
- void ProcessOrders(bool nextTimed, int orderType, const STATUS &status, const STATUS &revStatus)
- {
- if(status.Positions<=0) return ;
- color orderColor = orderType==OP_BUY ? ClrLongArrow : ClrShortArrow ;
- // トレーリング
- if(Trailing) {
- double tstart = TrailingStart*Point ;
- double tstop = TrailingStop*Point ;
- double minPadding = tstart+tstop ;
- for(int i=status.Positions-1;i>=0;i--) {
- CSortable<ORDER_STATUS>* order =
- (CSortable<ORDER_STATUS>*)status.Orders.At(
- orderType==OP_SELL?i:status.Positions-1-i) ;
- if( orderType==OP_BUY ?
- order.key.Price>Bid-minPadding : order.key.Price<Ask+minPadding )
- break;
- double sl=0.0 ;
- if( order.key.Stoploss==0.0 ||
- ( orderType==OP_BUY ?
- order.key.Stoploss<order.key.Price : order.key.Stoploss>order.key.Price) ) {
- //初回トレール
- sl = orderType==OP_BUY ? order.key.Price+tstart : order.key.Price-tstart ;
- }else {
- //既にトレール済
- sl = order.key.Stoploss ;
- }
- while( ( orderType==OP_BUY ? Bid-sl : sl-Ask ) >= tstop*2 ) {
- //カクカクにトレール幅を狭めていく
- sl += orderType==OP_BUY ? +tstop : -tstop ;
- }
- if(!InnerPoint(sl,order.key.Stoploss)) {
- //ストップロスを更新
- if(OrderModify(order.key.Ticket,order.key.Price,sl,order.key.Takeprofit,0,orderColor)) {
- order.key.Stoploss = sl ;
- }else PrintLastError();
- }
- }
- }
- // 3EMA処理
- if(MA3 && (nextTimed||FlushTL)) {
- double HalfSpread = (Ask-Bid)/2.0;
- double FastMA0 = iMA(NULL, MainTimeFrame, MA3FastPeriod, MAShift, MAMode, MAPriceType, 0) +HalfSpread ;
- double MediumMA0 = iMA(NULL, MainTimeFrame, MA3MediumPeriod, MAShift, MAMode, MAPriceType, 0) +HalfSpread ;
- double SlowMA0 = iMA(NULL, MainTimeFrame, MA3SlowPeriod, MAShift, MAMode, MAPriceType, 0) +HalfSpread ;
- for(int i=status.Positions-1;i>=0;i--) {
- CSortable<ORDER_STATUS>* order =
- (CSortable<ORDER_STATUS>*)status.Orders.At(
- orderType==OP_SELL?i:status.Positions-1-i) ;
- double price = order.key.Price ;
- double sl = order.key.Stoploss ;
- double trail_sl=0.0;
- double checkout_denom=0.0;
- string checkout_reason="";
- if(InnerPoint(sl,price)) { // プライスがslに一致
- if(FlushTL&&!nextTimed) continue;
- if(!InnerPoint(MediumMA0,price) &&
- (orderType==OP_BUY?MediumMA0-HalfSpread>price:MediumMA0+HalfSpread<price)) { // Medium MA がプライス以上
- if(orderType==OP_BUY?FastMA0>Ask:FastMA0<Bid) { // Fast MA が現価以上
- // 決済設定
- checkout_denom = LotsDenomMAFast ;
- checkout_reason = "Check-out by Fast MA" ;
- if(orderType==OP_BUY?MediumMA0>Ask:MediumMA0<Bid) // Medium MA が現価より上
- { checkout_reason += " & Medium MA"; checkout_denom = 1.0 ;} // 全決済する
- // ストップロスを Medium MA 値に更新する
- trail_sl = MediumMA0 + (orderType==OP_BUY?-HalfSpread:+HalfSpread) ;
- }
- }
- }else if(sl!=0.0&&(orderType==OP_BUY?sl>price:sl<price)) { //プライスがslより下
- if(FlushTL&&!nextTimed) continue;
- if(orderType==OP_BUY?Ask<=MediumMA0:Bid>=MediumMA0) { //現価が Medium MA より下になった
- // 決済設定
- checkout_denom = 1.0 ; // 全決済
- checkout_reason = "Check-out by Medium MA" ;
- }
- }else { //プライスがslより上、もしくは、slが設定されていない
- if(FlushTL||MA3TLPeriod>0) { // TL(TimeLimited) ポジションが有効
- //ロウソク足の期間を計測
- datetime tperiod = MainPeriod() * 60 ;
- int period = int((CurTime-order.key.OpenTime)/tperiod);
- if(FlushTL||period>=MA3TLPeriod-1) { //TL(TimeLimited)期間が過ぎている
- if(orderType==OP_BUY?Bid>price:Ask<price) { // 利確できる位置にある
- if(!FlushTL&&(orderType==OP_BUY?FastMA0>Ask||MediumMA0>Ask:FastMA0<Bid||MediumMA0<Bid)) { // 2MA が現価より上
- // 現価が 2MA を抜かすまでの間、ストップロスを原価ギリギリまで引き上げておく
- trail_sl = price + (orderType==OP_BUY?-Point:+Point);
- }else { // FastMA が現価以下
- // 決済設定
- checkout_denom = LotsDenomTL ;
- checkout_reason = "Check-out by TL(TimeLimited)" ;
- // ストップロスを原価に引き上げる
- trail_sl = price ;
- }
- }
- }
- }
- if(!FlushTL||nextTimed) {
- if(sl==0.0) { //ストップロスが設定されていない
- if(MaxGrosslossPer>=100.0) { // Max Gross loss が 100%以上
- if(orderType==OP_BUY?Ask<=SlowMA0:Bid>=SlowMA0) { //現価が Slow MA より下になった
- // 損切設定
- checkout_denom = 1.0 ; // 全決済
- checkout_reason = "Loss-cut order by Slow MA" ;
- }
- }
- }
- }
- }
- if(trail_sl!=0.0) {
- //MAによるトレーリング
- if(sl==0.0||(!InnerPoint(sl,trail_sl)&&(orderType==OP_BUY?sl<trail_sl:sl>trail_sl))) {
- sl = trail_sl ;
- if(OrderModify(order.key.Ticket,order.key.Price,sl,order.key.Takeprofit,0,orderColor)) {
- order.key.Stoploss = sl ;
- }else PrintLastError();
- }
- }
- if(checkout_denom>0.0) {
- //MAによる決済処理
- double lots = AdjLots(order.key.Lots/checkout_denom) ;
- if(lots<MinLots) lots = MinLots ;
- if(lots>order.key.Lots) lots = order.key.Lots ;
- if(CheckoutOrder(orderType,order.key.Ticket,lots)) {
- PrintMessage(checkout_reason);
- order.key.Lots -= lots ;
- }
- }
- }
- }
- }
- //---------------------------------------------------------------------------
- //すでに注文済みかどうか
- 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;
- }
- //---------------------------------------------------------------------------
- //マニュアルポジション発注
- int EntryManualPosition(string detector, int entryType, double lots)
- {
- double sl=0.0, tp=0.0;
- switch(entryType) {
- case OP_BUY:
- if(Stoploss!=0.0) sl = Ask-Stoploss*Point ;
- if(Takeprofit!=0.0) tp = Ask+Takeprofit*Point ;
- break;
- case OP_SELL:
- if(Stoploss!=0.0) sl = Bid+Stoploss*Point ;
- if(Takeprofit!=0.0) tp = Bid-Takeprofit*Point ;
- break;
- }
- if(sl==0.0) {
- if(MaxGrosslossPer>=100.0) {
- // SlowMAの現在位置がAsk/Bidよりも上回っていないことを確認する
- double HalfSpread = (Ask-Bid)/2.0;
- double SlowMA0 = iMA(NULL, MainTimeFrame, MA3SlowPeriod, MAShift, MAMode, MAPriceType, 0) +HalfSpread ;
- if(entryType==OP_BUY?SlowMA0>=Ask:SlowMA0<=Bid) {
- PrintMessage("Entrying failed due to Slow MA over price reached");
- return -1 ; // invalid
- }
- }
- }
- return MakeOrder(entryType,lots,sl,tp,detector,MAGICMA);
- }
- //---------------------------------------------------------------------------
- //注文の発注
- int MakeOrder(int entryType, double lots, double sl, double tp, string detector, int magic,
- double entryPrice=0.0, datetime expiration=0)
- {
- string entryName = ENTRY_NAME"("+detector+")" ;
- for(int retry=0; retry<ORDER_RETRY; retry++) {
- color orderColor = clrNONE;
- if( (entryType==OP_BUY||entryType==OP_SELL) &&
- MarketInfo(NULL,MODE_SPREAD) > Spread) { Sleep(2000); continue ; }
- double price=entryPrice ;
- switch(entryType) {
- case OP_BUY: case OP_BUYSTOP: case OP_BUYLIMIT:
- if(price==0.0) price = Ask ;
- orderColor = ClrLongArrow ;
- break;
- case OP_SELL: case OP_SELLSTOP: case OP_SELLLIMIT:
- if(price==0.0) price = Bid ;
- orderColor = ClrShortArrow ;
- break;
- }
- int ticket=MakeOrderSub(
- entryType,price,lots,sl,tp,entryName,
- magic,expiration,orderColor);
- if(ticket>=0)
- return ticket ;
- Sleep(2000);
- }
- return -1;
- }
- //---------------------------------------------------------------------------
- //注文発注サブルーチン
- int MakeOrderSub(int entryType, double entryPrice, double lots, double sl=0.0, double tp=0.0,
- string comment=NULL, int magicNumber=0, datetime expiration=0, color orderColor=clrNONE)
- {
- int res = OrderSend(
- NULL,
- entryType,
- lots,
- entryPrice,
- Slippage,
- sl,
- tp,
- comment,
- magicNumber,
- expiration,
- orderColor
- );
- if(res<0)
- PrintLastError();
- return res;
- }
- //---------------------------------------------------------------------------
- //注文の決済
- 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 = ClrLongArrow ;
- break;
- case OP_SELL:
- checkoutPrice = Ask ;
- orderColor = ClrShortArrow ;
- break;
- }
- if(OrderClose(orderTicket, orderLots, checkoutPrice, Slippage, orderColor))
- return true;
- Sleep(100);
- }
- PrintLastError();
- return false ;
- }
- //---------------------------------------------------------------------------
- struct OBJECT_CHECKOUT {
- int Ticket;
- double Profit;
- OBJECT_CHECKOUT() {
- Ticket = -1 ;
- Profit = 0.0 ;
- }
- OBJECT_CHECKOUT(int Ticket_, double Profit_) {
- Ticket = Ticket_ ;
- Profit = Profit_ ;
- }
- bool operator <(const OBJECT_CHECKOUT &rhs) const {
- return Profit < rhs.Profit ;
- }
- };
- //注文の全決済
- bool CheckoutOrderAll(int orderFlag, double lotsDenom=1.0)
- {
- bool result = true ;
- CArrayObj *array = new CArrayObj();
- for(int i = 0 ; i < OrdersTotal() ; 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 ){
- AddToArray(array,OBJECT_CHECKOUT(OrderTicket(),OrderProfit()));
- }
- }
- }
- }
- array.Sort(ARRAY_SORT_DESCEND); // 利益が多い順に並べ替える
- for(int i=0;i<array.Total();i++) {
- CSortable<OBJECT_CHECKOUT> *node = (CSortable<OBJECT_CHECKOUT>*)array.At(i);
- if(OrderSelect(node.key.Ticket, SELECT_BY_TICKET)) {
- if(!CheckoutOrder(OrderType(),OrderTicket(),OrderLots()/lotsDenom)) {
- result = false ; break;
- }
- }
- }
- delete array ;
- return result ;
- }
- //---------------------------------------------------------------------------
- //000,000,000表示
- // http://chocottokozukai.seesaa.net/article/417824756.html
- string DoubleToAmount(double inputdata, int dig)
- {
- string returnstr = DoubleToStr(inputdata,dig);
- int length;
- int noofcomma;
- int firstcomma;
- length = StringLen(DoubleToStr(MathFloor(inputdata),0));
- if (inputdata >= 0) noofcomma = (int)MathFloor((length - 1) / 3);
- else noofcomma = (int)MathFloor((length - 2) / 3);
- if (noofcomma == 0) return (returnstr);
- firstcomma = length - noofcomma * 3;
- if (firstcomma == 0) firstcomma = 3;
- for (int i = 0; i < noofcomma; i++){
- returnstr = StringConcatenate(StringSubstr(returnstr, 0, firstcomma + i * 4),
- ",",StringSubstr(returnstr, firstcomma + i * 4));
- }
- return (returnstr);
- }
- //---------------------------------------------------------------------------
- /* ( おまけ )
- //---------------------------------------------------------------------------
- // ZIGZAG_STATUS
- //-----
- struct ZIGZAG_STATUS {
- double Price;
- datetime Time;
- int Shift;
- ZIGZAG_STATUS() {Price=0;Time=0;Shift=0;}
- ZIGZAG_STATUS(double Price_, datetime Time_, int Shift_) {
- Price = Price_ ;
- Time = Time_ ;
- Shift = Shift_ ;
- }
- bool operator <(const ZIGZAG_STATUS &rhs) const {
- return Time < rhs.Time ;
- }
- };
- //-----
- // ZigZag のポジションを列挙する
- bool EnumZigZagStatus(int num, ZIGZAG_STATUS &arrayZZ[], int si=0, int expire=INT_MAX)
- {
- int limit = expire == INT_MAX ? INT_MAX : si + expire ;
- limit = MathMin(limit,iBars(NULL,MainTimeFrame)-1);
- ArraySetAsSeries(arrayZZ,true);
- ArrayResize(arrayZZ,num);
- for (int i = si, n=0; i < limit ; i++) {
- double zz = iCustom(NULL, MainTimeFrame, "ZigZag", ZigZagDepth, ZigZagDeviation, ZigZagBackstep, 0, i);
- if(zz!=0) {
- arrayZZ[n] = ZIGZAG_STATUS(zz, MainTime(i), i);
- n++;
- if(n>=num)
- return true;
- }
- }
- return false;
- }
- //---------------------------------------------------------------------------
- // XMA+ZigZag の最初のエントリポイントが存在するかどうか調べる
- int CheckDetectorXMAZigZag(double &entryPrice, double &stoploss, int si=0)
- {
- ZIGZAG_STATUS zz[];
- bool valid = EnumZigZagStatus(3,zz,si,ExpirationPeriod*3);
- if(valid&&zz[0].Shift<ZigZagBackstep)
- valid = EnumZigZagStatus(3,zz,zz[0].Shift+1,ExpirationPeriod*3);
- (以下略・・・)
- }
- //---------------------------------------------------------------------------
- */
Advertisement
Add Comment
Please, Sign In to add comment