Created
October 6, 2025 01:06
-
-
Save paibamboo/b8190e13d1735f2f09548c9c41d7b927 to your computer and use it in GitHub Desktop.
MyCustomTradePanel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //+------------------------------------------------------------------+ | |
| //| TradePanel.mq5 | | |
| //| Copyright 2023, MetaQuotes Ltd. | | |
| //| https://www.mql5.com | | |
| //+------------------------------------------------------------------+ | |
| #property copyright "Copyright 2023, MetaQuotes Ltd." | |
| #property link "https://www.mql5.com" | |
| #property version "1.00" | |
| #property strict | |
| #include <Controls/Dialog.mqh> | |
| #include <Controls/SpinEdit.mqh> | |
| #include <Controls/Button.mqh> | |
| #include <Controls/Label.mqh> | |
| #include <Controls/RadioGroup.mqh> | |
| #include <Controls/CheckGroup.mqh> | |
| #include "../Include/Utils.mqh"; | |
| input int MaxOpenTrades = 999; | |
| input int MaxTradesPerDay = 999; | |
| CAppDialog TradePanel; | |
| CButton placeOrderButton; | |
| CLabel slLabel, tpLabel, riskLabel, rrLabel, spreadLabel, maxOpenTradesLabel, maxTradesPerDayLabel, maxOrderSizeLabel, currentTimeLabel, lotSizeLabel; | |
| CEdit lotEdit, slEdit, tpEdit, riskEdit, rrEdit, spreadEdit, preferredRREdit; | |
| CRadioGroup radioGroup; | |
| CCheckBox autoPlaceOrderCheckbox; | |
| CCheckGroup checkboxGroup; | |
| int numChartClickedAfterSlTpEdit = 0; | |
| string editValue = ""; | |
| bool isSlEditLastClicked = false; | |
| bool isTpEditLastClicked = false; | |
| double defaultSl = 0; | |
| double defaultTp = 0; | |
| double defaultRiskAmount = 50; | |
| bool defaultAutoPlaceOrder = false; | |
| double defaultPreferredRR = 3.5; | |
| int OnInit() | |
| { | |
| if (GlobalVariableCheck(_Symbol + "_SL") && GlobalVariableGet(_Symbol + "_SL") != 0) | |
| { | |
| defaultSl = GlobalVariableGet(_Symbol + "_SL"); | |
| } | |
| if (GlobalVariableCheck(_Symbol + "_TP") && GlobalVariableGet(_Symbol + "_TP") != 0) | |
| { | |
| defaultTp = GlobalVariableGet(_Symbol + "_TP"); | |
| } | |
| if (GlobalVariableCheck(_Symbol + "_RISK") && GlobalVariableGet(_Symbol + "_RISK") != 0) | |
| { | |
| defaultRiskAmount = GlobalVariableGet(_Symbol + "_RISK"); | |
| } | |
| if (GlobalVariableCheck(_Symbol + "_AUTO_PLACE_ORDER") && GlobalVariableGet(_Symbol + "_AUTO_PLACE_ORDER") == 1) | |
| { | |
| defaultAutoPlaceOrder = true; | |
| } | |
| if (GlobalVariableCheck(_Symbol + "_PREFERRED_RR") && GlobalVariableGet(_Symbol + "_PREFERRED_RR") != 0) | |
| { | |
| defaultPreferredRR = GlobalVariableGet(_Symbol + "_PREFERRED_RR"); | |
| } | |
| TradePanel.Create(0, "Trade Panel", 0, 0, 0, 380, 185); | |
| radioGroup.Create(0, "radioGroup", 0, 0, 0, 90, 40); | |
| radioGroup.ColorBackground(clrWhite); | |
| radioGroup.ColorBorder(clrBlack); | |
| radioGroup.AddItem("Buy", 0); | |
| radioGroup.AddItem("Sell", 1); | |
| slLabel.Create(0, "slLabel", 0, 100, 8, 130, 8); | |
| slLabel.Text("SL"); | |
| slLabel.FontSize(12); | |
| slEdit.Create(0, "slEdit", 0, 130, 8, 220, 32); | |
| slEdit.FontSize(12); | |
| slEdit.TextAlign(ALIGN_CENTER); | |
| slEdit.Text(defaultSl); // have to implicitly convert to string | |
| tpLabel.Create(0, "tpLabel", 0, 230, 8, 260, 8); | |
| tpLabel.Text("TP"); | |
| tpLabel.FontSize(12); | |
| tpEdit.Create(0, "tpEdit", 0, 260, 8, 350, 32); | |
| tpEdit.FontSize(12); | |
| tpEdit.TextAlign(ALIGN_CENTER); | |
| tpEdit.Text(defaultTp); // have to implicitly convert to string | |
| riskLabel.Create(0, "riskLabel", 0, 55, 50, 50, 50); | |
| riskLabel.Text("Risk Amt"); | |
| riskLabel.FontSize(12); | |
| riskEdit.Create(0, "riskEdit", 0, 130, 50, 220, 74); | |
| riskEdit.FontSize(12); | |
| riskEdit.TextAlign(ALIGN_CENTER); | |
| riskEdit.Text(defaultRiskAmount); // have to implicitly convert to string | |
| rrLabel.Create(0, "rrLabel", 0, 230, 50, 260, 80); | |
| rrLabel.Text("RR"); | |
| rrLabel.FontSize(12); | |
| rrEdit.Create(0, "rrEdit", 0, 260, 50, 350, 74); | |
| rrEdit.FontSize(12); | |
| rrEdit.TextAlign(ALIGN_CENTER); | |
| rrEdit.ReadOnly(true); | |
| rrEdit.ColorBackground(clrGray); | |
| rrEdit.Color(clrWhite); | |
| spreadLabel.Create(0, "spreadLabel", 0, 65, 90, 85, 90); | |
| spreadLabel.Text("Spread"); | |
| spreadLabel.FontSize(12); | |
| spreadEdit.Create(0, "spreadEdit", 0, 130, 90, 220, 114); | |
| spreadEdit.FontSize(12); | |
| spreadEdit.TextAlign(ALIGN_CENTER); | |
| spreadEdit.ReadOnly(true); | |
| spreadEdit.ColorBackground(clrGray); | |
| spreadEdit.Color(clrWhite); | |
| placeOrderButton.Create(0, "placeOrderButton", 0, 260, 90, 350, 114); | |
| placeOrderButton.Text("PLACE ORDER"); | |
| autoPlaceOrderCheckbox.Create(0, "autoPlaceOrderCheckbox", 0, 40, 128, 260, 148); | |
| autoPlaceOrderCheckbox.Text("Auto place order when RR >="); | |
| autoPlaceOrderCheckbox.Checked(defaultAutoPlaceOrder); | |
| preferredRREdit.Create(0, "preferredRREdit", 0, 260, 125, 350, 149); | |
| preferredRREdit.FontSize(12); | |
| preferredRREdit.TextAlign(ALIGN_CENTER); | |
| preferredRREdit.Text(defaultPreferredRR); // have to implicitly convert to string | |
| TradePanel.Add(radioGroup); | |
| TradePanel.Add(slLabel); | |
| TradePanel.Add(slEdit); | |
| TradePanel.Add(tpLabel); | |
| TradePanel.Add(tpEdit); | |
| TradePanel.Add(riskLabel); | |
| TradePanel.Add(riskEdit); | |
| TradePanel.Add(rrLabel); | |
| TradePanel.Add(rrEdit); | |
| TradePanel.Add(spreadLabel); | |
| TradePanel.Add(spreadEdit); | |
| TradePanel.Add(placeOrderButton); | |
| TradePanel.Add(autoPlaceOrderCheckbox); | |
| TradePanel.Add(preferredRREdit); | |
| EventSetMillisecondTimer(200); | |
| TradePanel.Run(); | |
| ChartRedraw(); | |
| maxOpenTradesLabel.Create(0, "Max Open Trades Label", 0, 400, 0, 500, 10); | |
| maxOpenTradesLabel.FontSize(10); | |
| maxOpenTradesLabel.Text("Max Open Trades = " + IntegerToString(MaxOpenTrades) + ", Current Open Trades = " + IntegerToString(PositionsTotal())); | |
| maxTradesPerDayLabel.Create(0, "Max Trades Per Day Label", 0, 400, 20, 500, 30); | |
| maxTradesPerDayLabel.FontSize(10); | |
| maxTradesPerDayLabel.Text("Max Trades Per Day = " + IntegerToString(MaxTradesPerDay) + ", Current Trades Per Day = " + IntegerToString(GetCurrentTradesPerDay())); | |
| maxOrderSizeLabel.Create(0, "Max Order Size Label", 0, 400, 40, 500, 10); | |
| maxOrderSizeLabel.FontSize(10); | |
| maxOrderSizeLabel.Text("Max Order Size = " + DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX), 2)); | |
| currentTimeLabel.Create(0, "Current Time Label", 0, 400, 60, 500, 60); | |
| currentTimeLabel.FontSize(10); | |
| currentTimeLabel.Text(TimeTradeServer()); | |
| lotSizeLabel.Create(0, "Lot Size Label", 0, 400, 80, 500, 60); | |
| lotSizeLabel.FontSize(10); | |
| lotSizeLabel.Text("Lots:"); | |
| return(INIT_SUCCEEDED); | |
| } | |
| void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) | |
| { | |
| TradePanel.ChartEvent(id, lparam, dparam, sparam); | |
| if (sparam == "slEdit") | |
| { | |
| defaultSl = (double)slEdit.Text(); | |
| } | |
| else if (sparam == "tpEdit") | |
| { | |
| defaultTp = (double)tpEdit.Text(); | |
| } | |
| else if (sparam == "riskEdit") | |
| { | |
| defaultRiskAmount = (double)riskEdit.Text(); | |
| } | |
| else if (sparam == "preferredRREdit") | |
| { | |
| defaultPreferredRR = (double)preferredRREdit.Text(); | |
| } | |
| else if (sparam == "autoPlaceOrderCheckbox") | |
| { | |
| defaultAutoPlaceOrder = autoPlaceOrderCheckbox.Checked(); | |
| } | |
| if (id == CHARTEVENT_OBJECT_CLICK) | |
| { | |
| if (sparam == "placeOrderButton") | |
| { | |
| PlaceOrder(); | |
| } | |
| else if (sparam == "slEdit" || sparam == "tpEdit") | |
| { | |
| numChartClickedAfterSlTpEdit = 0; | |
| isSlEditLastClicked = sparam == "slEdit"; | |
| isTpEditLastClicked = sparam == "tpEdit"; | |
| if (isSlEditLastClicked) | |
| { | |
| editValue = slEdit.Text(); | |
| } | |
| else if (isTpEditLastClicked) | |
| { | |
| editValue = tpEdit.Text(); | |
| } | |
| } | |
| return; | |
| } | |
| if (id == CHARTEVENT_CLICK) | |
| { | |
| numChartClickedAfterSlTpEdit += 1; | |
| // we don't want to listen for chart click event that's immediately triggered after user clicks on sl and tp edit | |
| // and actually we just want to listen for the 2nd chart click event that's triggered after user clicks on sl and tp edit | |
| if (numChartClickedAfterSlTpEdit != 2) | |
| { | |
| return; | |
| } | |
| datetime time; | |
| double price; | |
| int subWindow; | |
| ChartXYToTimePrice(0, (int)lparam, (int)dparam, subWindow, time, price); | |
| if (StringFind(_Symbol, "US30") != -1 || StringFind(_Symbol, "US100") != -1 || StringFind(_Symbol, "US500") != -1 || StringFind(_Symbol, "BTC") != -1) | |
| { | |
| price = NormalizeDouble(price, 2); | |
| } | |
| else if (StringFind(_Symbol, "OIL") != -1) | |
| { | |
| price = NormalizeDouble(price, 3); | |
| } | |
| else if (StringFind(_Symbol, "GOLD") != -1 || StringFind(_Symbol, "XAUUSD") != -1) | |
| { | |
| price = NormalizeDouble(price, 2); | |
| } | |
| else if (StringLen(_Symbol) >= 6) | |
| { | |
| if (StringFind(_Symbol, "JPY") != -1) | |
| { | |
| price = NormalizeDouble(price, 3); | |
| } | |
| else | |
| { | |
| price = NormalizeDouble(price, 5); | |
| } | |
| } | |
| if (isSlEditLastClicked) | |
| { | |
| if (editValue == slEdit.Text()) | |
| { | |
| defaultSl = price; | |
| slEdit.Text(price); // have to implicitly convert to string | |
| ChartRedraw(); | |
| } | |
| isSlEditLastClicked = false; | |
| } | |
| else if (isTpEditLastClicked) | |
| { | |
| if (editValue == tpEdit.Text()) | |
| { | |
| defaultTp = price; | |
| tpEdit.Text(price); // have to implicitly convert to string | |
| ChartRedraw(); | |
| } | |
| isTpEditLastClicked = false; | |
| } | |
| } | |
| } | |
| void OnDeinit(const int reason) | |
| { | |
| GlobalVariableSet(_Symbol + "_SL", defaultSl); | |
| GlobalVariableSet(_Symbol + "_TP", defaultTp); | |
| GlobalVariableSet(_Symbol + "_RISK", defaultRiskAmount); | |
| GlobalVariableSet(_Symbol + "_AUTO_PLACE_ORDER", defaultAutoPlaceOrder ? 1 : 0); | |
| GlobalVariableSet(_Symbol + "_PREFERRED_RR", defaultPreferredRR); | |
| TradePanel.Destroy(reason); | |
| EventKillTimer(); | |
| } | |
| void OnTick() | |
| { | |
| UpdateAutoPlaceOrder(); | |
| UpdateSpread(); | |
| double rr = UpdateRr(); | |
| if (rr != NULL) | |
| { | |
| if (autoPlaceOrderCheckbox.Checked() && rr >= (double)preferredRREdit.Text()) | |
| { | |
| if (tpEdit.Text() != "" && slEdit.Text() != "" && riskEdit.Text() != "" && (radioGroup.Value() == 0 || radioGroup.Value() == 1)) | |
| { | |
| if (PlaceOrder()) | |
| { | |
| autoPlaceOrderCheckbox.Checked(false); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| void OnTimer() | |
| { | |
| UpdateComments(); | |
| UpdateAutoPlaceOrder(); | |
| UpdateRr(); | |
| } | |
| double PipToPrice(double val) | |
| { | |
| if ( | |
| StringFind(_Symbol, "US30") != -1 || | |
| StringFind(_Symbol, "US100") != -1 || | |
| StringFind(_Symbol, "NAS100") != -1 || | |
| StringFind(_Symbol, "US500") != -1 || | |
| StringFind(_Symbol, "BTC") != -1) | |
| { | |
| return val; | |
| } | |
| else if (StringFind(_Symbol, "OIL") != -1) | |
| { | |
| return val / 100; | |
| } | |
| else if (StringFind(_Symbol, "GOLD") != -1 || StringFind(_Symbol, "XAUUSD") != -1) | |
| { | |
| return val / 100; | |
| } | |
| else if (StringLen(_Symbol) >= 6) | |
| { | |
| if (StringFind(_Symbol, "JPY") != -1) | |
| { | |
| return val / 100; | |
| } | |
| else | |
| { | |
| return val / 10000; | |
| } | |
| } | |
| return val; | |
| } | |
| double GetRr() | |
| { | |
| double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); | |
| double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); | |
| double rawSpread = ask - bid; | |
| if (tpEdit.Text() != "" && slEdit.Text() != "") | |
| { | |
| double tp = GetTp(); | |
| double sl = GetSl(); | |
| if (radioGroup.Value() == 0) | |
| { | |
| if ((tp - ask) <= 0 || (ask - sl) <= 0) | |
| { | |
| return NULL; | |
| } | |
| return (tp - ask) / (ask - sl); | |
| } | |
| else if (radioGroup.Value() == 1) | |
| { | |
| if ((bid - tp) <= 0 || (sl + rawSpread - bid) <= 0) | |
| { | |
| return NULL; | |
| } | |
| // Increase sl by one spread in case of sell | |
| return (bid - tp) / (sl + rawSpread - bid); | |
| } | |
| } | |
| return NULL; | |
| } | |
| double GetTp() | |
| { | |
| double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); | |
| double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); | |
| bool tpInPips = StringSubstr(tpEdit.Text(), StringLen(tpEdit.Text()) - 1) == "p"; | |
| if (tpInPips) | |
| { | |
| double pips = (double)StringSubstr(tpEdit.Text(), 0, StringLen(tpEdit.Text()) - 1); | |
| return radioGroup.Value() == 0 ? ask + PipToPrice(pips) : bid - PipToPrice(pips); | |
| } | |
| return (double)tpEdit.Text(); | |
| } | |
| double GetSl() | |
| { | |
| double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); | |
| double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); | |
| bool slInPips = StringSubstr(slEdit.Text(), StringLen(slEdit.Text()) - 1) == "p"; | |
| if (slInPips) | |
| { | |
| double pips = (double)StringSubstr(slEdit.Text(), 0, StringLen(slEdit.Text()) - 1); | |
| return radioGroup.Value() == 0 ? ask - PipToPrice(pips) : bid + PipToPrice(pips); | |
| } | |
| return (double)slEdit.Text(); | |
| } | |
| void UpdateComments() | |
| { | |
| maxOpenTradesLabel.Text("Max Open Trades = " + IntegerToString(MaxOpenTrades) + ", Current Open Trades = " + IntegerToString(PositionsTotal())); | |
| maxTradesPerDayLabel.Text("Max Trades Per Day = " + IntegerToString(MaxTradesPerDay) + ", Current Trades Per Day = " + IntegerToString(GetCurrentTradesPerDay())); | |
| currentTimeLabel.Text(TimeTradeServer()); | |
| if (slEdit.Text() != "" && riskEdit.Text() != "" && (radioGroup.Value() == 0 || radioGroup.Value() == 1)) | |
| { | |
| bool isBuy = (radioGroup.Value() == 0); | |
| double open = isBuy ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); | |
| double sl = GetSl(); | |
| double rawSpread = SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID); | |
| double lotSize = LotsByRisk(_Symbol, isBuy, open, isBuy ? sl : (sl + rawSpread), (double)riskEdit.Text()); | |
| lotSizeLabel.Text("Lots: " + DoubleToString(lotSize, 2)); | |
| } | |
| else | |
| { | |
| lotSizeLabel.Text("Lots:"); | |
| } | |
| ChartRedraw(); | |
| } | |
| void UpdateAutoPlaceOrder() | |
| { | |
| if (PositionsTotal() >= MaxOpenTrades && autoPlaceOrderCheckbox.Checked()) | |
| { | |
| Print("Max open trades reached"); | |
| autoPlaceOrderCheckbox.Checked(false); | |
| } | |
| if (GetCurrentTradesPerDay() >= MaxTradesPerDay && autoPlaceOrderCheckbox.Checked()) | |
| { | |
| Print("Max trades per day reached"); | |
| autoPlaceOrderCheckbox.Checked(false); | |
| } | |
| ChartRedraw(); | |
| } | |
| double UpdateRr() | |
| { | |
| double rr = GetRr(); | |
| if (rr == NULL) | |
| { | |
| rrEdit.Text("NA"); | |
| } | |
| else | |
| { | |
| rrEdit.Text(DoubleToString(rr, 2)); | |
| } | |
| ChartRedraw(); | |
| return rr; | |
| } | |
| void UpdateSpread() | |
| { | |
| string spread = ""; | |
| double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); | |
| double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); | |
| if (StringFind(_Symbol, "US30") != -1 || StringFind(_Symbol, "US100") != -1 || StringFind(_Symbol, "US500") != -1 || StringFind(_Symbol, "BTC") != -1) | |
| { | |
| spread = DoubleToString(ask - bid, 2); | |
| } | |
| else if (StringFind(_Symbol, "OIL") != -1) | |
| { | |
| spread = DoubleToString((ask - bid) * 100, 1); | |
| } | |
| else if (StringFind(_Symbol, "GOLD") != -1 || StringFind(_Symbol, "XAUUSD") != -1) | |
| { | |
| spread = DoubleToString((ask - bid) * 100, 0); | |
| } | |
| else if ( | |
| StringFind(_Symbol, "USD") != -1 || | |
| StringFind(_Symbol, "EUR") != -1 || | |
| StringFind(_Symbol, "JPY") != -1 || | |
| StringFind(_Symbol, "GBP") != -1 || | |
| StringFind(_Symbol, "CHF") != -1 || | |
| StringFind(_Symbol, "AUD") != -1 || | |
| StringFind(_Symbol, "CAD") != -1 || | |
| StringFind(_Symbol, "NZD") != -1 | |
| ) | |
| { | |
| if (StringFind(_Symbol, "JPY") != -1) | |
| { | |
| spread = DoubleToString((ask - bid) * 100, 1); | |
| } | |
| else | |
| { | |
| spread = DoubleToString((ask - bid) * 10000, 1); | |
| } | |
| } | |
| else | |
| { | |
| spread = DoubleToString(ask - bid, _Digits); | |
| } | |
| spreadEdit.Text(spread); | |
| ChartRedraw(); | |
| } | |
| int GetCurrentTradesPerDay() | |
| { | |
| datetime todayMidnight = iTime(Symbol(), PERIOD_D1, 0); | |
| HistorySelect(todayMidnight, TimeCurrent()); | |
| ulong ticket = 0; | |
| int count = 0; | |
| for (int i = 0; i < HistoryDealsTotal(); i++) | |
| { | |
| if ((ticket = HistoryDealGetTicket(i)) > 0) | |
| { | |
| if (HistoryDealGetInteger(ticket, DEAL_ENTRY) == DEAL_ENTRY_IN) | |
| { | |
| count++; | |
| } | |
| } | |
| } | |
| return count; | |
| } | |
| bool PlaceOrder() | |
| { | |
| double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); | |
| double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); | |
| if (PositionsTotal() >= MaxOpenTrades) | |
| { | |
| Print("Max open trades reached"); | |
| return false; | |
| } | |
| if (GetCurrentTradesPerDay() >= MaxTradesPerDay) | |
| { | |
| Print("Max trades per day reached"); | |
| return false; | |
| } | |
| double tp = GetTp(); | |
| double sl = GetSl(); | |
| if (tpEdit.Text() == "" || slEdit.Text() == "") | |
| { | |
| Print("Please set SL and TP."); | |
| return false; | |
| } | |
| if (riskEdit.Text() == "") | |
| { | |
| Print("Please set risk."); | |
| return false; | |
| } | |
| if (radioGroup.Value() != 0 && radioGroup.Value() != 1) | |
| { | |
| Print("Please select Buy or Sell."); | |
| return false; | |
| } | |
| bool isBuy = (radioGroup.Value() == 0); | |
| double open = isBuy ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); | |
| double rawSpread = ask - bid; | |
| double lotSize = LotsByRisk(_Symbol, isBuy, open, isBuy ? sl : (sl + rawSpread), (double)riskEdit.Text()); | |
| if (lotSize > 0) | |
| { | |
| if (radioGroup.Value() == 0) | |
| { | |
| return PlaceOrderBuy(lotSize, sl, tp); | |
| } | |
| else | |
| { | |
| return PlaceOrderSell(lotSize, sl + rawSpread, tp); | |
| } | |
| } | |
| else | |
| { | |
| Print("Invalid lot size: " + DoubleToString(lotSize)); | |
| return false; | |
| } | |
| } | |
| bool PlaceOrderBuy(double lotSize, double sl, double tp) | |
| { | |
| double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); | |
| if (sl >= ask) | |
| { | |
| Print("To buy, SL should be less than Ask!"); | |
| return false; | |
| } | |
| if (tp <= ask) | |
| { | |
| Print("To buy, TP should be more than Ask!"); | |
| return false; | |
| } | |
| double remainingLotSize = lotSize; | |
| do { | |
| MqlTradeRequest request = {}; | |
| MqlTradeResult result = {}; | |
| request.action = TRADE_ACTION_DEAL; | |
| request.symbol = _Symbol; | |
| request.volume = MathMin(remainingLotSize, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX)); | |
| request.type = ORDER_TYPE_BUY; | |
| request.type_filling = ORDER_FILLING_FOK; | |
| request.sl = sl; | |
| request.tp = tp; | |
| OrderSend(request, result); | |
| if (result.retcode != 10009 && result.retcode != 10010) | |
| { | |
| Print("Lotsize = " + DoubleToString(MathMin(remainingLotSize, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX)))); | |
| Print("OrderSend failed with error #", result.retcode); | |
| return false; | |
| } | |
| remainingLotSize -= SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); | |
| } | |
| while (remainingLotSize > 0); | |
| Print("OrderSend placed successfully"); | |
| return true; | |
| } | |
| bool PlaceOrderSell(double lotSize, double sl, double tp) | |
| { | |
| double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); | |
| if (sl <= bid) | |
| { | |
| Print("To sell, SL should be more than Bid!"); | |
| return false; | |
| } | |
| if (tp >= bid) | |
| { | |
| Print("To sell, TP should be less than Bid!"); | |
| return false; | |
| } | |
| double remainingLotSize = lotSize; | |
| do { | |
| MqlTradeRequest request = {}; | |
| MqlTradeResult result = {}; | |
| request.action = TRADE_ACTION_DEAL; | |
| request.symbol = _Symbol; | |
| request.volume = MathMin(remainingLotSize, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX)); | |
| request.type = ORDER_TYPE_SELL; | |
| request.type_filling = ORDER_FILLING_FOK; | |
| request.sl = sl; | |
| request.tp = tp; | |
| OrderSend(request, result); | |
| if (result.retcode != 10009 && result.retcode != 10010) | |
| { | |
| Print("Lotsize = " + DoubleToString(MathMin(remainingLotSize, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX)))); | |
| Print("OrderSend failed with error #", result.retcode); | |
| return false; | |
| } | |
| remainingLotSize -= SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); | |
| } | |
| while (remainingLotSize > 0); | |
| Print("OrderSend placed successfully"); | |
| return true; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment