سوالات برنامه نویسی

سوال بپرسید, جواب بگیرید و با انجمن های ما در سرتاسر دنیا در ارتباط باشید.

آکادمی ایران ام کیو ال انجمن سوالات MQL5 اختصاص سود یک معامله هج برای بستن قسمتی از حجم معامله جهت عکس

برچسب زده شده: , , ,

  • اختصاص سود یک معامله هج برای بستن قسمتی از حجم معامله جهت عکس

    نوشته شده توسط Saeed43 در 2023-12-04 در 9:34 ب.ظ

    سلام و عرض ادب

    دنبال نوشتن برنامه ای در mql5 هستم که پس از تی پی شدن یک معامله سود ان را برای بستن معامله در ضرر جهت مخالف استفاده کند.

    به طور مثال: یک buy (1 lot tp 40 pips) بسته شده و 400 دلار سود معمامله میباشد. با فاصله 20 پیپ پایین تر یکsell (1 lot) باز میباشد که در نقطه حد سود معامله buy در 60 پیپ ضرر می باشد )-600$(

    با تی پی خوردن خرید، باید 2/3 حجم sell بسته شود

    با تابع onTradeTransaction تی پی و مقدار سود محاسبه میشود و با کلاس trade.mqh و دستور PositionClosePartial قسمتی از حجم باید بسته شود، (این دستور در تابغ transaction( نوشته شده، اما به جای یکبار اجراشدن چندین بار اجرا میشود تا حجم بیشتری بسته شود

    اگر تجربه مشابهی دارید ممنون میشم کمک کنید.

    Saeed43 پاسخ داد 1 سال پیش 2 اعضا · 5 پاسخ ها
  • 5 پاسخ ها
  • حسین

    مدیر کل
    2023-12-04 در 11:54 ب.ظ

    سلام ؛متوجه نشدم مشکلتون کجاست

  • Saeed43

    عضو
    2023-12-05 در 11:56 ق.ظ

    الان کاملا توضیح میدم خدمتتون:

    اول ی توضیحی درباره این برنامه بدم خدمتتون، برنامه در لحظه اجرا یک معامله تصادفی buy/sell باز میکنه، فرض کنیم buy (lot=1.0) که tp=40 pips

    بلافاصله یک sell stop (lot =1.0) به اندازه 20 pipsپایین تر هم گذاشته میشه ک در صورت حرکت خلاف جهت مارکت hedge بشه

    درصورتی که قبل ازتی پی شدن معامله buy معامله sell فعال شده باشد، اکسپرت سود حاصل از تی پی معامله buy را برای بستن کامل یا partial exit معامله sell استفاده میکند:

    Buy (lot = 1.0) hits +40 pips tp —-> profit = +400$

    Active sell (lot =1.0) is (40+20= 60 pips in loss) —-> loss= -600$

    با سود معامله خرید میتوان 0.66 از حجم معامله در ضرر sell را بست یعنی

    PositionClosePartial (0.66) —-> modified sell (lot = 0.34) —-> loss = -200$

    در این مرحله اکسپرت با مدیریت حجم های باقی مانده sell و buystop جدید باز میکند و ادامه ….

    برای محاسبه سود تی پی در لحظه فعال شدن تی پی از تابع OnTradeTransaction استفاده شده است:

    void OnTradeTransaction(const MqlTradeTransaction& trans,

    const MqlTradeRequest& request,

    const MqlTradeResult& result)

    {

    // Get transaction type as enumeration value

    ENUM_TRADE_TRANSACTION_TYPE type = trans.type;

    // If transaction is result of addition of the transaction in history

    if(type == TRADE_TRANSACTION_DEAL_ADD)

    {

    ResetLastError();

    if(HistoryDealSelect(trans.deal))

    m_deal.Ticket(trans.deal);

    else

    {

    Print(__FILE__, ” “, __FUNCTION__, “, ERROR: “, “HistoryDealSelect(“, trans.deal, “) error: “, GetLastError());

    return;

    }

    if(m_deal.DealType() == DEAL_TYPE_BUY || m_deal.DealType() == DEAL_TYPE_SELL)

    {

    if(m_deal.Entry() == DEAL_ENTRY_OUT)

    {

    long position_id = m_deal.PositionId();

    if(HistorySelectByPosition(position_id))

    {

    uint total = HistoryDealsTotal();

    ulong ticket = 0;

    // For all deals

    for(uint i=0; i<MathMax(total, 10); i++)

    {

    // Try to get deals ticket

    if((ticket=HistoryDealGetTicket(i))>0)

    {

    if(HistoryDealGetString(ticket, DEAL_SYMBOL) == Symbol() && HistoryDealGetInteger(ticket, DEAL_MAGIC) == MagicNumber && HistoryDealGetInteger(ticket, DEAL_ENTRY) == DEAL_ENTRY_OUT)

    {

    if(HistoryDealGetDouble(ticket, DEAL_PROFIT) > 0)

    {

    TT = HistoryDealGetDouble(ticket, DEAL_PROFIT);

    DealType = HistoryDealGetInteger(ticket, DEAL_TYPE);

    ApplyTT(TT, DealType);

    }

    }

    }

    }

    }

    }

    }

    }

    }

    برای بستن کامل پوزیشن در ضرر یا بستن قسمتی از حجم ان از تابع ApplyTT استفاده شده است:

    //+——————————————————————+

    //| Apply TT |

    //+——————————————————————+

    void ApplyTT(double tt, long dealType)

    {

    double remainedTT = tt;

    ulong furthestTicket = 0;

    double furthestProfit = 0.0;

    // If no opposite position is running

    if(dealType == 0 && PositionCounter(0) == 0)

    return;

    if(dealType == 1 && PositionCounter(1) == 0)

    return;

    // If buy position hits tp, apply TT to sell positions

    if(dealType == 1)

    {

    furthestTicket = Furthest(1);

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    while(remainedTT+ furthestProfit > 0)

    {

    remainedTT += furthestProfit;

    Trade.PositionClose(furthestTicket);

    // Go for next run

    furthestTicket = Furthest(1);

    if(furthestTicket == 0)

    break;

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    }

    // Partial close

    if(remainedTT > 0)

    {

    furthestTicket = Furthest(1);

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    if(furthestProfit == 0.0)

    return;

    double exitLot = remainedTT* PositionGetDouble(POSITION_VOLUME)/ MathAbs(furthestProfit);

    exitLot = NormalizeDouble(exitLot, 2);

    remainedTT += furthestProfit;

    Trade.PositionClosePartial(furthestTicket, exitLot);

    }

    }

    // If sell position hits tp, apply TT to buy positions

    if(dealType == 0)

    {

    furthestTicket = Furthest(0);

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    while(remainedTT+ furthestProfit > 0)

    {

    remainedTT += furthestProfit;

    Trade.PositionClose(furthestTicket);

    // Go for next run

    furthestTicket = Furthest(0);

    if(furthestTicket == 0)

    break;

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    }

    // Partial close

    if(remainedTT > 0)

    {

    furthestTicket = Furthest(0);

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    if(furthestProfit == 0.0)

    return;

    double exitLot = remainedTT* PositionGetDouble(POSITION_VOLUME)/ MathAbs(furthestProfit);

    exitLot = NormalizeDouble(exitLot, 2);

    remainedTT += furthestProfit;

    Trade.PositionClosePartial(furthestTicket, exitLot);

    }

    }

    TT = 0.0;

    }

    که در این تابع، تابع Furthest شماره ticket دورترین معامله خلاف جهت که قرار است بسته یا partial close شود را می دهد

  • Saeed43

    عضو
    2023-12-05 در 11:57 ق.ظ

    //+------------------------------------------------------------------+

    //| TradeTransaction function |

    //+------------------------------------------------------------------+

    void OnTradeTransaction(const MqlTradeTransaction& trans,

    const MqlTradeRequest& request,

    const MqlTradeResult& result)

    {

    // Get transaction type as enumeration value

    ENUM_TRADE_TRANSACTION_TYPE type = trans.type;

    // If transaction is result of addition of the transaction in history

    if(type == TRADE_TRANSACTION_DEAL_ADD)

    {

    ResetLastError();

    if(HistoryDealSelect(trans.deal))

    m_deal.Ticket(trans.deal);

    else

    {

    Print(__FILE__, " ", __FUNCTION__, ", ERROR: ", "HistoryDealSelect(", trans.deal, ") error: ", GetLastError());

    return;

    }

    if(m_deal.DealType() == DEAL_TYPE_BUY || m_deal.DealType() == DEAL_TYPE_SELL)

    {

    if(m_deal.Entry() == DEAL_ENTRY_OUT)

    {

    long position_id = m_deal.PositionId();

    if(HistorySelectByPosition(position_id))

    {

    uint total = HistoryDealsTotal();

    ulong ticket = 0;

    // For all deals

    for(uint i=0; i<MathMax(total, 10); i++)

    {

    // Try to get deals ticket

    if((ticket=HistoryDealGetTicket(i))>0)

    {

    if(HistoryDealGetString(ticket, DEAL_SYMBOL) == Symbol() && HistoryDealGetInteger(ticket, DEAL_MAGIC) == MagicNumber && HistoryDealGetInteger(ticket, DEAL_ENTRY) == DEAL_ENTRY_OUT)

    {

    if(HistoryDealGetDouble(ticket, DEAL_PROFIT) > 0)

    {

    TT = HistoryDealGetDouble(ticket, DEAL_PROFIT)- HistoryDealGetDouble(ticket, DEAL_VOLUME)* 100;

    DealType = HistoryDealGetInteger(ticket, DEAL_TYPE);

    ApplyTT(TT, DealType);

    }

    }

    }

    }

    }

    }

    }

    }

    }

  • Saeed43

    عضو
    2023-12-05 در 11:58 ق.ظ

    //+------------------------------------------------------------------+

    //| Apply TT |

    //+------------------------------------------------------------------+

    void ApplyTT(double tt, long dealType)

    {

    double remainedTT = tt;

    ulong furthestTicket = 0;

    double furthestProfit = 0.0;

    // If no opposite position is running

    if(dealType == 0 && PositionCounter(0) == 0)

    return;

    if(dealType == 1 && PositionCounter(1) == 0)

    return;

    // If buy position hits tp, apply TT to sell positions

    if(dealType == 1)

    {

    furthestTicket = Furthest(1);

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    while(remainedTT+ furthestProfit > 0)

    {

    remainedTT += furthestProfit;

    Trade.PositionClose(furthestTicket);

    // Go for next run

    furthestTicket = Furthest(1);

    if(furthestTicket == 0)

    break;

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    }

    // Partial close

    if(remainedTT > 0)

    {

    furthestTicket = Furthest(1);

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    if(furthestProfit == 0.0)

    return;

    double exitLot = remainedTT* PositionGetDouble(POSITION_VOLUME)/ MathAbs(furthestProfit);

    exitLot = NormalizeDouble(exitLot, 2);

    remainedTT += furthestProfit;

    Trade.PositionClosePartial(furthestTicket, exitLot);

    }

    }

    // If sell position hits tp, apply TT to buy positions

    if(dealType == 0)

    {

    furthestTicket = Furthest(0);

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    while(remainedTT+ furthestProfit > 0)

    {

    remainedTT += furthestProfit;

    Trade.PositionClose(furthestTicket);

    // Go for next run

    furthestTicket = Furthest(0);

    if(furthestTicket == 0)

    break;

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    }

    // Partial close

    if(remainedTT > 0)

    {

    furthestTicket = Furthest(0);

    if(PositionSelectByTicket(furthestTicket))

    furthestProfit = PositionGetDouble(POSITION_PROFIT)+ PositionGetDouble(POSITION_SWAP);

    if(furthestProfit == 0.0)

    return;

    double exitLot = remainedTT* PositionGetDouble(POSITION_VOLUME)/ MathAbs(furthestProfit);

    exitLot = NormalizeDouble(exitLot, 2);

    remainedTT += furthestProfit;

    Trade.PositionClosePartial(furthestTicket, exitLot);

    }

    }

    TT = 0.0;

    }

  • Saeed43

    عضو
    2023-12-05 در 12:04 ب.ظ

    و اما مشکل:

    تا وقتی که فقط یک معامله تی پی میشه، تابع OnTradeTransaction به درستی مقدار سود (TT) رامحاسبه کرده و دورترین پوزیشن در ضرر را مدیریت میکند ( اگر ضرر کمتر از tt باشه کامل بسته میشه در غیر این صورت partial exit ) اما زمانی که دو پوزیشن با هم tp میشن، دورترین معامله خلاف جهت اگر ضرر بیشتر از tt داشته باشه ک باید partial exit بشه، به طور عجیبی این کار چندین بار تکرار میشه تا کل پوزیشن با partial exit به طور کامل بسته بشه!!! در صورتی ک فقط یکبار باید اینکار انجام بشه

برای پاسخ دادن وارد سایت شوید.