How to disable autotrading globally from MQL4/5 program (EA) without DLLs? - algorithmic-trading

How do I disable autotrading globally in MetaTrader 4/5 from within MQL4/5 code without using DLLs?

Here you go, (Author is Tiago Praxedes)
#define MT_WMCMD_EXPERTS 32851
#define WM_COMMAND 0x0111
#define GA_ROOT 2
#include <WinAPI\winapi.mqh>
void SetAlgoTradingStatus(bool Enable)
{
bool Status = (bool) TerminalInfoInteger(TERMINAL_TRADE_ALLOWED);
if(Enable != Status)
{
HANDLE hChart = (HANDLE) ChartGetInteger(ChartID(), CHART_WINDOW_HANDLE);
PostMessageW(GetAncestor(hChart, GA_ROOT), WM_COMMAND, MT_WMCMD_EXPERTS, 0);
}
}
void OnTick()
{
SetAlgoTradingStatus(false);
}
Lifted it from here: Source

Yes, MQL4/5 Expert Adviser may locally forbid self to trade this way:
if ( IsTradeAllowed() )
{ Comment( __FILE__, " [EA] Trading is allowed, will disable self." );
...
}
else
{ Comment( __FILE__, " [EA] Trading is not allowed, will disable self." );
...
}
// ---------------------------------------// GRACEFULLY RELEASE ALL RESOURCES BEFORE FIN'd
// ********
// FINALLY: EXPERT-ADVISOR SIG_TERM -> self ( MT4 )
ExpertRemove(); /* MT4 The Expert Advisor
is not stopped immediately
as you call ExpertRemove();
just a flag to stop the EA operation is set.
That is:
- any next event won't be processed,
- OnDeinit() will be called
and
- the Expert Advisor will be unloaded and removed from the chart.
*/

If the idea is that you have several EA's on different pairs and you want to disable them all at the same time you could place a specific trade, that I would call an information trade and not meant to be used for trading.
Choose a price very far away from current price.
For this example, we can use 9,999.000 as price and we place the trade.
Loop through the trades and look for a price = 9999.
If you find it use that to disable trading.
If you want it to start again, you can have a button or manually delete that trade that is 9999.
Now the block is not there.
All the EA's you may have going can see this.
Also, an offsite computer will be able to see it as well.
This was used as a way to hand off trading control to a team of traders.
The new owner would send the trade that bumps everyone off.
Remove that trade but the other EA's are asleep until a human turns them back on or a "Wake Up" trade is sent.
You can send values in the Comment, TP and SL values as prices.
There are many ways to use this method.
For this to work though you would have to have your own code and make the changes. If you buy an EA and want to turn it on and off without the source code then this method won't work.

Related

performing logical NOT based on configurable data

I would like to configure my switch input type as either active high or active low. I wrote below code and I know it will not work because I when I multiply by 0, nothing works. One way is to write code to check ACTIVE LOW using if statement and handle. But I am sure there could be a simple method to perform logical NOT operation based on configurable bits. How to make the readSwitch() function configurable depending on switch input types?
#define ACTIVE_LOW 0
#define ACTIVE_HIGH 1
#define SWITCH_TYPE ACTIVE_LOW
uint8_t readSwitch(uint8_t pinNum)
{
uint8_t state=0;
if(SWITCH_TYPE*(PINC&(1<<pinNum)))
{
_delay_ms(20);
if(SWITCH_TYPE*(PINC&(1<<pinNum)))
{
state=1;
}
}
return(state);
}
Based on #AterLux comment and further analysis, below code could take care.
if(!(PINC&(1<<pinNum))^SWITCH_TYPE)

lock-free synchronization, fences and memory order (store operation with acquire semantics)

I am migrating a project that was run on bare-bone to linux, and need to eliminate some {disable,enable}_scheduler calls. :)
So I need a lock-free sync solution in a single writer, multiple readers scenario, where the writer thread cannot be blocked. I came up with the following solution, which does not fit to the usual acquire-release ordering:
class RWSync {
std::atomic<int> version; // incremented after every modification
std::atomic_bool invalid; // true during write
public:
RWSync() : version(0), invalid(0) {}
template<typename F> void sync(F lambda) {
int currentVersion;
do {
do { // wait until the object is valid
currentVersion = version.load(std::memory_order_acquire);
} while (invalid.load(std::memory_order_acquire));
lambda();
std::atomic_thread_fence(std::memory_order_seq_cst);
// check if something changed
} while (version.load(std::memory_order_acquire) != currentVersion
|| invalid.load(std::memory_order_acquire));
}
void beginWrite() {
invalid.store(true, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
}
void endWrite() {
std::atomic_thread_fence(std::memory_order_seq_cst);
version.fetch_add(1, std::memory_order_release);
invalid.store(false, std::memory_order_release);
}
}
I hope the intent is clear: I wrap the modification of a (non-atomic) payload between beginWrite/endWrite, and read the payload only inside the lambda function passed to sync().
As you can see, here I have an atomic store in beginWrite() where no writes after the store operation can be reordered before the store. I did not find suitable examples, and I am not experienced in this field at all, so I'd like some confirmation that it is OK (verification through testing is not easy either).
Is this code race-free and work as I expect?
If I use std::memory_order_seq_cst in every atomic operation, can I omit the fences? (Even if yes, I guess the performance would be worse)
Can I drop the fence in endWrite()?
Can I use memory_order_acq_rel in the fences? I don't really get the difference -- the single total order concept is not clear to me.
Is there any simplification / optimization opportunity?
+1. I happily accept any better idea as the name of this class :)
The code is basically correct.
Instead of having two atomic variables (version and invalid) you may use single version variable with semantic "Odd values are invalid". This is known as "sequential lock" mechanism.
Reducing number of atomic variables simplifies things a lot:
class RWSync {
// Incremented before and after every modification.
// Odd values mean that object in invalid state.
std::atomic<int> version;
public:
RWSync() : version(0) {}
template<typename F> void sync(F lambda) {
int currentVersion;
do {
currentVersion = version.load(std::memory_order_seq_cst);
// This may reduce calls to lambda(), nothing more
if(currentVersion | 1) continue;
lambda();
// Repeat until something changed or object is in an invalid state.
} while ((currentVersion | 1) ||
version.load(std::memory_order_seq_cst) != currentVersion));
}
void beginWrite() {
// Writer may read version with relaxed memory order
currentVersion = version.load(std::memory_order_relaxed);
// Invalidation requires sequential order
version.store(currentVersion + 1, std::memory_order_seq_cst);
}
void endWrite() {
// Writer may read version with relaxed memory order
currentVersion = version.load(std::memory_order_relaxed);
// Release order is sufficient for mark an object as valid
version.store(currentVersion + 1, std::memory_order_release);
}
};
Note the difference in memory orders in beginWrite() and endWrite():
endWrite() makes sure that all previous object's modifications have been completed. It is sufficient to use release memory order for that.
beginWrite() makes sure that reader will detect object being in invalid state before any futher object's modification is started. Such garantee requires seq_cst memory order. Because of that reader uses seq_cst memory order too.
As for fences, it is better to incorporate them into previous/futher atomic operation: compiler knows how to make the result fast.
Explanations of some modifications of original code:
1) Atomic modification like fetch_add() is intended for cases, when concurrent modifications (like another fetch_add()) are possible. For correctness, such modifications use memory locking or other very time-costly architecture-specific things.
Atomic assignment (store()) does not use memory locking, so it is cheaper than fetch_add(). You may use such assignment because concurrent modifications are not possible in your case (reader does not modify version).
2) Unlike to release-acquire semantic, which differentiate load and store operations, sequential consistency (memory_order_seq_cst) is applicable to every atomic access, and provide total order between these accesses.
The accepted answer is not correct. I guess the code should be something like "currentVersion & 1" instead of "currentVersion | 1". And subtler mistake is that, reader thread can go into lambda(), and after that, the write thread could run beginWrite() and write value to non-atomic variable. In this situation, write action in payload and read action in payload haven't happens-before relationship. concurrent access (without happens-before relationship) to non-atomic variable is a data race. Note that, single total order of memory_order_seq_cst does not means the happens-before relationship; they are consistent, but two kind of things.

How to setup a period of time in an MQL4 source code?

I am using MQL4.
Currently, I am using [Expert Advisor]-s in MT4.StrategyTester, and set a period-of-time by the build-in pull-down calendar GUI-elements.
What I want to do is to setup a period-of-time straight in an MQL4-source code.
If it is realized, for example, I can compare the result
'from 2011/01-to 2011/12'
to
'from 2012/01-to 2012/12'
and so on.
There is an easy solution to the requirement, even with an added value for a fully automated, large-scale hyper-parameter optimisations inside the said MT4.StrategyTester tool, using the proposed pair of parameters ( aStartFromDATE and aRunTillDATE ) as an iterable tuple, that could be harnessed into a TradingStrategy robustness cross-validations of its release-candidates over some sweeping/sliding calendar window-of-time.
extern datetime aStartFromDATE = D'2010.01.01 00:00';
extern datetime aRunTillDATE = D'2345.01.01 00:00';
void OnTick(){
if ( Time < aStartFromDATE
|| Time > aRunTillDATE
){
IgnoreTicksOutsideTheGivenPeriodOfTime();
return;
}
// SURE TO BE INSIDE THE GIVEN ( MT4.STRATEGY/TESTER ITERABLE ) PERIOD OF TIME
...
..
.
}
void IgnoreTicksOutsideTheGivenPeriodOfTime(){
// Ignore, but still may do execute some utility service during a void run
}
Be careful on different scopes of syntax support:
One might be also cautious on use-cases, that include StrategyTester restrictions for some of the powerful new-syntax-constructors:
A PrintFormat() being one of such un-supported pieces inside the StrategyTester during hyper-parameter optimisations.
PrintFormat() function does not work during optimization in the Strategy Tester.

Solving tcsncpy_s.inl assertion (line 24)

I've a fairly simple program which needs user input in the form of a text string. I've a CLR form with an edit box and I need to take that input and pass it into my class which just copies it to a member variable.
In the Form.h code, handling the TextChanged event is...
int textLength = m_userDest->TextLength;
if (textLength > 2 && textLength < 5)
{
// Could be an ICAO code in here
char dest[5];
String^ text = m_userDest->Text->ToUpper();
sprintf_s(dest, 5, "%s", text);
airTraffic.SetUserDest(dest);
}
My class (airTraffic) SetUserDest function is just
void CAirTraffic::SetUserDest(char* dest)
{
strncpy_s(m_userDest, 5, dest, 5);
}
When this is run I get this debug assertion, it doesn't stay on the screen and automatically clears after a few seconds.
Debug Assertion Failed!
Program: ...sual Studio 2010\Projects\FSAirTraffic\Debug\FSAirTraffic.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\tcsncpy_s.inl
Line: 24
Expression: ((_Dst)) != NULL && ((_SizeInBytes)) > 0
I don't have an f:\ drive so I'm guessing this is some internal Microsoft(?) code so I can't see the context of the assertion and exactly what it's problem is. I don't have a file called tcsncpy_s.inl on my machine.
If I don't call my class function then there's no assertion so I assumed that was the problem.
Curiously though, when stepping through the debugger the assertion occurs as I step out of the TextChanged event, with the rest of the functions operating as intended (as far as I can see).
Does anyone know what the problem is and how I can go about solving it?
I don't understand how your code works. You use m_userDest twice, first it appears to be a pointer to a structure of some sort, maybe a handle to a TextBox control:
int textLength = m_userDest->TextLength;
Later you pass it to strncpy_s, which needs a char*, not a pointer to some structure.
void CAirTraffic::SetUserDest(char* dest)
{
strncpy_s(m_userDest, 5, dest, 5);
}
While it's possible for a structure to implicitly convert to a char*, it's not possible for a structure pointer to do so. Perhaps there's a smart pointer involved? Or you are using the same member variable name for completely different purposes in different classes1?
In any case, strncpy_s is inspecting the value of its first argument and not liking it.
1 Note that the new "wisdom" saying not to use Hungarian notation has destroyed the ability to understand this code in textual form. We don't have an IDE providing mouseover information about the data type of variables. Applications Hungarian is still a good idea in the real world, despite how many "best practices" documents decry it. Amazing how many code style documents are written from a purely theoretical basis.

Does ShellExecuteW(...) work only once in MetaTrader 4 or not?

Trying to launch an .exe from MQL4 using ShellExecuteW().
Does this command work only once, or not?
#import "shell32.dll" // MQL4-syntax-wrapper-Bo[#import]Container
// v-------------- caller-side interface to DLL
int ShellExecuteW( int hWnd,
int lpVerb,
string lpFile,
int lpParameters,
int lpDirectory,
int nCmdShow
);
#import // MQL4-syntax-wrapper-Eo[#import]Container
if ( cond == true ){
ShellExecuteW( 0, "open", "D:\\Execute.exe", "", "", 1 );
}
A: a short version
Maybe yes, maybe no.
A: a bit more indepth one [TLDR]
Fact:
MT4 Terminal's process-control / process-management is nothing superior, however it allows you to integrate several lines of control over what happens inside ( and outside ... not only via ShellExecuteW(...) ... ) the MT4 Terminal.
MT4 Terminal supports the following processes per graph ( via built-in threads ):
{ 0 | 1 } occurences of a singleton instance called MQL4-ExpertAdvisor
{ 0 | 1 } occurences of a singleton instance called MQL4-Script
{ 0 | 1 ... n } occurences of a functionally restricted instance called MQL4-TechnicalIndicator
The nature of these instances differs in several ways, however in the closest relation to your question, each of the processes have both a mandatory part and a set of arbitrary parts.
Speaking in the original MQL4 ( one may have noticed, that since Build 7xx MQL4 language syntax has moved closer and closer towards MQL5, thus sometimes got labeled as MQL4.5 :o) )
//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
//
// MQL4 code ----------------------------------------------------------<BoF>------
// MQL4 code compiler directives' section -----------------------<BoS>
#import ... // MQL4-syntax-wrapper-Bo[#import]Container
..
.
#import // MQL4-syntax-wrapper-Eo[#import]Container
// MQL4 code compiler directives' section -----------------------<EoS>
// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//
// MQL4 code section ---------------------------- init() / start() / deinit()
//
int init(){ // this part is being run just once,
// right upon an instance activation
}
int start(){ // this part is being run just once, for an MQL4-Script
// right upon an instance activation
// run upon an FX-MarketEvent is being observed
// in an MQL4-ExpertAdvisor
// or
// in an MQL4-TechnicalIndicator
}
...
..
.
//
// MQL4 code ---------------------------------------------------------<EoF>------
//
//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
So, the exact location of your deployment code, that (re-)uses the generic DLL-service ( #import-ed for both the compile-time alignment and the dynamic linking upon (re-use) decides how many times the external process has been asked to get invoked.
Nota Bene
There are much smarter ways to integrate MT4 Terminal with external processes or remote processes ( Clouds & Grids ) than just a DLL-based spawn of just another blind & deaf unmanageable <localhost> process.
Typically one needs both process-control and bidirectional communication between / among processes.
Do not hesitate to ask more.
MT4 ( with some additional tools ) can do.

Resources