Forex programozás › Fórum › Egyéb › MT4 build 950 kifagy
-
SzerzőBejegyzés
-
Üdv mindenkinek.
Van egy expertem, ami alapvetően elég egyszerű logikai felépítésű.
Fejlesztés alatt áll, naponta bővítem ilyen-olyan képességekkel.
Pontosan az csinálja amire készült, és jól működik több charton is!DE!
Egy újrafordítás után, egyszecsak az egyik charton (nem tudom mi befolyásolja, hogy melyiken) megszűnik működni.
Míg pl. a többin simán kiiratom egy cimkébe a Tickvalue értékét ezen az egyen megáll a robot teljesen. Árak érkeznek a chart-ra. Kis fej vigyorog a sarokban, kereskedés engedélyezve van.(recompile>deinit, new code>oninit>ontick)
Naplóba olyan üzenetet kapok, hogy „shutdown by timeout” , „abnormal termination”.
Azt tudom, hogy a terminál korlátott szab a deinit végrehajtására, de ez esetben a deinit-ben nincs kód.Szóval úgynéz ki a dolog mintha végtelen ciklusba küldtem volna a procit, de a többi charton minden megy gond nélkül. Amúgy is csak For ciklus van a kódban, nullával nem osztok sehol. Ellenőriztem.
Ha teljesen becsukom a terminált és újra elindítom, újra megynyílnak a chart-ok ugyebár, de azon az egyen fagy az expert! az OnInit még végrehajtódik. Az OnTick egy része is(néhány címke új értéket kap), aztán megáll.
——–
Na mielőtt elküldtem volna ez a post-ot, rányomtam mégegyszer (…tizenhatodszor..) Complie-ra.
Most megint megy. Pedig nem változtattam semmit!Találkozott valaki hasonlóval?
Valamelyik for ciklusodban rosszul van megírva valami.
Ellenőrizd az OnInit() eljárást, mert annak van pár másodperces időlimitje, amin ha túlfutsz akkor is kaphatsz ilyen hibaüzenetet.
Az érintett charton írass ki Print() segítségével hibakereső üzeneteket, de használhatod a Profiler-t is, az megmutatja hogy hol tölt el sok időt az expert.
Vedd figyelembe azt is, hogy a recompile-kor néha a MT4 hajlamos rosszul viselkedni – bár ebben az esetben nem hiszem, hogy erről lenne szó.
Köszi a választ. Hétvégén nem volt időm foglakozni vele. Ma már talán lesz.
Pénteken még az történt, hogy ment a kód minden chart-on, aztán az egyiken megállt.Demó számláról lévén szó azt az egyet bezártam, most hétfő 8:00-kor az van, hogy többi azt csinálja amit kell.
Eddig hajlamos voltam az gondolni, hogy a For ciklusokkal nem lehet probléma. Lefutja a köreit aztán annyi.Jobban átgondolva a dolgot, talán az lesz a baj, hogy az OrdersTotal()-t használom feltételként a For ciklusban, aminek akár menet közben is változhat az értéke.
Időközben kivettem az OrdersTotal()-t For ciklusból.
Most így csinálom:
int oT=OrdersTotal(); for (int i=0; i<oT; i++) { if (OrderSelect(i,SELECT_BY_POS)) { ... } }
és megszűnt a fagyás.
Tudom még ez sem tökéletes, mert ha időközben zárul egy megbízás egy másik charton, akkor az ‘Order-sorrend’
változás miatt kimaradhat a ciklusban egy-egy pozíció, de esetemben ez nem kritikus.Ha mégis nagyon kritikus lenne az időzítés akkor meg beteszem az egészet egy do while ciklusba és a végén összehasonlítom újra oT!= OrdersTotal() [esetleg: oT-closedposCount!=OrdersTotal()] értékét.
A lényeg, hogy már nem fagy.
————————————————-
Még egy dolog amit tapasztaltam:
Egy másik ciklusban ahol egy saját tömböt járok végig, rosszul adtam meg a feltétel és minuszba futtattam a tömbindexet.
Azonkívül, hogy megállt az expert és kaptam egy kövér hibaüzenetet a naplóba, az MT4 lecsatolta az expert minden példányát az összes chartról. Kézzel vissza kellet helyeznem a chartok-ra és újra megadni a paramétereket. Érdekes.Na közben ráfutottam egy másik ágra.
A For ciklus fejlécét Ctrl+C -vel másoltam, és itt szúrtam el:for(j=0; i<oTotal; j++)
Tanulságos. Legközelebb már tudni fogom mit keressek.
Örülök, hogy meglettek a hibák! Amit az OrdersTotal() kapcsán írtál, ne hagyd így, mert elfeledkezel róla és később nagyon sok gondot okozhat. Megoldási javaslatot ebben a cikkben találsz.
Köszi, hogy mindig lehet rád számítani a válaszadásban, és a cikket is.
Korábban már én is arra következtetésre jutottam, hogy először ki kell gyűjteni a bezárandó pozíciókat egy tömbe és utána zárni.
A fentebb leírt problémám, inkább az volt, hogy sikerült egy soha nem teljesülő feltételt megadni a For ciklusban. Eddig valamiért azt hittem, hogy csak a while ciklus veszélyes ebből a szempontból.Viszont ennek kapcsán jutott eszembe, hogy nem tökéletes közvetlenül a For ciklusban használni az OrdersTotal() függvény értékét feltételként!
Vegyük az alábbi feltételezett esetet: nyitva van 8 db megbízás. E=EURUSD, G=GBPUSD
Index szerint ebben a sorrendben:
E1, E2, G3, G4, E5, E6, E7, E8
Valamilyen feltételünk szerint itt az ideje kigyűjteni a zárandó pozíciókat.
EURUSD szimbólumot dolgozzuk fel éppen és az 5. indexű megbízásnál járunk, és itt el kell időznünk néhány millisecundomot(kapcsolati késleltetés, miegymás)
Közben egy másik szálon, vagy pl. StopLoss miatt a G3, G4 bezáródik.Akkor a sorrendem már így néz ki:
E1, E2, E5, E6, E7, E8
És MOST ugrok a cikluban a 6. indexre – E8 !
Tehát E6, E7 kiértékelése ki fog maradni. És az OrdersTotal() szerint minden rendben. Végig mentünk az összesen. Pedig nem.Itt jön be még az, hogy vajon mi volt az eredeti trigger feltétel ami a pozíció kigyűjtést elindította.
Vajon a következő tick-nél is fenn fog állni?
Mindenképp meg kell oldani, hogy a kimaradt pozíciókat (ha vannak!?) detektáljam valahogy. De miért várnék a következő tickre? Ráadásul úgy bonyolultabb is lenne, mert valami „pótfeltételt” is vizsgálnom kéne(előfeltételezve azt, hogy az imént hiányosan(?) kigyűjtött pozíciókat be is zártam).Ezért gondolom, hogy a cikkben leírtakat még ki kell egészíteni egy while ciklussal is.
Valami ilyesmire gondolok(a teljesség igénye nélkül):int oTo=OrdersTotal(); int zarniKell[]; int limit=0; do { ArrayFree(zarniKell); for (int i=0; i<oTo; i++) { if (OrderSelect(i,SELECT_BY_POS)) { //...feltételek ellenőrzése, ArrayResize(...); zarniKell[x]=OrderTicket(); stb. } } limit++; } while(oTo!=OrdersTotal() && limit<10);
Az OrdersTotal() értékét még a ciklus előtt lementem, és csak akkor fogadom el feldolgozottnak a teljes megbízás listát, ha az értéke menet közben nem változott (vagy GetLastError()-ra alapozva dolgozom fel újra).
(És arról még nem is beszéltünk, hogy mi van ha közben egy pozíció bezárult egy másik pedig megnyílt. :) )Mit gondolsz?
A legelső pillanatban, amikor a külön tömbbe gyűjtés lezajlik, az idő alatt OrdersTotal() értéke nem fog megváltozni. Ennek az az oka, hogy ez tick-en belül – kivéve ha a programfutás nem extrém lassú vagy szándékosan nem provokáljuk – az OrdersTotal() értéke nem fog automatikusan frissülni. Ez kizárólag az adott tick-hez tartozó futás befejeztével történik csak meg.
Én emiatt teljesen feleslegesnek gondolom, amit leírsz, mert az OrdersTotal() -t rengeteg esetben használom for ciklusban – ahogy a cikk végén le van írva, kizárólag az elején. Zárni nem a for ciluson belül, hanem a kigyűjtött tömb elemszámai alapján iterált for ciklusban zárok.
A javaslatoddal az a probléma, hogy – ha feltételezzük, hogy az OrdersTotal() értéke változik a ciklus elején érvényes értéktől egy más értékre – hiába tárolod el az OrdersTotal értékét, hiszen maguk az indexek is keveredhetnek attól függően, hogy hány pozíció szűnik meg és jön létre egyszerre.
Tehát: az OrdersTotal() for cikluson belül én kizárólag kiválasztást és szűrést végzek, minden más feladatot a kigyűjtött ticket számokkal feltöltött egy- vagy kétdimenziós tömbök iterálásával végzek. Ebben az esetben pedig már ticket számokkal dolgozok, azok pedig nem fognak változni.
Amennyiben kizárható, hogy az OrdersTotal() értéke megváltozik egy tick alatt, akkor a felvetésemnek nincs értelme természetesen. De nem találtam erre vonatkozó referenciát.
Abból indultam ki, hogy az MQL4 Help-jében is így használják.
Én az évek során nem tapasztaltam ebből fakadó problémát vagy furcsaságot. Ticken belül biztosan nem változik az OrdersTotal() által visszaadott érték, más kérdés, hogy régen divat volt az expertet végtelenítve futtatni, amikor is sosem ért véget az első futtatási példány, hanem azon belül történt kényszerítetten a belső adatok frissítése. De itt most nem ez a helyzet.
A tapasztalatod nagy kincs. Biztos észrevetted volna ha valami hibádzik az OrdersTotal() körül.
De fura megemészteni, hogy egy külső paramétrekkel operáló függvény nem mindig az aktuális értéket adja vissza.
Ez olyan mintha azt mondanánk pl. hogy:
1.
EURUSD cahrton futtatott expertben az OnTick() legelején meghívott
MarketInfo(„GBPUSD”,MODE_BID) fügvény biztosan ugyanazt az értéket adja akkor is ha OnTick()végén újra lekérdezem, és közte volt egy hosszas analízis (és GBPUSD-n meg záporoztak a tickek).
vagy ha:
2. Mégis a(z ‘összeszámláló’) For cikluson belül hajtok végre sikeres zárást, de ez nem befolyásolja az OrdersTotal() értékét. De akkor meg minek kigyűjteni külön tömbe a zárandó pozíciókat?Ez így következetlen, szerintem.
A fentebb leírt while ciklusba ágyazás – mivel csak 2 feltétel ellenőrzését jelenti, ami többnyire nem teljesül – gyakorlatilag 0 befolyással van a program futási idejére.
Száz szónak is egy a vége: Programból egy ideig megfigyelem hogyan viselkedik az OrdersTotal().„De fura megemészteni, hogy egy külső paramétrekkel operáló függvény nem mindig az aktuális értéket adja vissza.”
Nem azt mondtam, hogy nem az aktuális értéket adja vissza! Valószínűleg nem volt egyértelmű a megfogalmazásom, elnézést.Én minden eljárásomat úgy építem fel, hogy a logikai gondolatmenetben ne jelentsen az problémát, hogy ha a ticken belül az OrdersTotal() értéke megváltozik. Természetesen fog, hiszen ha pl. egy zárást végzünk (akár a tömbös megoldással), majd nyomunk utána egy pozíció számlálást, és a program megy a további teendők felé, akkor az OrdersTotal() már a lezárásá utáni, helyes és lehető legkurrensebb eredményt ad vissza.
„MarketInfo(„GBPUSD”,MODE_BID) fügvény biztosan ugyanazt az értéket adja akkor is ha OnTick()végén újra lekérdezem, és közte volt egy hosszas analízis (és GBPUSD-n meg záporoztak a tickek).”
Egy tick lefutása mindenképpen gyors kell, hogy legyen. A gyors természetesen relatív, tudom. Viszont mindennek úgy kell felépítve lennie, hogy ha a futás közben változás van, akkor vagy automatikusan, vagy kérésre – lásd RefreshRates() – történő változások ne okozzanak gondot a programlogikában.„Mégis a(z ‘összeszámláló’) For cikluson belül hajtok végre sikeres zárást, de ez nem befolyásolja az OrdersTotal() értékét.”
De, befolyásolja – pont ezért kellett a tömbös megoldás. Ezzel 100%-ig egyetértek, csak bután fogalmaztam. Ha nem gondolnám így, akkor nem született volna belőle cikk sem :)Én arra gondolok, hogy a for ciklus előtti lekérdezés és a for ciklus – ha pl. pozíciógyűjtésre használjuk – lefutásának ideje alatt nem fog változni az érték. Én ezért nem tárolom el külön változóban az OrdersTotal() értékét. Magyarul: minden olyan teendőt, ami hosszabb időt vehet igénybe, kiszervezek pl. tömbös megoldásként. Minden más gyorsan történik, tehát még 200 pozíció végignyálazása sem vehet igénybe annyi időt, amely során megváltozik az OrdersTotal() értéke.
Na jó akkor összefoglalom magamnak.
Tehát azt mondod lényegében, hogy a For ciklusos számbavétel egy villámgyors memóriaművelet (ahhoz képest mintha egyben a zárást is megkísérelnénk amelynek lehet hálózati késleltetése, ami ráadásul a pozíció indexeket is meg keveri). És a tempó akkora, hogy pl. a 200 pozíció „átnyálazása” alatt elhanyagolható az esélye, hogy az OrdersTotal() értéke megváltozik(avgy pozíciók nyílnak vagy zárodnak egy másik instrumentumon), ezért nem érdemes az OrdersTotal() nyitó és záró értékét összevetni.
——————————————————————————————————-
PS:
Csak érdekességnek írom, hogy: Internet Explorer alatt ha InPrivate módban böngészem az oldalad, akkor a konkrét témaoldalon nem jelenik meg a szerkesztődoboz, hanem helyette megkapom a felkérést, hogy jelentkezzek be (pedig már bent vagyok). A kezdőoldaladra visszalépve újra bejelentkezett állpotban vagyok.Igen, pontosan ezt mondom, jól értelmezted – köszi az összefoglalást. Az elhanyagolható esély jó megfogalmazás, hat év fejlesztés után nem volt probléma a kódjaimmal, így ezt saját tapasztalattal alá tudom támasztani.
IE-t jómagam nem használok, de köszönöm a visszajelzést – Chrome és Firefox alatt ilyesmi hibát nem tapasztaltam még, így elsőre azt mondanám, hogy vagy az IE-ben, vagy a blogmotorban van hiba. Az utóbbit azért nem gondolom, mert az ilyesfajta munkameneti adatokat nem szokták böngészőfüggővé tenni.
-
SzerzőBejegyzés
- Be kell jelentkezni a hozzászóláshoz.