OrderClose not working in MQL4 without proper error feedback - mql4

So I have this EA that should close 2 trades together under certain conditions. Sometimes it closes only 1/2, sometimes it closes both smoothly. I cannot really pinpoint the times it closes only one and detect a pattern so I can spot the logical error.
P.S.: Obviously the trades are from different pairs running from an EA within 1 chart/pair.
The error message is this:
invalid ticket for OrderClose function
But the trade clearly exists, and i make sure I have it within the int as every time I restart the EA, if trade is already open (detected by comment) it has a message like that:
"Buy trade: [ticket number], recognised."
So I know for fact that it is recognised and within the proper int to be used. Any ideas about the error's source?
OrderClose(TicketA,LotSize,iClose(NULL,0,0),Slippage,clrGray);
OrderClose(TicketB,LotSize,iClose(SymbolB,0,0),Slippage,clrGray);
Will this fix this? I mean... it will be errored out 2/4 close orders... but I don't really care about how beautiful it looks.
OrderClose(TicketA,LotSize,Ask,Slippage,clrGray);
OrderClose(TicketB,LotSize,Bid,Slippage,clrGray);
OrderClose(TicketA,LotSize,Ask,Slippage,clrGray);
OrderClose(TicketB,LotSize,Ask,Slippage,clrGray);

Make sure that you didn't override TicketA or TicketB variable somewhere.
You can use OrderLots() function instead of using LotSize, especially when this value is changing during EA process. Additionally, by checking the OrderType(), you will avoid a mistake at the closing price.
Example:
if(yourCloseCondition){
if(OrderSelect(ticket, SELECT_BY_TICKET)){
if(OrderType() == OP_BUY){
if(OrderClose(ticket, OrderLots(), Bid, 0)){
//Print("success");
}
}
if(OrderType() == OP_SELL){
if(OrderClose(ticket, OrderLots(), Ask, 0)){
//Print("success");
}
}
}
}
Also check docs: OrderClose() and OrderType().
Update:
For different pairs running within 1 chart use close price from MarketInfo
Example:
MarketInfo("EURUSD",MODE_BID);
Check MarketInfo().

Related

Why is this basic MQL4-code taking so much time to load up on my MT4?

I am learning MQL4 language and am using this Code to plot a Simple moving Average, the Code works fine, but when I load it up on my MT4 it takes a lot of time, am I missing something ?
int start() // Special function start()
{
int i, // Bar index
n, // Formal parameter
Counted_bars; // Number of counted bars
// Sum of Low values for period
// --------------------------------------------------------------------
Counted_bars=IndicatorCounted(); // Number of counted bars
i=Bars-Counted_bars-1; // Index of the first uncounted
while(i>=0) // Loop for uncounted bars
{
Buf_0[i]=(iMA(Symbol(),PERIOD_M5,200,i,MODE_EMA,PRICE_HIGH,0);
i--; // Calculating index of the next bar
}
// --------------------------------------------------------------------
return; // Exit the special funct. start()
}
// --------------------------------------------------------------------
Q : am I missing something?
No, this is a standard feature to process all the Bars back, towards the earliest parts of the history.
If your intentions require a minimum setup-time, it is possible to "shorten" the re-painted part of the history to just, say, last week, not going all the way back all the Bars-number of Bars a few years back, as all that data have been stored in the OHLCV-history database.
That "shortened"-part of the history will this way become as long as your needs can handle and not a single bar "longer".
Hooray, The Problem was solved.
BONUS PART :
Given your code instructs to work with EMA, not SMA, there is one more vector of attack onto the shortest possible time.
For EMA, any next Bar value will become a product of alfa * High[next] added to a previously known as EMA[next+1]
Where a constant alfa = 2. / ( N_period + 1 ) is known and constant across the whole run of the history processed.
This approach helped me gain about ~20-30 [us] FASTER processing for a 20-cell Price-vector, when using this algorithmic shortcut on an array of float32-values compared to cell-by-cell processing. Be sure to benchmark the code for your use-case and may polish further tricks with using different call-signatures of iHigh() instead of accessing an array of High[]-s for any potential speedups, if in utmost need to shave-off any further [us] possible.

Is there a reason why this code is not outputting a worth

Problem
Hello, StackOverflow community! I am working on this Lua game, and I was testing to see if it would change the text on my TextLabel to the Bitcoins current worth, I was utterly disappointed when nothing showed up.
I have tried to do research on Google, and my code seems to be just right.
Code
Change = false
updated = false
while Change[true] do --While change = true do
worth = math.random(1,4500) --Pick random number
print('Working!') --Say its working
Updated = true --Change the updated local var.
end --Ending while loop
script.Parent.TextLabel.Text.Text = 'Bitcoin is currently worth: ' .. worth
--Going to the Text, and changing in to a New worth.
while Updated[false] do --While updated = false do
wait(180) --Wait
Change = true --After waits 3 minutes it makes an event trigger
end -- Ending while loop
wait(180) --Wait
Updated = false --Reseting Script.
I expect the output on the Label to be a random number.
I can't really speak to roblox, but there are a couple of obvious problems with your code:
Case
You have confusion between capitalized ("Updated", "Change") and lowercase ("updated", "change" [in commented while statement]), which will fail. See, for example:
bj#bj-lt:~$ lua
Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> Updated = true
> print(Updated)
true
> print(updated)
nil
So be super-careful about what identifiers you capitalize. In general, most programmers leave variables like that in all-lowercase (or sometimes things like camelCase). I suppose there might be some oddball lua runtime out there that is case-insensitive, but I don't know of one.
Type misuse.
Updated is a boolean (a true/false value), so the syntax:
while Change[true] do
...is invalid. See:
> if Updated[true] then
>> print("foo")
>> end
stdin:1: attempt to index global 'Updated' (a boolean value)
stack traceback:
stdin:1: in main chunk
[C]: in ?
Note also that the "While change == true do" is also wrong because of case ("While" is not valid lua, but "while" is).
Lastly:
Lack of threading.
You have basically two different things that you're trying to do at once, namely randomly change the "worth" variable as fast as possible (it's in a loop) and see a set a label to match it (it looks like you probably want it to change constantly). This requires two threads of operation (one to change worth and another to read it and stick it on the label). You've written this like you're assuming you have a spreadsheet or something and that. What your code is actually doing is:
Setting some variables
Updating worth indefinitely, printing 'Working!' a bunch, and...
Never stopping
The rest of the code never runs, because the rest of the code isn't in a background thread (basically the first bit monopolizes the runtime and never yields to everything else).
Lastly, even if the top code was running in the background, you only set the Text label one-time to exactly "Bitcoin is currently worth: 3456" (or some similar number) one time. The way this is written there won't be any updates thereafter (and, if it runs once before the other thread has warmed up, it might not be set to anything useful at all).
My guess is that your runtime is spitting out errors left and right due to the identifier problems and/or is running in a tight infinite loop and never actually getting to the label refresh logic.
BJ Black has given an excellent description of the issues with the syntax, so I'll try to cover the Roblox piece of this. In order for this kind of thing to work properly in a Roblox game, here are some assumptions to double check :
Since we are working with a TextLabel, is it inside a ScreenGui? Or a SurfaceGui?
If it's in a ScreenGui, make sure that ScreenGui is in StarterGui, and is this code in a LocalScript
If it's in a SurfaceGui, make sure that SurfaceGui is adorning a Part and this code
is in a Script
After you checked all those pieces, maybe this is closer to what you were thinking :
-- define the variables we're working with
local textLabel = script.Parent.TextLabel
local worth = 0
-- create an infinite loop
spawn(function()
while true do
--Pick random number
worth = math.random(1,4500)
-- update the text of the label with the new worth
textLabel.Text = string.format("Bitcoin is currently worth: %d", worth)
-- wait for 3 minutes, then loop
wait(180)
end
end)
I removed Updated and Changed because all they were doing was deciding whether or not to change the value. The flow of your loop was:
do nothing and display an undefined number. Wait 3 minutes
update the number, display it, wait 6 minutes
repeat 1 and 2.
So hopefully this is a little clearer and closer to what you were thinking.

Script stops after a few seconds

I have this exploit for Murder Mystery 2.
It is a tpcoins and esp exploit. When I enable the tpcoins it will turn off after a few seconds. Is there any way of making it so it stays on?
Here's the code:
function enableTpCoin()
if nameMap ~= "" and wp[nameMap] ~= nil then
if lplr.PlayerGui.MainGUI.Game.CashBag:FindFirstChild("Elite") then
tpCoin(10)
elseif lplr.PlayerGui.MainGUI.Game.CashBag:FindFirstChild("Coins") then
tpCoin(15)
end
end
Trigger to start the script is q.
Short answer, you can't. Since this is script related I'll answer your question.
So each round, the player can only earn 10 coins, and 15 if they have purchased the "Elite" gamepass.
This meaning that the game physically doesn't allow you to add anymore per round. You'll have to execute the code at the launch of every round.
The game has FE, so it's most likely that the original developer of the game has specified the remote events to only accept 10 or 15 coins depending on the boolean value whether the user is "Elite" or not.
Even if Universal Link says the truth, here's the solution.
Create a new function. In that function, do a while loop with a interval (use wait(.1)), and in that while loop, call enableTpCoin().
Now, call spawn() and pass the function you created as an argument.
The code should look like this:
function _loop()
while wait(.1) do
enableTpCoin()
end
end
spawn(_loop)

What is the correct way to set StopLoss and TakeProfit in OrderSend() in MetaTrader4 EA?

I'm trying to figure out if there is a correct way to set the Stop Loss (SL) and Take Profit (TP) levels, when sending an order in an Expert Advisor, in MQL4 (Metatrader4). The functional template is:
OrderSend( symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color);
So naturally I've tried to do the following:
double dSL = Point*MM_SL;
double dTP = Point*MM_TP;
if (buy) { cmd = OP_BUY; price = Ask; SL = ND(Bid - dSL); TP = ND(Ask + dTP); }
if (sell) { cmd = OP_SELL; price = Bid; SL = ND(Ask + dSL); TP = ND(Bid - dTP); }
ticket = OrderSend(SYM, cmd, LOTS, price, SLIP, SL, TP, comment, magic, 0, Blue);
However, there are as many variations as there are scripts and EA's. So far I have come across these.
In the MQL4 Reference in the MetaEditor, the documentation say to use:
OrderSend(Symbol(),OP_BUY,Lots,Ask,3,
NormalizeDouble(Bid - StopLoss*Point,Digits),
NormalizeDouble(Ask + TakeProfit*Point,Digits),
"My order #2",3,D'2005.10.10 12:30',Red);
While in the "same" documentation online, they use:
double stoploss = NormalizeDouble(Bid - minstoplevel*Point,Digits);
double takeprofit = NormalizeDouble(Bid + minstoplevel*Point,Digits);
int ticket=OrderSend(Symbol(),OP_BUY,1,price,3,stoploss,takeprofit,"My order",16384,0,clrGreen);
And so it goes on with various flavors, here, here and here...
Assuming we are interested in a OP_BUY and have the signs correct, we have the options for basing our SL and TP values on:
bid, bid
bid, ask
ask, ask
ask, bid
So what is the correct way to set the SL and TP for a BUY?
(What are the advantages or disadvantages of using the various variations?)
EDIT: 2018-06-12
Apart a few details, the answer is actually quite simple, although not obvious. Perhaps because MT4 only show Bid prices on the chart (by default) and not both Ask and Bid.
So because: Ask > Bid and Ask - Bid = Slippage, it doesn't matter which we choose as long as we know about the slippage. Then depending on what price you are following on the chart, you may wish to decide on using one over the other, adding or subtracting the Slippage accordingly.
So when you use the measure tool to get the Pip difference of currently shown prices, vs your "exact" SL/TP settings, you need to keep this in mind.
So to avoid having to put the Slippage in my code above, I used the following for OP_BUY: TP = ND(Bid + dTP); (and the opposite for OP_SELL.)
If you buy, you OP_BUY at Ask and close (SL, TP) at Bid.
If you sell, OP_SELL operation is made at Bid price, and closes at Ask.
Both SL and TP should stay at least within STOP_LEVEL * Point() distance from the current price to close ( Bid for buy, Ask for sell).
It is possible that STOP_LEVEL is zero - in such cases ( while MT4 accepts the order ) the Broker may reject it, based on its own algorithms ( Terms and Conditions may call it a "floating Stoplevel" rule or some similar Marketing-wise "re-dressed" term ).
It is adviced to send an OrderSend() request with zero values of SL and TP and modify it after you see that the order was sent successfully. Sometimes it is not required, sometimes that is even mandatory.
There is no difference between the two links you gave us: you may compute SL and TP and then pass them into the function or compute them based on OrderOpenPrice() +/- distance * Point().
So what is the correct way to set the SL and TP for a BUY ?
There is no such thing as "The Correct Way", there are rules to meet
Level 0: Syntax is to meet the call-signature ( the easiest one )
Level 1: all at Market XTO-s have to meet the right level of the current Price +/- slippage, make sure to repeat a RefreshRates()-test as close to the PriceDOMAIN-levels settings, otherwise they get rejected from the Broker side ( blocking one's trading engine at a non-deterministic add-on RTT-latency ) + GetLastError() == 129 | ERR_INVALID_PRICE
Level 2: yet another rules get set from Broker-side, in theire respective Service / Product definition in [ Trading Terms and Conditions ]. If one's OrderSend()-request fails to meet any one of these, again, the XTO will get rejected, having same adverse blocking effects, as noted in Level 1.
Some Brokers do not allow some XTO situations due to their T&C, so re-read such conditions with a due care. Any single of theirs rule, if violated, will lead to your XTO-instruction to get legally rejected, with all adverse effects, as noted above. Check all rules, as you will not like to see any of the following error-states + any of others, restricted by your Broker's T&C :
ERR_LONG_POSITIONS_ONLY_ALLOWED Buy orders only allowed
ERR_TRADE_TOO_MANY_ORDERS The amount of open and pending orders has reached the limit set by the broker
ERR_TRADE_HEDGE_PROHIBITED An attempt to open an order opposite to the existing one when hedging is disabled
ERR_TRADE_PROHIBITED_BY_FIFO An attempt to close an order contravening the FIFO rule
ERR_INVALID_STOPS Invalid stops
ERR_INVALID_TRADE_VOLUME Invalid trade volume
...
..
.
#ASSUME NOTHING ; Is the best & safest design-side (self)-directive

Logic behind COBOL code

I am not able to understand what is the logic behind these lines:
COMPUTE temp = RESULT - 1.843E19.
IF temp IS LESS THAN 1.0E16 THEN
Data definition:
000330 01 VAR1 COMP-1 VALUE 3.4E38. // 3.4 x 10 ^ 38
Here are those lines in context (the sub-program returns a square root):
MOVE VAR1 TO PARM1.
CALL "SQUAREROOT_ROUTINE" USING
BY REFERENCE PARM1,
BY REFERENCE RESULT.
COMPUTE temp = RESULT - 1.843E19.
IF temp IS LESS THAN 1.0E16 THEN
DISPLAY "OK"
ELSE
DISPLAY "False"
END-IF.
These lines are just trying to test if the result returned by the SQUAREROOT_ROUTINE is correct. Since the program is using float-values and rather large numbers this might look a bit complicated. Let's just do the math:
You start with 3.4E38, the squareroot is 1.84390889...E19.
By subtracting 1.843E19 (i.e. the approximate result) and comparing the difference against 1.0E16 the program is testing whether the result is between 1.843E19 and 1.843E19+1.0E16 = 1.844E19.
Not that this test would not catch an error if the result from SQUAREROOT_ROUTINE was too low instead of too high. To catch both types of wrong results you should compare the absolute value of the difference against the tolerance.
You might ask "Why make things so complicated"? The thing is that float-values usually are not exact and depending on the used precision you will get sightly different results due to rounding-errors.
well the logic itself is very straight forward, you are subtracting 1.843*(10^19) from the result you get from the SQUAREROOT_ROUTINE and putting that value in the variable called temp and then If the value of temp is less than 1.0*(10^16) you are going to print a line out to the SYSOUT that says "OK", otherwise you are going to print out "False" (if the value was equal to or greater than).
If you mean the logic as to why this code exists, you will need to talk to the author of the code, but it looks like a debugging display that was left in the program.

Resources