Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // hyrGlobal.mq5
- // by 2026 (c)hyrolean
- //---------------------------------------------------------------------------
- // Local:: <DataFolder>\MQL5\Libraries\User\hyrGlobal.mq5
- // URL:: https://pastebin.com/Lw82F2MN
- //---------------------------------------------------------------------------
- #property copyright "2026, hyrolean"
- #property link "https://pastebin.com/Lw82F2MN"
- #property library
- //---------------------------------------------------------------------------
- #include <Trade/PositionInfo.mqh>
- #include <Trade/Trade.mqh>
- #include <User/errordescription.mqh> // https://www.mql5.com/ja/code/79
- #include <User/hyrDefs.mqh> // https://pastebin.com/iHZKAWqC
- #include <User/hyrTmpl.mqh> // https://pastebin.com/LG1vurny
- #include <User/hyrStatus.mqh> // https://pastebin.com/d9Z8P2qD
- 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 CPositionInfo PosInfo ;
- static CTrade Trade ;
- //---------------------------------------------------------------------------
- //グローバル変数の設定
- 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 PrintLastError(string sender) export
- {
- int lastError = GetLastError() ;
- if(sender!="") {
- PrintFormat(ENTRY_NAME+"(%s): error(%d): %s",
- sender,lastError,ErrorDescription(lastError));
- }else {
- PrintFormat(ENTRY_NAME+"error(%d): %s",
- lastError,ErrorDescription(lastError));
- }
- }
- //---------------------------------------------------------------------------
- //メッセージ出力
- void PrintMessage(string message, string sender) export
- {
- if(sender!="")
- PrintFormat(ENTRY_NAME+"(%s): %s",sender,message);
- else
- PrintFormat(ENTRY_NAME+": %s",message);
- }
- //---------------------------------------------------------------------------
- //vとcompの距離が1Pointのサイズに収まっているかどうか
- bool InnerPoint(double v, double comp) export
- {
- return comp-_Point/2.0 < v && v < comp+_Point/2.0 ;
- }
- //---------------------------------------------------------------------------
- //基軸時間を返す
- datetime BaseTime(ENUM_TIMEBASE TimeBase) export
- {
- 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) export
- {
- double minLots = SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
- double stepLots = SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);
- double maxLots = SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
- double roundLots = MathRound( MathMax(lots,stepLots) / stepLots ) ;
- return MathMin(MathMax(roundLots*stepLots,minLots),maxLots) ;
- }
- //---------------------------------------------------------------------------
- //すでに注文済みかどうか
- FLAG AlreadyOrdered(FLAG orderFlag, MAGIC magic) export
- {
- FLAG flag = 0 ;
- for(int i=PositionsTotal()-1 ; i>=0 ; i--) {
- if(PosInfo.SelectByIndex(i)) {
- MAGIC orderMagic = PosInfo.Magic() ;
- if( PosInfo.Symbol() == Symbol() && (magic<0||magic==orderMagic) ){
- OP orderType = PosInfo.PositionType() ;
- 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) export
- {
- string entryName = ENTRY_NAME+"("+detector+")" ;
- uint startTick = GetTickCount();
- for(int retry=0; retry<ORDER_RETRY; retry++) {
- if( MaxAllowedSpread<0 || (entryType!=OP_BUY&&entryType!=OP_SELL) ||
- SymbolInfoInteger(NULL,SYMBOL_SPREAD) <= MaxAllowedSpread ) {
- TICKET ticket=MakeOrderSub(
- entryType,entryPrice,lots,sl,tp,entryName,magic,expiration,CLR_NONE);
- if(ticket>0)
- return ticket ;
- }
- if(GetTickCount()-startTick>=ORDER_RETRY_DURATION)
- break; // タイムオーバー
- Sleep(ORDER_RETRY_SLEEP);
- }
- PrintMessage("entry failed.","MakeOrder");
- return 0;
- }
- //---------------------------------------------------------------------------
- //注文発注サブルーチン
- TICKET MakeOrderSub(OP entryType, double entryPrice, double lots, double sl, double tp,
- string comment, MAGIC magicNumber, datetime expiration, color orderColor) export
- {
- // ※ MT5 では、orderColor は使われない
- Trade.SetDeviationInPoints(MaxAllowedSlippage);
- Trade.SetExpertMagicNumber(magicNumber);
- bool res=false ;
- ENUM_ORDER_TYPE_TIME orderTime
- = expiration==0? ORDER_TIME_GTC: ORDER_TIME_SPECIFIED;
- switch(entryType) {
- case OP_BUY:
- res = Trade.Buy(lots, NULL, entryPrice, sl, tp, comment);
- break;
- case OP_SELL:
- res = Trade.Sell(lots, NULL, entryPrice, sl, tp, comment);
- break;
- case OP_BUYLIMIT:
- res = Trade.BuyLimit(lots, entryPrice, NULL, sl, tp, orderTime, expiration, comment);
- break;
- case OP_SELLLIMIT:
- res = Trade.SellLimit(lots, entryPrice, NULL, sl, tp, orderTime, expiration, comment);
- break;
- case OP_BUYSTOP:
- res = Trade.BuyStop(lots, entryPrice, NULL, sl, tp, orderTime, expiration, comment);
- break;
- case OP_SELLSTOP:
- res = Trade.SellStop(lots, entryPrice, NULL, sl, tp, orderTime, expiration, comment);
- break;
- default:
- PrintMessage("Unknown entry type","MakeOrderSub");
- return 0;
- }
- if(!res) {
- PrintLastError("MakeOrderSub");
- return 0;
- }
- return Trade.ResultOrder();
- }
- //---------------------------------------------------------------------------
- //リミット価格付き逆指値注文の発注
- TICKET MakeOrderStopLimit(double stopPrice, double limitPrice, double lots,
- double sl, double tp, string detector, MAGIC magic, datetime expiration)
- export
- {
- string entryName = ENTRY_NAME+"("+detector+")" ;
- ENUM_ORDER_TYPE orderType = stopPrice<limitPrice ?
- ORDER_TYPE_BUY_STOP_LIMIT: ORDER_TYPE_SELL_STOP_LIMIT;
- Trade.SetDeviationInPoints(MaxAllowedSlippage);
- Trade.SetExpertMagicNumber(magic);
- ENUM_ORDER_TYPE_TIME orderTime
- = expiration==0? ORDER_TIME_GTC: ORDER_TIME_SPECIFIED;
- if(Trade.OrderOpen(_Symbol,orderType,lots,limitPrice,stopPrice,sl,tp,
- orderTime,expiration,entryName)) {
- return Trade.ResultOrder();
- }
- PrintLastError("MakeOrderStopLimit");
- return 0;
- }
- //---------------------------------------------------------------------------
- //発注済オーダーのStoplossとTakeprofitの変更
- bool ModifyOrderSlTp(TICKET ticket, double sl, double tp) export
- {
- bool res=Trade.PositionModify(ticket, sl, tp);
- if(!res) PrintLastError("ModifyOrderSlTp");
- return res;
- }
- //---------------------------------------------------------------------------
- //発注済予約注文の取消
- bool WithdrawOrder(TICKET ticket, color orderColor) export
- {
- // ※ MT5 では、orderColor は使われない
- bool res = Trade.OrderDelete(ticket);
- if(!res) PrintLastError("WithdrawOrder");
- return res;
- }
- //---------------------------------------------------------------------------
- //注文の決済
- bool CheckoutOrder(OP orderType, TICKET orderTicket, double orderLots) export
- {
- // ※ MT5 では、orderType は使われない
- uint startTick = GetTickCount();
- for(int retry=0; retry<ORDER_RETRY; retry++) {
- if(Trade.PositionClosePartial(orderTicket,orderLots,MaxAllowedSlippage)) {
- //NetProfit += Trade.ResultProfit() + Trade.ResultCommission() + Trade.ResultSwap();
- 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) export
- {
- int i;
- bool result = true ;
- CArrayObj *array = new CArrayObj();
- for(i = 0 ; i < PositionsTotal() ; i++){
- if(PosInfo.SelectByIndex(i)) {
- MAGIC posMagic = PosInfo.Magic();
- ENUM_POSITION_TYPE posType = PosInfo.PositionType();
- if( (posType==POSITION_TYPE_BUY&&(orderFlag&FLAG_BUY)!=0) ||
- (posType==POSITION_TYPE_SELL&&(orderFlag&FLAG_SELL)!=0) ) {
- if( PosInfo.Symbol() == Symbol() && (magic<0||magic==posMagic) ){
- AddToArray(array,OBJECT_CHECKOUT(PosInfo.Ticket(),PosInfo.Profit()));
- }
- }
- }
- }
- array.Sort(ARRAY_SORT_DESCEND); // 利益が多い順に並べ替える
- for(i=0;i<array.Total();i++) {
- CSortable<OBJECT_CHECKOUT> *node = (CSortable<OBJECT_CHECKOUT>*)array.At(i);
- if(PosInfo.SelectByTicket(node.v.Ticket)) {
- if(!CheckoutOrder(PosInfo.Type(),PosInfo.Ticket(),AdjustMarketLots(PosInfo.Volume()/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) export
- {
- 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) export
- {
- string textOrg = DoubleToString(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