Jak uruchomić aplikację w MQL, np. terminal.exe :)

O jezykach programowania w platformach i nie tylko.
259
Maniak
Maniak
Posty: 3968
Rejestracja: 15 cze 2011, 23:20

Jak uruchomić aplikację w MQL, np. terminal.exe :)

Nieprzeczytany post autor: 259 »

Witam,

Kiedyś ktoś mnie o to pytał, szczególnie pod kątem samo-optymalizującego się EA :-)

Ogólnie, aby uruchomić jakiś nowy program w MQL wystarczy funkcja ShellExecute() z shell32.dll:

http://msdn.microsoft.com/en-us/library ... s.85).aspx

Implementacja:

Kod: Zaznacz cały

#import "shell32.dll"
	int ShellExecuteA(int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd);
#import
Proszę zwrócić uwagę, że o ile sama funkcja nazywa się ShellExecute() to w MQL używamy nazwę ANSI: ShellExecuteA()

Wywołanie:

Kod: Zaznacz cały

ShellExecuteA(0, "Open", "cmd.exe", "", "C:\", 1);
To uruchomi okienko z cmd.exe w głównym katalogu C:

Albo np... restart komputera:

Kod: Zaznacz cały

ShellExecuteA(0, "Open", "shutdown.exe", "-r", "", 1);
Można się pokusić o wywołanie innego MT4 bez parametrów (normalne uruchomienie):

Kod: Zaznacz cały

ShellExecuteA(0, "Open", "terminal.exe", "", "C:\Program Files\Metatrader\", 1);
lub z parametrem wskazującym na plik konfiguracyjny:

Kod: Zaznacz cały

ShellExecuteA(0, "Open", "terminal.exe", "mojkonfig.txt", "C:\Program Files\Metatrader\", 1);
MT4 ma to bardzo rozbudowane możliwości uruchamiania w rozmaitych trybach, z różnymi profilami itp. Szczegóły w helpie MT4.
Powyższa linia uruchomi terminal wskazując mu plik mojkonfig.txt jako zawierający szczegóły testu do wykonania (to przykład z help):

Kod: Zaznacz cały

mojkonfig.txt:
TestExpert=Moving Average 
TestExpertParameters=ma0.set 
TestSymbol=EURUSD 
TestPeriod=H1 
TestModel=2 
TestOptimization=false 
TestDateEnable=true 
TestFromDate=1970.01.01 
TestToDate=2006.06.06 
TestReport=MovingAverageReport 
TestReplaceReport=false 
TestShutdownTerminal=true 
Tutaj mała dygresja: ShellExecute() nie toleruje spacji w nazwie pliku do wywołania o ile nie poda się całego stringu w cudzysłowie. N.p. "C:\Program Files\MT4\terminal.exe". I teraz aby to prawidłowo przekazać należałoby napisać w MQL: ""C:\Program Files\MT4\terminal.exe"" - podwójny cudzysłów. MQL tego wprost nie kupi. Można na około, ale zamiast walczyć ze stringami, można po prostu rozbić to na zasadniczy plik i katalog i podać ten katalog w parametrze lpDirectory. A ten z kolei nie ma żadnych problemów ze spacjami czy innymi śmieciami :)

A teraz, jak ponownie uruchomić ten sam terminal?
MT4 sprawdza czy jest już uruchomiony i nie pozwala na duplikaty z tej samej lokalizacji więc samo uruchomienie tego samego programu nic nie da.
Trzeba go najpierw zamknąć, a następnie uruchomić ponownie.
Ręcznie nie ma problemu. Ale jak ma to zrobić skrypt czy EA? Przecież przestanie działać wraz z zamknięciem gospodarza...

W zasadzie prosto - EA czy skrypt musi wpierw... uruchomić terminal.exe w lokalizacji w której aktualnie pracuje, a następnie zamknąć poprzednią postać w której działa. Coś nie tak - przed chwilą napisałem, że tak nie zadziała bo program sprawdzi i nie pozwoli... No cóż, jest logika maszynowa i logika zdarzeń - tutaj mamy do czynienia z tą drugą.
Trick polega na tym, że uruchamianie trwa znacznie dłużej niż zamykanie więc zanim nowa postać dojdzie to tego żeby cokolwiek sprawdzić, poprzednia już nie powinna istnieć ;-)

Aby uruchomić terminal wystarczy:

Kod: Zaznacz cały

ShellExecuteA(0, "Open", "terminal.exe", "", TerminalPath(), 1);
Ale żeby zamknąć bieżącą postać trzeba nieco więcej - wysłać sygnał zamknięcia do właściwego obiektu czyli procesu nadrzędnego. Trzeba umieć do niego dotrzeć. Ja wybrałem drogę poprzez okna - odnalezienie głównego okna terminal.exe i zamknięcie tego zadania (są i inne możliwości).
Tutaj podeprę się dwoma funkcjami z user32.dll:
http://msdn.microsoft.com/en-us/library ... s.85).aspx
http://msdn.microsoft.com/en-us/library ... s.85).aspx

Implementacja:

Kod: Zaznacz cały

#import "User32.dll"
	int GetAncestor(int hWnd, int gaFlags);
	bool EndTask(int hWnd, bool fShutDown, bool fForce);
#import
Te funkcje nie mają wersji ANSI więc biorę nazwy originalne.

Pierwsza pozwoli mi znaleźć uchwyt głównego okna na podstawie uchwytu okna wykresu w którym pracuje skrypt/EA - MQL dostarcza funkcję podającą uchwyt bieżącego okna:

Kod: Zaznacz cały

int hwnd = WindowHandle(Symbol(),Period()); // pobierz uchwyt okna wykresu 
int terminalHwnd = GetAncestor(hwnd, 2); // znajdz główne okno właściciela 
I teraz jak już wiadomo które to okno, wystarczy wysłać mu polecenie zamknięcia zadania:

Kod: Zaznacz cały

EndTask(terminalHwnd, false, false); // drugi parametr określa tryb wyłączenia. TRUE = wymuszenie natychmiastowego przerwania pracy i zamknięcia, FALSE = normalne zamknięcie
I teraz zrobiłem sobie taka małą procedurkę która restartuje terminal gdy zdarzy się coś co tego wymaga:

Kod: Zaznacz cały

void panic()
{
	int hwnd = WindowHandle(Symbol(),Period());
	int terminalHwnd = GetAncestor(hwnd, 2);
	ShellExecuteA(0, "Open", "terminal.exe", "", TerminalPath(), 1);
	EndTask(terminalHwnd, false, false);
}
Co można łatwo przerobić na coś co ponownie uruchamia terminal w jakimś innym trybie. Np. uruchamia optymalizację, potem analizuje wyniki, zapisuje je do plików .set a potem uruchamia ponownie z nowymi parametrami.

Albo np. uruchomienie ze wskazanym skryptem. Jak kto lubi :-)
Ostatnio zmieniony 05 cze 2012, 11:37 przez 259, łącznie zmieniany 6 razy.
Jakże często ludzie mają już gotową opinię zanim zdążą pojąć istotę rzeczy.
A gdy już ta istota w pełni do nich dotrze, jakże często muszą zmagać się z konsekwencjami swojej opinii ;-)

Awatar użytkownika
mike_05
Maniak
Maniak
Posty: 1668
Rejestracja: 02 wrz 2010, 11:55

Re: Jak uruchomić aplikację w MQL, np. terminal.exe :)

Nieprzeczytany post autor: mike_05 »

Szerokie możliwości. Jak by popracował, to mt4 stałby się tylko maszynką do komunikacji z serwerem wykonawczym.
Napisałeś, że mt4 sprawdza, czy "jest już uruchomiony" i nie pozwala na duplikat. A mnie często to się "udaje" wywołując terminal z paska szybkiego uruchamiania. "Udaje" w cudzysłowie, bo oczywiście jest to skutkiem błędu, nie zamierzonego działania. Po tym co napisałeś, wydaje mi się, że tę procedurę sprawdzania można więc obejść.

Zdalnie też mam takie "cudo", ze jeden z terminali, Windsor Direct, uruchamia mi się sam, jak nikt go nie prosi. Robi to np. w niedzielę czy sobotę, jak wszystko powinno "spać". Jest tam zainstalowany copier z MT4i jako odbiornik i czy on może przez ich serwer powodować uruchomienie przez heartbeat?

Dodano po 14 minutach:
259 pisze:...

Aby uruchomić terminal wystarczy:

Kod: Zaznacz cały

ShellExecuteA(0, Open, "terminal.exe", "", "TerminalPath()", 1);
...
a z tego widzę zbudowanie np. plik .bat uruchamiający wszystko, co ma być w piątek uruchomione, albo po jakiejś totalnej wywałce komputera czy zasilania :lol:

259
Maniak
Maniak
Posty: 3968
Rejestracja: 15 cze 2011, 23:20

Re: Jak uruchomić aplikację w MQL, np. terminal.exe :)

Nieprzeczytany post autor: 259 »

mike_05 pisze:A mnie często to się "udaje" wywołując terminal z paska szybkiego uruchamiania. "Udaje" w cudzysłowie, bo oczywiście jest to skutkiem błędu, nie zamierzonego działania. Po tym co napisałeś, wydaje mi się, że tę procedurę sprawdzania można więc obejść.
Pewnie, że da się. On sprawdza tylko jakieś podstawowe rzeczy. Jedną z nich jest ścieżka w której został uruchomiony. A to można obejść na wiele sposobów. Albo wystarczy skopiować terminal.exe w tym samym katalogu i można uruchomić dwa programy pracujące na tych samych plikach. Nie trzeba nawet tych launcherów od Birta ;-) Byleby oba exe miały różne nazwy.
mike_05 pisze: Zdalnie też mam takie "cudo", ze jeden z terminali, Windsor Direct, uruchamia mi się sam, jak nikt go nie prosi. Robi to np. w niedzielę czy sobotę, jak wszystko powinno "spać". Jest tam zainstalowany copier z MT4i jako odbiornik i czy on może przez ich serwer powodować uruchomienie przez heartbeat?
Coś go musi uruchamiać, sam się nie uruchomi (chyba, że zna sztuczki z timerami - prawdę mówiąc wątpię). Nie wiem jak skonstruowany jest ten kopier - czy to jest jakaś dodatkowa aplikacja? Może ona to robi? Ale to powinno się jakoś konfigurować... A może gdzieś coś go dopisało. Np. do zaplanowanych zadań.
W sumie, skoro można z MQL uruchomić niemalże cokolwiek, to żaden problem wsadzić coś do rejestru czy uruchomić jakiś skrypt...
Czy napisałem, że tym samym mechanizmem można uruchamiać zdalnie programy na innym komputerze? Ba, zarządzać nim! Co prawda trzeba znać jego adres sieciowy, mieć w miarę swobdny dostęp przez sieć i znać hasło odpowiedniego użytkownika ale można.
Tutaj np. są narzędzia do zdalnego manipulowania komputerem bez żadnego VNC czy Remote Desktop:
http://technet.microsoft.com/en-us/sysi ... 96649.aspx
Bardzo pożyteczna i mocna sprawa.
Serwer odkleił mi się od UI, Remote Desktop pokazywał błękit i nic więcej, inne wynalazki graficzne też nie dawały rady, ale mogłem uruchamiać i zamykać programy przy pomocy tych narzędzi.
Np. wywalić przeszkadzający mi serwis czy napisać sobie skrypt ładujący interesujący mnie fragment rejestru, wrzucić temu zombie na twardziela i uruchomić...

Dodano po 12 minutach:
mike_05 pisze: a z tego widzę zbudowanie np. plik .bat uruchamiający wszystko, co ma być w piątek uruchomione, albo po jakiejś totalnej wywałce komputera czy zasilania :lol:
No właśnie - jest całe szerokie pole do popisu :-)

PS: tam był mały błąd, już poprawiony. Open powninien być w cudzysłowie, a TerminalPath() nie:

Kod: Zaznacz cały

ShellExecuteA(0, "Open", "terminal.exe", "", TerminalPath(), 1); 
Ostatnio zmieniony 05 cze 2012, 07:41 przez 259, łącznie zmieniany 2 razy.
Jakże często ludzie mają już gotową opinię zanim zdążą pojąć istotę rzeczy.
A gdy już ta istota w pełni do nich dotrze, jakże często muszą zmagać się z konsekwencjami swojej opinii ;-)

Awatar użytkownika
mike_05
Maniak
Maniak
Posty: 1668
Rejestracja: 02 wrz 2010, 11:55

Nieprzeczytany post autor: mike_05 »

Teraz kojarzę, że copier ma nakładkę instalacyjną. Tam mogło coś dopisać. Przeszukam rejestr.

A on z tego:

http://www.mt4i.com/appstore/app.aspx?i ... popularity

to teraz chyba jest już własnością IBFX.

Fiku
Stały bywalec
Stały bywalec
Posty: 23
Rejestracja: 14 lut 2009, 16:14

Nieprzeczytany post autor: Fiku »

Ciekawa sprawa. Ale 259, co masz na myśli, że można by modyfikować w kodzie strategii, skoro w testerze w sumie można zmieniać wyexportowane parametry?
Mql minimal techno remix

259
Maniak
Maniak
Posty: 3968
Rejestracja: 15 cze 2011, 23:20

Nieprzeczytany post autor: 259 »

Fiku pisze:Ciekawa sprawa. Ale 259, co masz na myśli, że można by modyfikować w kodzie strategii, skoro w testerze w sumie można zmieniać wyexportowane parametry?
O samoczynnym modyfikowaniu kodu nie mówiłem - to zupełnie inne zagadnienie.

Kiedyś wykorzystywałem podobny mechanizm (automatyczne uruchamianie MT4 w szczególnych trybach) do automatycznego optymalizowania EA na wielu parach. Dla każdej pary trzeba było uruchomić terminal z innym zestawem parametrów dla testera, a optymalizacja jednej pary trwała prawie dobę. Osiem terminali na dwóch komputerach robiło te optymalizacje całkowicie automatycznie. Wtedy zrobiłem to kombinacją EA, zewnętrznych skryptów kontrolujących pętlę i serwera ftp co było lekkim koszmarkiem, bardzo nieelastycznym rozwiązaniem i wystarczał powiew wiatru aby wywalić całą konstrukcję. Teraz zrobiłbym to w samym MQL, byłoby łatwiej.
Choć pewnie napisanie aplikacji kontrolującej i analizującej wyniki w C++ mogłoby być wydajniejsze. Choćby tylko dlatego, że łatwiej mogłaby kontrolować rozproszone zasoby i dynamicznie rozrzucać po nich zadania.
Nie wspominając już o szybkości wykonywania kodu i integracji ze choćby ze środowiskiem sieciowym... a co dopiero paleta narzędzi :)

Teraz zaś potrzebowałem to do bardzo prostej rzeczy - Metaquotes skopał screenshoty od wersji gdzieś 40x i w szczególnych przypadkach zamiast obrazka otrzymuje się komunikat o przepełnieniu pamięci i śmieć na dysku. Trzeba zrestartować terminal. Miałem już dosyć ręcznego przeładowywania więc zrobiłem automat :-)
Jakże często ludzie mają już gotową opinię zanim zdążą pojąć istotę rzeczy.
A gdy już ta istota w pełni do nich dotrze, jakże często muszą zmagać się z konsekwencjami swojej opinii ;-)

Awatar użytkownika
mike_05
Maniak
Maniak
Posty: 1668
Rejestracja: 02 wrz 2010, 11:55

Nieprzeczytany post autor: mike_05 »

Skoro robiłeś multi kombajny mt4, to pomyśl, jak z jednego zaciągnięcia nowego update za jednym zamachem zainstalować hurtowo na wszystkich instalacjach?
Ściąganie całości kilkadziesiąt razy na każą sztukę to paranoja. Zwłaszcza te wszystkie obcojęzyczne tutoriale i helpy. Po kiego one? Opcja instalacyjna powinna być, jak w każdym cywilizowanym programie komputerowym, z opcja zaawansowaną z wariantami instalacji elementów. Oszczędność czasu, ruchu na serwerach, i miejsca na dyskach.

259
Maniak
Maniak
Posty: 3968
Rejestracja: 15 cze 2011, 23:20

Nieprzeczytany post autor: 259 »

mike_05 pisze:Skoro robiłeś multi kombajny mt4, to pomyśl, jak z jednego zaciągnięcia nowego update za jednym zamachem zainstalować hurtowo na wszystkich instalacjach?
Ściąganie całości kilkadziesiąt razy na każą sztukę to paranoja. Zwłaszcza te wszystkie obcojęzyczne tutoriale i helpy. Po kiego one? Opcja instalacyjna powinna być, jak w każdym cywilizowanym programie komputerowym, z opcja zaawansowaną z wariantami instalacji elementów. Oszczędność czasu, ruchu na serwerach, i miejsca na dyskach.
Ale to akurat co innego.
Prawdę mowiąc ja robię wszystko co mogę aby nie aktualizować MT4 :lol:
Bo co update to coś nie działa jak działało...
Ale można to ogarnąć w miarę prosty sposób:
LiveUpdate najpierw ściąga wszystko do katalogu .\liveupdate, a potem przenosi do odpowiednich katalogów jak naciśnie się update&restart.
Ja to robię w ten sposób, że jak już ściągnie co musi, nie naciskam update&restart tylko zamykam LiveUpdate, a potem ręcznie kopiuję sobie co znajdę z katalogu ,\liveupdate do wszystkich terminali których to dotyczy (trzeba pamiętać o ich zamknięciu).
Kłopot jest tylko taki, że brokerzy różnie aktualizują swoje oprogramowanie, u jednego jest np. 419, u drugiego już 432 więc jak używasz kilku jednocześnie to trudno to generalnie zautomatyzować. Ale można zrobić prosty batch który to zrobi.
Np:

Kod: Zaznacz cały

taskkill /IM liveupdate.exe
zamknie liveupdate bez klikania w okienko,

Kod: Zaznacz cały

taskkill /IM terminal.exe
zamknie wszyskie działające terminale,

a potem:

Kod: Zaznacz cały

copy "C:\...\liveupdate\*.*" "C:\...."
copy "C:\...\liveupdate\languages\*.*" "C:\....\languages"
i tak dalej.
Można zbudować listę i rozrzucać.

Można to jeszcze bardziej zautomatyzować...

PS: jak kogoś nie chce aktualizować MT4, a LiveUpdate otwiera się automatycznie i denerwuje, są na to dwa sposoby:

1) Po prostu nic nie robić. Po dwóch minutach LiveUpdate zamknie się samoczynnie ;-)
2) Zmienić nazwę LiveUpdate. Wystarczy jedne znak. Ale to rozwiązanie ma mały haczyk - w którymś momencie serwer przestanie obsługiwać starą wersję i trzeba będzie uruchomić LiveUpdate. A że nie za bardzo daje się to zrobić ręcznie więc trzeba będzie przywrócić oryginalną nazwę i pozwolić zrobić to automatycznie.
Ostatnio zmieniony 07 cze 2012, 15:04 przez 259, łącznie zmieniany 1 raz.
Jakże często ludzie mają już gotową opinię zanim zdążą pojąć istotę rzeczy.
A gdy już ta istota w pełni do nich dotrze, jakże często muszą zmagać się z konsekwencjami swojej opinii ;-)

Awatar użytkownika
mike_05
Maniak
Maniak
Posty: 1668
Rejestracja: 02 wrz 2010, 11:55

Nieprzeczytany post autor: mike_05 »

Updejty jednak są konieczne. Chociażby ostatnia zmiana komunikacji z serwerami, które już nie będą obsługiwać wersji starszych niż 416. Poza tym, każdy w zasadzie update coś modyfikuje co znaleziono jako bug. Jak się jednak okazuje, może wprowadzić nowe albo ujawnić już istniejące a jeszcze nie odkryte.
Skoro upadejtuje sie bugi, to w takim razie po diabła robi się to jako nadgranie całej instalacji w całości?! Skoro błąd jest w terminal.exe, to jest łącznie z metaeditor 30% (?) całej instalacji, a nie zawsze metaeditor musi być zmieniany, zwłaszcza jak to co wprowadził user i tak jest nienaruszone. Userzy zgłaszają, ze coś im przestaje działać po zmianie wersji. Skoro tak sie dzieje, update powinien robić automatyczne ponowne kompilowanie wszystkich plików nie tylko tych uruchomionych na wykresach, a nie, żeby ludzie szukali pomocy na forach.
Kierowca nie musi się znać na zasadach języków programowania, jak programista -pasażer taksówki nie musi mieć prawa jazdy. Obaj mają zamiennie z tego móc korzystać.

259
Maniak
Maniak
Posty: 3968
Rejestracja: 15 cze 2011, 23:20

Nieprzeczytany post autor: 259 »

mike_05 pisze:(...) Skoro błąd jest w terminal.exe, to jest łącznie z metaeditor 30% (?) całej instalacji, a nie zawsze metaeditor musi być zmieniany, zwłaszcza jak to co wprowadził user i tak jest nienaruszone. Userzy zgłaszają, ze coś im przestaje działać po zmianie wersji. Skoro tak sie dzieje, update powinien robić automatyczne ponowne kompilowanie wszystkich plików nie tylko tych uruchomionych na wykresach, a nie, żeby ludzie szukali pomocy na forach.
Kierowca nie musi się znać na zasadach języków programowania, jak programista -pasażer taksówki nie musi mieć prawa jazdy. Obaj mają zamiennie z tego móc korzystać.
Nie da się przekompilować wszystkiego od początku - nikt nie sprzedaje kodów źródłowych ;-)

Jeżeli w terminal.exe zostanie poprawione cokolwiek co dotyczy MQL to musi być też zaktualizowany Editor. Inaczej będzie generował niekompatybilny lub wadliwy kod (choć terminal.exe jest kompatybilny w dół więc teoretycznie nie trzeba by tego ruszać ale byłoby to sprzeczne z ideą łatania dziur).
Jeżeli zaś zostanie zmienione cokolwiek dotyczące interfejsu pociąga to za sobą zmiany w plikach zawierających stringi w rozmaitych językach.

A ostatnio takie zmiany są bardzo częste, to widać po tym jak przestają np. działać dobrze do tej pory działające mechanizmy odwołań do dll.
Dlatego właśnie wcale nie spieszy mi się z aktualizacjami - zanim zaktualizuję, muszę sprawdzić czy nie strzelę sobie w stopę.
Niestety wiele razy naciąłem się na problemy z nowymi wersjami. Nie tylko ja.
Brokerzy też nie są zadowoleni - w końcu stado debiutantów z maszynkami tracącymi pieniądze to żyła złota. Jak im te maszynki przestają nagle działać to brokerzy zaczyna płakać... ;-)
Np. Oanda w przeciągu ostatniego pół roku pozwoliła na jedną zaledwie aktualizację. Chyba wszystke te śmieci pomiędzy 388 do 432 zostały pominięte.

Tak mi się jakoś wydaje, że Metaquotes wycofuje się rakiem z MT5 i robi generalny remont MT4 - jakoś za bardzo jest ostatnio aktywne z tymi aktualizacjami.
Jakże często ludzie mają już gotową opinię zanim zdążą pojąć istotę rzeczy.
A gdy już ta istota w pełni do nich dotrze, jakże często muszą zmagać się z konsekwencjami swojej opinii ;-)

ODPOWIEDZ