Instrumentum lista lekérdezése2012-03-15T12:02:41+00:00

Radu.hu Fórum Kérdések az MQL4 programozási nyelvvel kapcsolatban Instrumentum lista lekérdezése

15 bejegyzés megtekintése - 1-15 / 17
  • Szerző
    Bejegyzés
  • Roden
    Tag
    Bejegyzések száma: 46

    Elsőként szeretném elmondani, hogy rengeteget tanultam az általad közétett posztokból és könyvből. Köszönöm szépen!
    A kérdésem az lenne, hogy:
    1. Le tudom-e valahogy kérdezni a terminálom által kezelt instrumentumok listáját?
    2. MT4 terminál által kezelt globális változó csak double típusú lehet?
    3. HA (2.kérdés == igen) akkor {Egy instrumentumra csak a nevével tudok hivatkozni? (pl.: “EURUSD”) Nincs vmilyen azonosító száma is a terminálon belül.}

    Röviden leírom miért érdekelne:
    Szeretném megoldani, hogy egy több charton futatott expert egyik példánya kitüntetett szerepet kapjon és adatokat szolgátasson – a terminálban definiált globális változókon keresztül a többi expertnek .
    Pl:
    – lenne egy G_MasterSymbol nevű változó értéke: “EURUSD” >>(2. kérdés)

    Utána az “alárendelt” expertekben használnám fel pl:
    if (Symbol() != G_MasterSymbol) x=MarketInfo(G_MasterSymbol,MODE_BID); formában.

    Ami lenginkább érdekel az hogy a 3.kérdésre mi a válasz. Köszi.

    Roden
    Tag
    Bejegyzések száma: 46

    Ha nincs más akkor a szimbólum névből lesz UID. 🙂

    double Symbol_ID (string sym=””)
    {
    int strl=StringLen(sym);
    string uid=””;
    for (int i=0; i<strl; i++) uid=StringConcatenate(uid,StringGetChar(sym, i));
    return (StrToDouble(uid));
    }

    Radulovic Attila
    Tag
    Bejegyzések száma: 646

    Örülök, hogy segíthettem! 🙂

    1. kérdésedre a válasz:

    void LoadSymbols (string &SymbolsArray[]) {
     
       int ElementCount;
       string Row;
     
       int 
          fileHandle = FileOpenHistory("symbols.sel", FILE_BIN|FILE_READ);
     
       if (fileHandle >= 0) {
     
          ElementCount = (FileSize(fileHandle) - 4) / 128;
     
          ArrayResize(SymbolsArray, ElementCount);
     
          FileSeek(fileHandle, 4, SEEK_SET);
     
          for (int k = 0; k < ElementCount; k++) {
     
             Row = FileReadString(fileHandle, 12);
             SymbolsArray[k] = Row;
     
             FileSeek(fileHandle, 116, SEEK_CUR);
          }
     
          FileClose(fileHandle);
       }
    }
     
    /*
    Használat:
    */
     
    string 
       Szimbolumok[];
     
    LoadSymbols (Szimbolumok);

    Miután a Szimbolumok tömb feltöltődött, felhasználhatod az elemeit.

    2. Igen, a globális változók csak double típusúak lehetnek. Ellenben a nevükkel is lehet trükközni: csinálsz egy prefixet (_kiskutya_) és mögé rakod az értékes(ebb) adatokat is. Példa:

    _kiskutya_EURUSD_
    _kiskutya_GBPUSD_

    Amikor szükséged van az adatokra, beolvasod az összes GV-t, és kiszűröd belőle a prefix-szeiddel rendelkezőeket. Aztán kiszeded a változónévből a hasznos adatot, plusz az értéket és kész.

    Bonyolultabb példa:

    _kiskutya|EURUSD|1|1.0455|1.0055

    Itt természetesen a | jel szeparátor feladatát tölti be.

    3. Igen, csak a nevével tudsz rá hivatkozni. Illetve, ha te készítesz valamilyen háttértámogatást egy tömb formájában, akkor hivatkozhatsz a Szimbolumok kulcsával is.

    Egyébként a te megoldásod is jópofa 🙂

    Ui: a kódformázást trükközéssel csináltam, sajna még egyelőre nem érhető el a fórumposztokon keresztül

    Roden
    Tag
    Bejegyzések száma: 46

    Köszönöm a kódot. Pontosan erre van szükségem.
    A _prefix-es névadás is jó ötletnek tűnik, pláne most hogy jobban megnéztem; a GlobalVariablesDeleteAll() függvény is mintha direkt ehhez lenne kitalálva.

    A kódott elnézve mindjárt felvetődött bennem a kérdés, hogy instrumentumtípusonként szeparálva (forex, commodities,stb.) is le lehetne kérdezni a szimbólumokat, mondjuk egy két dimenziós tömbbe?

    A Row változónak van vmilyen gyakorlati jelentősége, vagy inkább csak a jobb olvashatóság miatt van a kódban?

    Radulovic Attila
    Tag
    Bejegyzések száma: 646

    A GlobalVariablesDeleteAll() -t még írni is akartam, csak elfelejtettem!:)

    Az instrumentumtípusonkénti szeparalást passzolom, én anno már annak is örültem, hogy ezt az alap megoldást sikerült meglelni. Nyilván a symbols.sel -ben a kategorizálás is benne van, de hogy hogy szedjük ki az számomra ismeretlen kérdés.

    A Row változónak ott volt jelentősége, hogy a korábbi tesztelés során Printtel kiírattam a sorokat, nem szeretem duplán elvégezni azt, amit elég egyszer – és benne hagytam a kódban. Amúgy persze, kiveheted.

    Roden
    Tag
    Bejegyzések száma: 46

    Sebaj. Ez is tuti.

    A fentebb levő Symbol_ID függvénynek leginkább akkor van értelme, ha az általa generált double értékből újból ki lehet nyerni az eredeti stringet. Ide bigyesztem azt is hátha vkit érdekel:

    string SydToName(double syd=0)
    {
    int karakterdb = StringLen(DoubleToStr(syd,0))/2;
    int charcode=0;
    string symbol_name=””;
    for (int i=1; i<=karakterdb; i++) {

    //az utolsó két számjegy kinyerése maradékos osztással
    charcode=MathMod(syd,100);

    //összerakjuk a szimbólumnevet karaktereneként
    symbol_name=StringConcatenate(CharToStr(charcode),symbol_name);

    // megrövidítjük két számjeggyel a következő ciklushoz
    syd=(syd-charcode)/100;
    }
    return(symbol_name);
    }

    Max 8 karakter hosszúságú neveket lehet vele helyesen átalakítnai. Tehát pl. a FxPro-n elérhető SILVEREURO szimbólumnevet nem. Ehhez tovább kéne fejleszteni, a tizedesjegyeket is bevonva a karakterábrázolásba.
    Persze nem csak szimbólumnevek hanem bármilyen NAGYBETŰS(!) ill. két számjeggyel kódolt (ASCII)karaktereket tartalmazó string is átadható vele.

    Mivel igen rövid előéletem van a programozást tekintve, ha bárki hibát talál az áltlam leírt kód(okban) vagy tud egy hatékonyabb megoldást és megírja, azt örömmel veszem.

    Roden
    Tag
    Bejegyzések száma: 46

    Instrumentum lista lekérdezése – az oroszok így csinálják 🙂 :
    http://codebase.mql4.com/6134
    http://codebase.mql4.com/source/18718 (SymbolsLib.mq4)

    Radulovic Attila
    Tag
    Bejegyzések száma: 646

    Akkor csak meglett a csoportosítás is, ugye ? 😉 Köszi a tippet!

    Ferenc_
    Tag
    Bejegyzések száma: 8

    A CHART_WINDOW_HANDLE is le lehet kérdezni így azonos szimbólumú, és idősíkú chartoknak különböző globális változó nevet lehet adni (bár általában erre ritkán van szükség). Az egyértelmű azonosításhoz CHART_WINDOW_HANDLE 5 jegyű szám elég (súgóban még egy függvény forráskódja is van ennek a lekérdezéséhez), de a könnyebb értelmezhetőség miatt a globális változók nevébe a szimbólumot és idősíkot érdemes bele tenni.

    Az MT4 build 900 következő problémával találkoztam, egy chartra 2 indikátort raktam fel, az egyik létre hozta a globális változót, GBP JPY60 67338 valami néven, a név generáláshoz a _Symbol MQL4 előredefiniált változót használtam, ez rakta bele a szóközt. A másik indikátor lekérdezte a globális változót, de nem létezett. A hiba az volt, hogy amit kérdezett:
    GBPJPY60 67338 valami volt, de a _Symbol itt nem rakta bele a szóközt. Tehát _Symbol kénye kedve szerint vagy belerakja vagy kihagyja a szóközt. Kénytelen leszek szóköztelenítő függvényt írni, és át nézni az összes forráskódom van-e benne _Symbolra kényes rész.

    Ferenc_
    Tag
    Bejegyzések száma: 8

    Elnézést, de az előző bejegyzésem második bekezdése fals. Kiderül, hogy a _Symbol nem rak bele szóközt, csak nem proporcinális a betű típus és úgy néz ki van benne szóköz P és J betű között pedig nincs. Más instrumentumnál nem tűnne úgy.

    Ferenc_
    Tag
    Bejegyzések száma: 8

    Mi értelme van letölteni a szimbólum listát?
    Gondolkoztam rajta, aztán írtam egy scriptet a LoadSymbols függvényhez. Az orosz módszert nem néztem meg, mert az bonyolultabbnak tűnt. Vigyázni kell, hogy legyen valamilyen profil a MetaTraderben mert, 100 ablakot elég nehéz kézzel, egyenként bezárni, persze lehetne arra is írni scriptet. Sok időt lehet spórolni ezzel a programmal.

    #property description "A piacfigyelő által megjelenített szimbólumok csv fileba írása, és/vagy megnyitása"
    #property description "Csak korlátozott számban: maximum 100 nyitható meg, a már megnyitottakkal együtt"
    #property script_show_inputs
    #property strict
    //+------------------------------------------------------------------+
    #include <stdlib.mqh>  //ErrorDescription-hoz kell
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    enum boole {nem,igen};
    input boole FileWriting=nem;//fileba írás
    input boole AllSymbolOpen=igen;//az összes szimbolum megnyitása maximum 100
    input int TimeFrame=PERIOD_H1;//Idősík
    void OnStart()
    {
       string Szimbolumok[];
       int i;
       int db=0;  
       int filehandle=INVALID_HANDLE; 
       int Error;
       //+---
       if(!FileWriting && !AllSymbolOpen)
       {
         Alert("A script ezzel a beállítással nem csinál semmit");
       }
       else
       {   
    		LoadSymbols (Szimbolumok);
    	   db=ArraySize(Szimbolumok);
    	   
    	   if(db)
    	   {     
    		   if(FileWriting)
    		   {
    			   filehandle=FileOpen("Symbollist.csv",FILE_WRITE|FILE_CSV);
    			}   	     	      
    			for(i=0;i<db;i++ )
    			{
    		 	    if(FileWriting && filehandle!=INVALID_HANDLE) 
    		 	    {
    			        FileWrite(filehandle,Szimbolumok[i]);
    			    }  
    			    if(AllSymbolOpen && db<CHARTS_MAX)  
    			    {
    			         if(!ChartOpen(Szimbolumok[i],TimeFrame))				        
    					   { 
    					      Error=GetLastError();		        
    			            Print(__FUNCTION__,"  ",__LINE__," Error code = ",Error," ",ErrorDescription(Error));		          
    			         }
    			    }
    		   }
    		   if(filehandle!=INVALID_HANDLE)
    		   {
    			    FileClose(filehandle);		
    			}    
    		}  
    	}
    }
    Ferenc_
    Tag
    Bejegyzések száma: 8

    Apró hiba van a kódban, nem mindig működik,
    if(AllSymbolOpen && i<CHARTS_MAX) kell a if(AllSymbolOpen && db<CHARTS_MAX) helyett a 43 sorban

    Ferenc_
    Tag
    Bejegyzések száma: 8

    A for(i=0;i<db;i++ ) helyett a for(i=0;i<db-1;i++ ) jobbnak tűnik, mert különben egy plussz instrumentumot jelenit meg, de ha 2-nél kevesebb az instrumentum azt nem tudom kipróbálni, mert van nyitott pozícióm és azokat nem engedi az MT4 kitörölni a piacfigyelőből.

    Radulovic Attila
    Tag
    Bejegyzések száma: 646

    Köszönöm mások nevében, hogy megosztottad!

    Radulovic Attila
    Tag
    Bejegyzések száma: 646

    Az alábbi meglátásaim vannak (köszönöm az e-mailt, amit küldtél):

    A db értékét ne csökkentsd eggyel, az jó úgy ahogy van; ehelyett ellenőrizd hogy az a chart, amely épp nyitva van (vagyis amiről a szkriptet indítottad) ne legyen kinyitva még egyszer. Ezt ezzel a kódsorral megteheted:

    if (Szimbolumok[i] != Symbol()) {
    
    }
    

    Természetesen ha pontosak szeretnénk lenni, akkor meg lehetne nézni, hogy a jelenleg nyitott chartok közül van-e olyan amit nem kellene még egyszer megnyitni. Legyen ez a házi feladat 🙂

    Egy int() típusváltást beraktam, hogy a warning is eltűnjön.

    Csatolom a módosított kódot, még egyszer köszi hogy megosztottad!

    #property description "A piacfigyelő által megjelenített szimbólumok csv fileba írása, és/vagy megnyitása"
    #property description "Csak korlátozott számban: maximum 100 nyitható meg, a már megnyitottakkal együtt"
    #property script_show_inputs
    #property strict
    //+------------------------------------------------------------------+
    #include   //ErrorDescription-hoz kell
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    enum boole {nem,igen};
    input boole FileWriting=nem;//fileba írás
    input boole AllSymbolOpen=igen;//az összes szimbolum megnyitása maximum 100
    input int TimeFrame=PERIOD_H1;//Idősík
    void OnStart()
    {
       string Szimbolumok[];
       int i;
       int db=0;  
       int filehandle=INVALID_HANDLE; 
       int Error;
       //+---
       if(!FileWriting && !AllSymbolOpen)
       {
         Alert("A script ezzel a beállítással nem csinál semmit");
       }
       else
       {   
    		LoadSymbols (Szimbolumok);
    	   db=ArraySize(Szimbolumok);
     
    	   if(db)
    	   {     
    		   if(FileWriting)
    		   {
    			   filehandle=FileOpen("Symbollist.csv",FILE_WRITE|FILE_CSV);
    			}   	     	      
    			for(i=0;i= 0) {
     
          ElementCount = (int(FileSize(fileHandle)) - 4) / 128;
     
          ArrayResize(SymbolsArray, ElementCount);
     
          FileSeek(fileHandle, 4, SEEK_SET);
     
          for (int k = 0; k < ElementCount; k++) {
     
             Row = FileReadString(fileHandle, 12);
             SymbolsArray[k] = Row;
     
             FileSeek(fileHandle, 116, SEEK_CUR);
          }
     
          FileClose(fileHandle);
       }
    }
    

15 bejegyzés megtekintése - 1-15 / 17

A hozzászóláshoz jelentkezz be!

Adhatok Neked még több ingyenes tartalmat?

Értesítelek hetente megjelenő új tartalmaimról.

Hozzájárulok, hogy az adatvédelmi nyilatkozat szerint biztonságosan kezeld megadott adataimat, valamint hasznos anyagokat és egyedi ajánlatokat küldj nekem termékeiddel, szolgáltatásaiddal kapcsolatban e-mailben