[ARCHIVIO]Qualsiasi domanda da principiante, per non ingombrare il forum. Professionisti, non passate oltre. Non posso andare da nessuna parte senza di te - 5. - pagina 289

 
qwert2:
Ho scritto cosa succede se si sposta lo script in una cartella con degli esperti. Funziona, ma non nel modo in cui dovrebbe. Lo script crea 8 ordini pendenti ma se lo salviamo solo nella cartella con Expert Advisors, crea 8 ordini pendenti dopo ogni tick. Mi serve per piazzare 8 nuovi ordini solo dopo che i vecchi sono stati chiusi.

Avete scritto solo un "rinvio" nella vostra sceneggiatura? Allora non farà altro che procrastinare: tante zecche arrivano quante ce ne vogliono... oops... .........

Dovete aggiungere un terzo inibitore di controllo in esso...

 
qwert2:
Questo è quello che succede se lo script viene semplicemente spostato nella cartella degli esperti. Funziona, ma non come dovrebbe. Lo script crea 8 ordini pendenti, ma se lo salvi solo nella cartella degli esperti, crea 8 ordini pendenti dopo ogni tick. Mi serve per piazzare 8 nuovi ordini solo dopo che i vecchi sono stati chiusi.
Questo non era menzionato nella sua domanda. Non importa come cambiare lo script in un Expert Advisor. Questa è un'altra implementazione del programma.
 
Roger:

Ho trovato un errore. Nella libreria per questa funzione sulla linea

dovrebbe cancellare lo zero in ciascuno dei numeri 13, 14 e 15.


Ora correttamente



Ciao funzioni di libreria.
 
Roger:

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

Теперь правильно
tara:
Ciao funzioni di libreria.
No! Non si possono toccare le funzioni della libreria standard! Dima bannato :-))
 
artmedia70:

Avete scritto solo un "rinvio" nella vostra sceneggiatura? Allora non farà altro che procrastinare: tante zecche arrivano quante ce ne vogliono... oops... .........

Devi metterci anche un controllore di proibizioni...


))))) Non può resistere)))))

Bene, passiamo agli affari. Sto lavorando all'ottimizzazione del codice della seconda TF, ho deciso di tradurre il doppio in int[2] per scrivere la struttura RateInfo in un unico blocco. Ci ho pensato e ho deciso di descrivere tutti i modi possibili, compresiquelli irrealizzabili, in modo che qualcuno possa essere messo in guardia dagli errori.

1. WinAPI (msdn). In generale, non c'è molto in termini di funzioni di conversione. Questo perché la conversione fa ampio uso della traduzione di tipo c, che è qualcosa come

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

nella penultima rigaint i1 è convertito in char e nell'ultima riga char s2 è convertito in int. Come risultato tutta questa roba è usata nelle cosiddette "funzioni di conversione" che in realtà non sono in nessuna dll WinAPI, ma dichiarate nei file .h dell'header usando macro come

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

che a tempo di compilazione il preprocessore srotola in stringa come nel primo codice. E i file header .h non sono dll e sono usati solo nell'ambiente di sviluppo (Studio, Borland, gcc, ecc.). Pertanto, non è né buono né cattivo per MQL4. Comunque, puoi sempre controllare se la funzione è dichiarata solo nell'header .h-file o in funzioni esportate nascoste da occhi indiscreti di qualche dll in System32.

2) WinAPI (dll CRT). Queste DLL sono chiamate msvcp*, msvcr*, msvcrt*, msvci*, msvcirt. Qui la scelta è più ampia: _atodbl, _atoi64, _atoldbl, _ftol, _i64toa, _itoa, _ltoa, _strtoi64, _strtoui64 _ui64toa, _ultoa, atof, atoi, atol, strtod, strtol, strtoul. I simboli nel nome hanno il seguente significato:

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

Ma l'atteso _dtoi64/_dtoui64 manca ancora. Usando le definizioni msvcrt*, msvci*, msvcirt.dll, invece

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

è disponibile solo, anche se si ottiene contorto, come operazione su file (queste sono operazioni da console).

Potete cercare, oltre a msdn, suquesto sito, ecco la barra di ricerca del sito. Una simile "comoda" stringa di ricerca msdn è qui. In cosa differiscono? Il msdn ha una buona descrizione delle funzioni, ma alcune non ci sono affatto (NativeAPI, per esempio). In quello alternativo, invece, c'è qualsiasi tabella di esportazione dll sistema, ma nessuna descrizione. Fondamentalmente, una serie di tabelle di esportazione sul sito web è più facile che estrarre le tabelle di esportazione dalla dll da soli (IDA, PE Explorer, ecc.).

3. inserti dell'assemblatore (più precisamente, inserti di codice macchina). Lo spiegherò tra un momento, dato che la documentazione ufficiale è molto vaga a questo proposito. Gli inserti C++ in MQL4

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

asm/_asm non è una funzione, ma una direttiva del preprocessore, e non è definita da nessuna parte in system32/*.dll (vedi ricerca all'interno del sito). In altre parole, non esiste.

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

Si può scrivere puro codice macchina in MQL4 ma solo in un caso: quando secondo la definizione WinAPI-function in msdn dovrebbe passare un puntatore a una funzione/procedura comelpTimerFunc (esempio completo qui nel forum), in msdn è dichiarato come:

UINT_PTR SetTimer(

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

olpfnWndProc (esempioincompiuto qui sul forum, dichiarazione msdn e tentativo di dichiarazione della struttura mql4). Non c'è altro modo, MQL4 è un interprete, l'indirizzo della funzione non esiste, non c'è niente da passare, solo se il codice è scritto in codice macchina. Sono poi impacchettati in un array int e passati alla funzione per riferimento.

Quindi gli inserti compilati in assembler (cioè il codice macchina) non sono applicabili a questo compito - hanno uno scopo completamente diverso. Il massimo che si può ottenere è eseguire un tale int array via debug in cmd tramite shell32.dll. Sembra che la linea di comando non possa essere passata lì, ma può essere scritta usando i tasti virtuali tramite keybd_event.

4. Scrivere la mia funzione per convertire il doppio in int[2] in puro MQL4 senza inserti. Ma ho stimato la dimensione del codice e le sue prestazioni, e ho rinunciato. Non ho nemmeno scritto il modulo stesso, ma credo che l'algoritmo sia il seguente:

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 забыл.

Ci vorrebbe molto tempo per l'esecuzione. Così alla fine sono arrivato alla soluzione più ovvia e più semplice

5. Uso di una dll auto-scritta in C++. Il codice è il seguente:

#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;
 }

Nella sceneggiatura.

#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] è invertito perché lo passiamo per riferimento. Otteniamo:

...ha funzionato, le linee nel dump sono identiche. Cartella allegata, in essa nelle librerie è double.dll, in samples - source dll, in scripts - script.

La sera: ho riscaricato l'archivio e ho manomesso un po' il codice degli script e delle DLL.

File:
ftdqcs.zip  57 kb
 

Non capisco cosa ho fatto di male. Per qualche motivo la posizione non si chiude come avevo previsto?

Ecco il criterio per aprire una posizione

         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);     //окрываем позицию 
            
           }

Ecco il criterio di chiusura di una posizione

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;
         }

ed ecco cosa otteniamo:

 
Zhunko:
No! Non si possono toccare le funzioni della libreria standard! Dima bannato :-))


Perché state facendo una pagliacciata qui? Se c'è un errore, dovete segnalarlo a servicedesk, o fare la vostra copia del file.
 
GaNDarM:

Non capisco cosa ho fatto di male. Per qualche motivo la posizione non si chiude come avevo previsto?

Ecco il criterio per aprire una posizione

Ecco il criterio di chiusura di una posizione

ed ecco cosa otteniamo:


E quanto spesso viene controllato il criterio di chiusura? Non da bar per caso?
 
ilunga:

E quanto spesso viene controllato il criterio di chiusura? Non da bar per caso?

Non ho capito bene il senso della domanda. Modello di test del prezzo di apertura (metodo rapido su barre formate)
 
Ho bisogno di prelevare denaro da WMZ a QIWI. cerco persone che collaborino. Pronto a prendere circa il 5% di commissione