Instrumentum lista lekérdezése 2012-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: 644

    Ö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: 644

    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: 644

    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: 644

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

    Radulovic Attila
    Tag
    Bejegyzések száma: 644

    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.