[ARCHIVE]Any rookie question, so as not to clutter up the forum. Professionals, don't pass it by. Can't go anywhere without you - 5. - page 289

 
qwert2:
I've written what happens if you just move the script to a folder with experts. It works, but not in the way it should. The script creates 8 pending orders but if we just save it in the folder with Expert Advisors, it creates 8 pending orders after each tick. I need it to place 8 new orders only after the old ones are closed.

Have you written only a "postponement" in your script? Then it will only procrastinate: as many ticks come in as it takes... oops... .........

You have to add a third checker-inhibitor in it...

 
qwert2:
This is what happens if the script is simply moved to the experts folder. It works, but not the way it should. The script creates 8 pending orders, but if you just save it in the Expert Advisors folder, it creates 8 pending orders after each tick. I need it to place 8 new orders only after the old ones are closed.
This was not mentioned in your question. It does not matter how to change the script into an Expert Advisor. This is another implementation of the program.
 
Roger:

I found a mistake. In the library for this function on the line

should delete zero in each of the 13th, 14th and 15th numbers.


Now correctly



Hello library functions.
 
Roger:

Нашел ошибку. В библиотеке для данной функции в строке
надо удалить по нулю в 13, 14 и 15 числе.

Теперь правильно
tara:
Hello library functions.
No! You can't touch functions from the standard library! Dima banned :-))
 
artmedia70:

Have you written only a "postponement" in your script? Then it will only procrastinate: as many ticks come in as it takes... oops... .........

You need to put a prohibition checker in there as well...


))))) Can't resist)))))

All right, let's get down to business. I'm working on optimization of code of the second TF, I've decided to translate double into int[2] to write the RateInfo structure in one block. I thought about it and decided to describe all possible ways, includingunrealizable ones, so that somebody could be warned against errors.

1. WinAPI (msdn). Generally speaking, there is not a lot there in terms of conversion functions. This is because conversion makes extensive use of the c-type translation, which is something like

char s1;
char s2="g";//код ANSI 0x67
int i1=1357;//0x54D в шестн. представлении
int i2;

s1=(char)i1;//0x4D, "M", старший разряд (5) был усечён по границе байта (две шестн. цифры), остался один байт (0x4D, десятичное 77)
i2=(int)s2;//0x00 0x00 0x00 0x67, десятичное 103

in the next-to-last lineint i1 is converted to char and in the last line char s2 is converted to int. As the result all this stuff is used in so called "conversion functions" which in fact are not in any WinAPI dll, but declared in header .h files using macros like

#define _dtoi64(d)     (*((int64_t *)&(d)))
#define _dtoui64(d)     (*((uint64_t *)&(d)))

which at compile time preprocessor unrolls into string like in the first code. And header .h files are not dll and are used only in development environment (Studio, Borland, gcc, etc). Therefore, it is neither good nor bad for MQL4. However, you can always check whether the function is declared only in the header .h-file or in hidden from prying eyes exported functions of some dll in System32.

2) WinAPI (CRT dll). These dlls are named msvcp*, msvcr*, msvcrt*, msvci*, msvcirt. Here the choice is wider: _atodbl, _atoi64, _atoldbl, _ftol, _i64toa, _itoa, _ltoa, _strtoi64, _strtoui64 _ui64toa, _ultoa, atof, atoi, atol, strtod, strtol, strtoul. The symbols in the name have the following meaning:

a, str, w - string
f, l, i, ui, ul - int (4 байта)
d, dbl, i64 - double, int[2] (8 байт)
ldbl - int[2.5] (шучу) - 10 байт.

But the expected _dtoi64/_dtoui64 is still missing. Using the msvcrt*, msvci*, msvcirt.dll definitions, on the other hand

istream::operator>>(double &)
ostream::operator<<(double)

is only available, even if you get twisted, as a file operation (these are console operations).

You can search, apart from msdn, onthis site, here is the site search bar. A similar "handy" msdn search string is here. How do they differ? The msdn has a good description of the functions, but some are not there at all (NativeAPI, for example). On the alternative one, on the other hand, any system dll export table is there, but no description. Basically, a set of export tables on the website is easier than pulling export tables from the dll yourself (IDA, PE Explorer, etc.).

3. assembler inserts (more precisely, machine code inserts). I will explain in a moment, as the official documentation is very vague in this respect. The C++ inserts in MQL4

asm{//или _asm{
   //
   //какой-либо ассемблерный код
   //
}

asm/_asm is not a function, but a preprocessor directive, and is not defined anywhere in system32/*.dll (see search within the site). In other words, there is no such thing.

#import "/Windows/system32/superpuper.dll"
   asm(string& item[]);//в строковый массив заносим команы ассемблера
#import

You can write pure machine code in MQL4 but only in one case: when according to definition WinAPI-function in msdn it should pass a pointer to function/procedure likelpTimerFunc (completeexample here at forum), in msdn it is declared as:

UINT_PTR SetTimer(

    HWND hWnd,
    UINT_PTR nIDEvent,
    UINT uElapse,
    TIMERPROC lpTimerFunc//<-
);

orlpfnWndProc (unfinishedexample here on the forum, msdn declaration and attempted mql4 structure declaration). There is no other way, MQL4 is an interpreter, the address of the function does not exist, there is nothing to pass, only if the code is written in machine code. They are then packed in an int array and passed to the function by reference.

So compiled assembler inserts (i.e. machine code) are not applicable to this task - they have a completely different scope. The most that can be achieved is to run such an int array via debug in cmd via shell32.dll. It seems that the command line cannot be passed there, but it can be written using the virtual keys via keybd_event.

4. Writing my own function to convert double into int[2] in pure MQL4 without inserts. But I've estimated the size of the code and its performance, and gave up. I haven't even written the module itself, but I believe the algorithm is as follows:

1. Объявляем bool[64].
2. bool[0] равен 0, если плюс, и 1, если минус (отрицательное число то есть).
3. Находим значение выражения целая_часть(log_2(число))+1023. В цикле находим остатки от деления его на 2, заносим их в bool[11]-bool[1]
        в обратном порядке.
4. Разделяем целую и дробную чсти, сохраняем их в разные переменные.
5. Для целой части в цикле находим остаток от деления её на 2, пока не останется остаток от деления 1 или 0, заносим в этом же цикле значения
        в массив с bool[13+log_2(целая_часть)] до bool[12], в обратном порядке.
6. Для дробной части в цикле находим целую часть числа при циклическом умножении на 2. Целую часть запоминаем и отбрасываем, дробную умножаем дальше.
        Цикл до тех пор, пока при умножении в результате не получится 1. Заносим в прямом порядке, т.е. с начала (а начало на следующей ячейке после
        окончания пред. записи).
7. Теперь в цикле собираем в int[2] с конца bool[64], помня, что в int[0] идёт bool[0]-bool[31], а в int[1] идёт bool[32]-bool[63].
8. Ах, да, ещё BigEndian забыл.

It would take a very long time to execute. So I finally came to the most obvious and easiest solution

5. Use of a self-written dll in C++. The code is as follows:

#include "stdafx.h"

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                                         )
{
    return TRUE;
}

__declspec(dllexport) void __stdcall dtoi(unsigned _int64 Dbl, int iDbl[2])
 {
        iDbl[0]=static_cast<unsigned int>(Dbl);
        iDbl[1]=static_cast<unsigned int>(Dbl>>32);
        return;
 }

In the script.

#property show_inputs //для вывода окна с настройкой параметров

#import "double.dll"//самонаписанная dll
   void dtoi(double Dbl, int& iDbl[]);
#import

extern double Dbl=96.578;//в параметрах передаём любую double-переменную
int iDbl[2];//и выходной double->int[2] массив
int handle;//хэндл тестового файла

int start(){
   handle=FileOpen("test.txt",FILE_BIN|FILE_WRITE);//открываем тестовый файл как бинарный "только на запись"
   FileWriteDouble(handle, Dbl);//записываем в тестовый файл double-переменную (8 байт)
   dtoi(Dbl, iDbl);//вызываем функцию конвертации; в iDbl помещается разпарсенный double
   FileWriteArray(handle, iDbl, 0, 2);//записываем в тестовый файл int[2]-переменную (8 байт)
   FileClose(handle);//сначала идут 8 байт double, затем 4+4=8 байт сконвертированных int
   return(0);//Получаем перезаписываемый \experts\files\test.txt в 16 байт.
  }

Int upper[0] is reversed because we pass it by reference. We get:

...it worked, the lines in the dump are identical. Attached folder, in it in libraries is double.dll, in samples - source dll, in scripts - script.

In the evening: re-downloaded the archive and tampered with script and dll code a bit.

Files:
ftdqcs.zip  57 kb
 

I don't understand what I've done wrong. For some reason the position is not closing as I had planned?

Here is the criterion for opening a position

         if (Ask > iBands(NULL,0,M,2,0,N,MODE_LOWER,0)&& Low [1] < iBands(NULL,0,M,2,0,N,MODE_LOWER,1) && Hour()>=23 || Hour()<4)
         if (iStochastic(NULL,0,K,D,L,MODE_SMA,0,MODE_MAIN,0)> 20 && iStochastic(NULL,0,K,D,L,MODE_SMA,0,MODE_MAIN,1) < 20)
           {     
            Opn_B  =  true;     // Критерий открs. Buy
            OpenFunction ( Opn_B,  Opn_S, Lots);     //окрываем позицию
            
           }
         
         if (Bid < iBands(NULL,0,M,2,0,N,MODE_UPPER,0)&& High [1] > iBands(NULL,0,M,2,0,N,MODE_UPPER,1) && Hour()>=23 || Hour()<4)
         if (iStochastic(NULL,0,K,D,L,MODE_SMA,0,MODE_MAIN,0)> 80 && iStochastic(NULL,0,K,D,L,MODE_SMA,0,MODE_MAIN,1) < 80)
       
           {   
            Opn_S  =  true;     // Критерий откр. Sell
            OpenFunction ( Opn_B,  Opn_S,  Lots);     //окрываем позицию 
            
           }

Here's the criterion for closing a position

if (Bid >= iBands(NULL,0,M,2,0,N,MODE_UPPER,0))    
         {                                                                      
         Cls_B  =  true;     // ... получаем критерий для закрытия позиции Buy
         CloseFunction ();     //исполняем функцию закрытия ордеров
         return;
         }
       
       if (Ask <= iBands(NULL,0,M,2,0,N,MODE_LOWER,0))       
         {                                                                      
         Cls_S  =  true;
         CloseFunction ();     //исполняем функцию закрытия ордеров
         return;
         }

and here's what we get:

 
Zhunko:
No! You can't touch functions from the standard library! Dima banned :-))


Why are you making a clownery here? If there is an error, you either need to report it to servicedesk, or make your own copy of the file.
 
GaNDarM:

I don't understand what I've done wrong. For some reason the position is not closing as I had planned?

Here is the criterion for opening a position

Here's the criterion for closing a position

and here's what we get:


And how often is the closing criterion checked? Not by bar by any chance?
 
ilunga:

And how often is the closing criterion checked? Not by bars by any chance?

I don't quite get the gist of the question. Opening price testing model (quick method on formed bars)
 
Need to withdraw money from WMZ to QIWI. looking for people to cooperate. Ready to take about 5% commission