Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // hyrGlobal.mq4
- // by 2025-2026 (c)hyrolean
- //---------------------------------------------------------------------------
- // Local:: <DataFolder>\MQL4\Libraries\User\hyrGlobal.mq4
- // URL:: https://pastebin.com/hk9XfDiv
- //---------------------------------------------------------------------------
- #property copyright "2025-2026, (c)hyrolean"
- #property link "https://pastebin.com/hk9XfDiv"
- #property library
- //---------------------------------------------------------------------------
- #include <stdlib.mqh>
- #include <User/hyrDefs.mqh> // https://pastebin.com/iHZKAWqC
- #include <User/hyrTmpl.mqh> // https://pastebin.com/LG1vurny
- #include <User/hyrStatus.mqh> // https://pastebin.com/D9JP5Ujq
- static string ENTRY_NAME = "hyrEA"; // エントリー名
- static int MaxAllowedSlippage=10; // 最大許容スリッページ(points)
- static int MaxAllowedSpread=50; // 最大許容スプレッド(points)
- static int ORDER_RETRY = 10 ; // 注文の最大許容リトライ回数
- static int ORDER_RETRY_SLEEP = 100 ; // 注文のリトライ時待機時間
- static uint ORDER_RETRY_DURATION = 1000 ; // 注文のリトライ最大許容有効時間
- static color ColorLongArrow=clrBlue; // 買い矢印の色
- static color ColorShortArrow=clrRed; // 売り矢印の色
- //---------------------------------------------------------------------------
- //グローバル変数の設定
- void GlobalSettings(
- string entryName,
- int maxSlippage,
- int maxSpread,
- int orderRetry,
- int orderRetrySleep,
- uint orderRetryDuration ) export
- {
- ENTRY_NAME = entryName ;
- MaxAllowedSlippage = maxSlippage ;
- MaxAllowedSpread = maxSpread ;
- ORDER_RETRY = orderRetry ;
- ORDER_RETRY_SLEEP = orderRetrySleep ;
- ORDER_RETRY_DURATION = orderRetryDuration ;
- }
- //---------------------------------------------------------------------------
- //注文の色設定
- void OrderColorSetting(
- color colLongArrow,
- color colShortArrow )
- {
- ColorLongArrow = colLongArrow ;
- ColorShortArrow = colShortArrow ;
- }
- //---------------------------------------------------------------------------
- //エラーログ出力
- void PrintLastError(string sender)
- {
- int lastError = GetLastError() ;
- if(sender!="") {
- printf(ENTRY_NAME+"(%s): error(%d): %s",
- sender,lastError,ErrorDescription(lastError));
- }else {
- printf(ENTRY_NAME+"error(%d): %s",
- lastError,ErrorDescription(lastError));
- }
- }
- //---------------------------------------------------------------------------
- //メッセージ出力
- void PrintMessage(string message, string sender)
- {
- if(sender!="")
- printf(ENTRY_NAME+"(%s): %s",sender,message);
- else
- printf(ENTRY_NAME+": %s",message);
- }
- //---------------------------------------------------------------------------
- //vとcompの距離が1Pointのサイズに収まっているかどうか
- bool InnerPoint(double v, double comp)
- {
- return comp-Point/2.0 < v && v < comp+Point/2.0 ;
- }
- //---------------------------------------------------------------------------
- //基軸時間を返す
- datetime BaseTime(ENUM_TIMEBASE TimeBase)
- {
- 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;
- }
- //---------------------------------------------------------------------------
- //マーケットで扱えるようにロットサイズを補正して返す
- double AdjustMarketLots(double lots)
- {
- double minLots = MarketInfo(Symbol(),MODE_MINLOT);
- double stepLots = MarketInfo(Symbol(),MODE_LOTSTEP);
- double maxLots = MarketInfo(Symbol(),MODE_MAXLOT);
- double roundLots = MathRound( MathMax(lots,stepLots) / stepLots ) ;
- return MathMin(MathMax(roundLots*stepLots,minLots),maxLots) ;
- }
- //---------------------------------------------------------------------------
- //すでに注文済みかどうか
- FLAG AlreadyOrdered(FLAG orderFlag, MAGIC magic)
- {
- FLAG flag = 0 ;
- for(int i=OrdersTotal()-1 ; i>=0 ; i--) {
- if( OrderSelect(i, SELECT_BY_POS) ) {
- MAGIC orderMagic = OrderMagicNumber() ;
- if( OrderSymbol() == Symbol() && (magic<0||magic==orderMagic) ){
- OP orderType = OrderType() ;
- 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;
- }
- //---------------------------------------------------------------------------
- //注文の発注
- TICKET MakeOrder(OP entryType, double lots, double sl, double tp, string detector,
- MAGIC magic, double entryPrice, datetime expiration)
- {
- string entryName = ENTRY_NAME+"("+detector+")" ;
- uint start = GetTickCount();
- for(int retry=0; retry<ORDER_RETRY; retry++) {
- if( MaxAllowedSpread<0 || (entryType!=OP_BUY&&entryType!=OP_SELL) ||
- MarketInfo(NULL,MODE_SPREAD) <= MaxAllowedSpread ) {
- color orderColor = clrNONE;
- double price=entryPrice ;
- switch(entryType) {
- case OP_BUY: case OP_BUYSTOP: case OP_BUYLIMIT:
- if(price==0.0) price = Ask ;
- orderColor = ColorLongArrow ;
- break;
- case OP_SELL: case OP_SELLSTOP: case OP_SELLLIMIT:
- if(price==0.0) price = Bid ;
- orderColor = ColorShortArrow ;
- break;
- }
- TICKET ticket=MakeOrderSub(
- entryType,price,lots,sl,tp,entryName,
- magic,expiration,orderColor);
- if(ticket>=0)
- return ticket ;
- }
- if(GetTickCount()-start>=ORDER_RETRY_DURATION)
- break; // タイムオーバー
- Sleep(ORDER_RETRY_SLEEP);
- }
- PrintMessage("entry failed.","MakeOrder");
- return -1;
- }
- //---------------------------------------------------------------------------
- //注文発注サブルーチン
- TICKET MakeOrderSub(OP entryType, double entryPrice, double lots, double sl, double tp,
- string comment, MAGIC magicNumber, datetime expiration, color orderColor)
- {
- TICKET res = OrderSend(
- NULL,
- entryType,
- lots,
- entryPrice,
- MaxAllowedSlippage,
- sl,
- tp,
- comment,
- magicNumber,
- expiration,
- orderColor
- );
- if(res<0)
- PrintLastError("MakeOrderSub");
- return res;
- }
- //---------------------------------------------------------------------------
- //発注済オーダーのStoplossとTakeprofitの変更
- bool ModifyOrderSlTp(TICKET ticket, double sl, double tp)
- {
- if(OrderSelect(ticket,SELECT_BY_TICKET)) {
- color orderColor = clrNONE;
- switch(OrderType()) {
- case OP_BUY: case OP_BUYSTOP: case OP_BUYLIMIT:
- orderColor = ColorLongArrow ;
- break;
- case OP_SELL: case OP_SELLSTOP: case OP_SELLLIMIT:
- orderColor = ColorShortArrow ;
- break;
- }
- return
- OrderModify(
- ticket,OrderOpenPrice(),sl,tp,OrderExpiration(),orderColor) ;
- }
- PrintLastError("ModifyOrderSlTp");
- return false ;
- }
- //---------------------------------------------------------------------------
- //発注済予約注文の取消
- bool WithdrawOrder(TICKET ticket, color orderColor)
- {
- bool res = OrderDelete(ticket, orderColor);
- if(!res) PrintLastError("WithdrawOrder");
- return res ;
- }
- //---------------------------------------------------------------------------
- //注文の決済
- bool CheckoutOrder(OP orderType, TICKET orderTicket, double orderLots)
- {
- uint startTick = GetTickCount();
- for(int retry=0; retry<ORDER_RETRY; retry++) {
- double checkoutPrice = 0.0 ;
- color orderColor = clrNONE ;
- switch(orderType) {
- case OP_BUY:
- checkoutPrice = Bid ;
- orderColor = ColorLongArrow ;
- break;
- case OP_SELL:
- checkoutPrice = Ask ;
- orderColor = ColorShortArrow ;
- break;
- }
- if(OrderClose(orderTicket, orderLots, checkoutPrice, MaxAllowedSlippage, orderColor))
- return true;
- if(GetTickCount()-startTick>=ORDER_RETRY_DURATION)
- break; // タイムオーバー
- Sleep(ORDER_RETRY_SLEEP);
- }
- PrintLastError("CheckoutOrder");
- return false ;
- }
- //---------------------------------------------------------------------------
- struct OBJECT_CHECKOUT {
- TICKET Ticket;
- double Profit;
- OBJECT_CHECKOUT() {
- Ticket = -1 ;
- Profit = 0.0 ;
- }
- OBJECT_CHECKOUT(const OBJECT_CHECKOUT &lhs) {
- Ticket = lhs.Ticket ;
- Profit = lhs.Profit ;
- }
- OBJECT_CHECKOUT(TICKET Ticket_, double Profit_) {
- Ticket = Ticket_ ;
- Profit = Profit_ ;
- }
- bool operator <(const OBJECT_CHECKOUT &rhs) const {
- return Profit < rhs.Profit ;
- }
- };
- //注文の全決済
- bool CheckoutOrderAll(FLAG orderFlag, MAGIC magic, double lotsDenom)
- {
- int i;
- bool result = true ;
- CArrayObj *array = new CArrayObj();
- for(i = 0 ; i < OrdersTotal() ; i++){
- if(OrderSelect(i, SELECT_BY_POS)) {
- MAGIC orderMagic = OrderMagicNumber();
- OP orderType = OrderType() ;
- if( (orderType==OP_BUY&&(orderFlag&FLAG_BUY)!=0) ||
- (orderType==OP_SELL&&(orderFlag&FLAG_SELL)!=0) ) {
- if( OrderSymbol() == Symbol() && (magic<0||magic==orderMagic) ){
- AddToArray(array,OBJECT_CHECKOUT(OrderTicket(),OrderProfit()));
- }
- }
- }
- }
- array.Sort(ARRAY_SORT_DESCEND); // 利益が多い順に並べ替える
- for(i=0;i<array.Total();i++) {
- CSortable<OBJECT_CHECKOUT> *node = (CSortable<OBJECT_CHECKOUT>*)array.At(i);
- if(OrderSelect(node.v.Ticket, SELECT_BY_TICKET)) {
- if(!CheckoutOrder(OrderType(),OrderTicket(),AdjustMarketLots(OrderLots()/lotsDenom))) {
- result = false ; break;
- }
- }
- }
- delete array ;
- return result ;
- }
- //---------------------------------------------------------------------------
- //時間動作制御(戻り値: true=アクティブ時間, false=オフタイム)
- bool ControlTimeAction(
- datetime TimeTick, datetime TimeStart, datetime TimeEnd,
- datetime &NextStartTime, MAGIC magic, ENUM_TIMEACT TimeAction)
- {
- MqlDateTime mqlTick, mqlStart, mqlEnd ;
- TimeToStruct(TimeTick, mqlTick);
- TimeToStruct(TimeStart, mqlStart);
- TimeToStruct(TimeEnd, 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 = NextStartTime<TimeTick ;
- // 現在活動時間帯
- if(activeTime) {
- if(!isActivated)
- NextStartTime = TimeTick ; // 現在時間を開始時間切り上げて完了
- return true ;
- }
- // 活動時間を次の時間にセットする
- 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 ;
- NextStartTime = timNextStart ;
- // 次の開始までの秒数
- datetime timOff = NextStartTime - TimeTick ;
- FLAG orderFlag = AlreadyOrdered(FLAG_SELL|FLAG_BUY, magic);
- STATUS status_long, status_short;
- double total=0.0;
- switch(TimeAction) {
- case TIMEACT_NONE:
- // None
- break;
- case TIMEACT_FORCE_CLOSE_ALL:
- // Force Close All positions
- if(orderFlag!=0)
- CheckoutOrderAll(orderFlag, magic, 1.0);
- break;
- case TIMEACT_FORCE_CLOSE_LONG:
- // Force Close Long positions
- if((orderFlag&FLAG_BUY)!=0)
- CheckoutOrderAll(FLAG_BUY, magic, 1.0);
- break;
- case TIMEACT_FORCE_CLOSE_SHORT:
- // Force Close Short positions
- if((orderFlag&FLAG_SELL)!=0)
- CheckoutOrderAll(FLAG_SELL, magic, 1.0);
- break;
- case TIMEACT_SOFT_CLOSE_ALL:
- // Close All positions if profits are Positive
- if(orderFlag!=0) {
- CheckStatus(OP_BUY,magic,&status_long);
- CheckStatus(OP_SELL,magic,&status_short);
- total = status_long.GrossProfit+status_short.GrossProfit ;
- if(total>0) {
- CheckoutOrderAll(orderFlag, magic, 1.0);
- }
- }
- break;
- case TIMEACT_SOFT_CLOSE_LONG:
- // Close Long positions if profits are Positive
- if((orderFlag&FLAG_BUY)!=0) {
- CheckStatus(OP_BUY,magic,&status_long);
- total=status_long.GrossProfit;
- if(total>0) {
- CheckoutOrderAll(FLAG_BUY, magic, 1.0);
- }
- }
- break;
- case TIMEACT_SOFT_CLOSE_SHORT:
- // Close Short positions if profits are Positive
- if((orderFlag&FLAG_SELL)!=0) {
- CheckStatus(OP_SELL,magic,&status_short);
- total=status_short.GrossProfit;
- if(total>0) {
- CheckoutOrderAll(FLAG_SELL, magic, 1.0);
- }
- }
- break;
- }
- return false ;
- }
- //---------------------------------------------------------------------------
- //000,000,000表示
- string DoubleToAmount(double inputdata, int dig)
- {
- string textOrg = DoubleToStr(inputdata,dig);
- int lnOrg = StringLen(textOrg) ;
- if(!lnOrg) return "" ;
- int periodPos = StringFind(textOrg,".");
- string textRes="";
- int beg=0, lnHead = periodPos>=0 ? periodPos : lnOrg ;
- StringReserve(textRes,lnHead+(lnHead+2)/3+1);
- if(textOrg[0]=='-') { textRes="-"; beg++ ; } // マイナス損益
- int lnRem = lnHead-beg ;
- int first = lnRem%3;
- if(!first&&lnRem>=3) first=3 ;
- if(first>0) {
- textRes+=StringSubstr(textOrg,beg,first);
- for(int i=first;i<lnRem;i+=3) // 三桁区切り
- textRes+=","+StringSubstr(textOrg,beg+i,3);
- }
- if(periodPos>=0)
- return textRes+StringSubstr(textOrg,periodPos);
- return textRes;
- }
- //---------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment