English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
preview
Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 16): İnternetteki verilere erişme (II)

Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 16): İnternetteki verilere erişme (II)

MetaTrader 5Entegrasyon | 31 Mayıs 2023, 09:19
291 0
Daniel Jose
Daniel Jose

Giriş

Bir önceki "Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 15): İnternetteki verilere erişme (I)" makalesinde, piyasalar hakkında bilgi sağlayan web sitelerinden verilere erişmek için MetaTrader 5 platformunun nasıl kullanılacağına ilişkin mantığı ve fikirleri inceledik.

Makalede, ilgili sitelere nasıl erişileceğini ve platformda kullanmak üzere bu sitelerden bilgilerin nasıl bulunup alınacağını ele aldık. Ancak iş burada bitmiyor, çünkü sadece verileri yakalamak pek bir anlam ifade etmiyor. En ilginç kısım aslında bu verilerin platformdan Uzman Danışmana nasıl alınıp kullanılacağını bilmektir. Bunu yapmanın yolu o kadar net değildir. MetaTrader 5'te bulunan tüm işlevleri gerçekten anlamadan bunu yapabilmek zordur.


Planlama ve uygulama

Önceki makaleyi okumadıysanız, onu okumanızı ve orada bulunan tüm konseptleri anlamaya çalışmanızı tavsiye ederim, çünkü burada bu konuya devam edeceğiz - MetaTrader 5'i pek keşfedilmemiş bir şekilde kullanarak çok sayıda şeyi inceleyeceğiz, birçok sorunu çözeceğiz ve sonunda güzel bir çözüme ulaşacağız. Bunu söylüyorum çünkü platformda bulunan bazı özelliklerin kullanımına ilişkin yeterli bilgi kaynağı bulmak zordu, dolayısıyla burada bu özelliklerin nasıl kullanılacağını açıklamaya çalışacağım.

Öyleyse hazırlanalım ve işe koyulalım.


1. Uzman Danışman aracılığıyla internetteki verilere erişme

Sistemdeki en ilginç kısım burasıdır. Basit bir şey olmasına rağmen, kötü planlandığında açık ara en tehlikeli kısımdır. Tehlikelidir çünkü Uzman Danışmanı bir an için bile olsa sunucudan yanıt beklemek zorunda bırakabilir.

Bu mantık aşağıdaki görüntüde gösterilmektedir:

Uzman Danışmanın yakalamak istediğimiz bilgileri içeren web sunucusuyla doğrudan nasıl etkileşim kurduğunu görelim. Aşağıda tam olarak bu şekilde çalışan bir kod örneği bulunmaktadır:

#property copyright "Daniel Jose"
#property version "1.00"
//+------------------------------------------------------------------+
int OnInit()
{
        EventSetTimer(1);
        
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+
void OnTimer()
{
        Print(GetDataURL("https://tradingeconomics.com/stocks", 100, "<!doctype html>", 2, "INDU:IND", 172783, 173474, 0x0D));
}
//+------------------------------------------------------------------+
string GetDataURL(const string url, const int timeout, const string szTest, int iTest, const string szFind, int iPos, int iInfo, char cLimit)
{
        string  headers, szInfo = "";
        char    post[], charResultPage[];
        int     counter;
   
        if (WebRequest("GET", url, NULL, NULL, timeout, post, 0, charResultPage, headers) == -1return "Bad";
        for (int c0 = 0, c1 = StringLen(szTest); c0 < c1; c0++) if (szTest[c0] != charResultPage[iTest + c0]) return "Failed";
        for (int c0 = 0, c1 = StringLen(szFind); c0 < c1; c0++) if (szFind[c0] != charResultPage[iPos + c0]) return "Error";
        for (counter = 0; charResultPage[counter + iInfo] == 0x20; counter++);
        for (;charResultPage[counter + iInfo] != cLimit; counter++) szInfo += CharToString(charResultPage[counter + iInfo]);
        
        return szInfo;
}
//+------------------------------------------------------------------+

Yakından bakarsanız, kodun önceki makalede oluşturulan kodla tamamen aynı olduğunu görebilirsiniz, ancak şimdi bu kod Uzman Danışmanın bir parçasıdır ve onun için adapte edilmiştir; yani önceden halihazırda çalıştıysa, şimdi burada da çalışacaktır. Aradaki fark, Uzman Danışmanın yeni bir koşul içermesidir, bu da kodun her saniye yürütüleceği anlamına gelir, yani Uzman Danışman her saniye belirtilen web sunucusuna istekte bulunacak ve yanıt bekleyecektir. Ardından yakalanan verileri sağlayacak ve diğer dahili fonksiyonları çalıştıracaktır. Bu döngü Uzman Danışmanın ömrü boyunca tekrarlanacaktır. Yürütme sonucu aşağıdan görülebilir.


Bu tam olarak bu şekilde yapılsa da, böyle uygulanmasını tavsiye etmiyorum çünkü Uzman Danışman birkaç dakika bile olsa sunucunun yanıtını beklerken takılıp kalabilir - ki bu da platformun ticaret sistemini ve Uzman Danışmanın kendisini tehlikeye atabilir. Öte yandan, sadece yöntemi öğrenmekle ilgileniyorsanız, o zaman bu sistem aracılığıyla çok şey öğrenebilirsiniz.

Ancak, internetteki bilgiler ile platform arasında yönlendirmeleri yapacak bir yerel sunucunuz varsa, belki de bu yöntem sizin için yeterli olabilir. Bu durumda, sistem bir istekte bulunduğunda, şu gerçekleşecektir: yerel sunucu henüz herhangi bir bilgiye sahip olmayacak ve hızlı bir şekilde yanıt verecektir, bu da sizi sonraki adımlardan kurtaracaktır.

Şimdi bu tür bir görevi gerçekleştirmenin biraz daha güvenli olan başka bir yolunu ele alalım. Bir miktar güvenlik elde etmek ve Uzman Danışmanın uzak web sunucusunun koşullarına tabi olmasını önlemek için MetaTrader 5 iş parçacığı sistemini kullanacağız, böylece uzak sunucunun yanıt vermesini beklerken kendimizi birkaç dakikalığına askıya alabileceğiz. Uzman Danışmanın neler olup bittiğini bilmesi, internetten bilgi toplayabilmesi adına ek koşullar oluşturacağız.


2. İletişim kanalı oluşturma

Çevrimiçi olarak toplanan verileri almanın ve onları bir Uzman Danışmanda kullanmanın daha iyi ve daha basit bir yolu bir kanaldır. Her ne kadar işe yarasa da, bazı durumlarda bu tür kanalların kullanımında sınırlamalar olduğu için bizim için pek de uygun değildir. Ancak en azından Uzman Danışman, uzak sunucudan yanıt beklemek zorunda kalmadan internetten toplanan bilgilere erişebilecektir.

Yukarıda, sorunu çözmenin en kolay yolunun verileri yönlendirmenin olduğunu belirtilmiştik: verileri indirecek ve MetaTrader 5 platformuna sağlayacak bir yerel sunucu oluşturmak. Fakat bu, belirli bir tecrübe ve hesaplama gücü gerektirir ve dolayısıyla süreci karmaşıklaştırır. Ancak, MetaTrader 5 özelliklerini kullanarak çok benzer bir kanal oluşturabiliriz, bu da yerel sunucu üzerinden yönlendirme yapılmasından çok daha basit olacaktır.

Aşağıdaki görüntü böyle bir kanalın nasıl düzenleneceğini göstermektedir.

Bir nesne kullanılarak oluşturulur. Uzman Danışmanın, komut dosyası tarafından yerleştirilen bilgiler için nesnenin içerisine bakacağını unutmayın. Bunun nasıl çalıştığını anlamak adına, aşağıda tam haliyle gösterilen üç koda göz atalım. Biri Uzman Danışman, diğeri nesneyi içeren header, bir diğeri de komut dosyası olacaktır.

#property copyright "Daniel Jose"
#property description "Testing Inner Channel"
#property version "1.00"
//+------------------------------------------------------------------+
#include <Inner Channel.mqh>
//+------------------------------------------------------------------+
int OnInit()
{
        
        EventSetTimer(1);
        
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+
void OnTimer()
{
        Print(GetInfoInnerChannel());
}
//+------------------------------------------------------------------+

Aşağıdaki kod kullanmamız gereken headerdır. Buradaki nesnenin, Uzman Danışman ve komut dosyası arasında paylaşılmak üzere bildirildiğine dikkat edin.

//+------------------------------------------------------------------+
//|                                          Canal Intra Process.mqh |
//|                                                      Daniel Jose |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#define def_NameObjectChannel   "Inner Channel Info WEB"
//+------------------------------------------------------------------+
void CreateInnerChannel(void)
{
        long id;
        
        ObjectCreate(id = ChartID(), def_NameObjectChannel, OBJ_LABEL, 0, 0, 0);
        ObjectSetInteger(id, def_NameObjectChannel, OBJPROP_COLOR, clrNONE);
}
//+------------------------------------------------------------------+
void RemoveInnerChannel(void)
{
        ObjectDelete(ChartID(), def_NameObjectChannel);
}
//+------------------------------------------------------------------+
inline void SetInfoInnerChannel(string szArg)
{
        ObjectSetString(ChartID(), def_NameObjectChannel, OBJPROP_TEXT, szArg);
}
//+------------------------------------------------------------------+
inline string GetInfoInnerChannel(void)
{
        return ObjectGetString(ChartID(), def_NameObjectChannel, OBJPROP_TEXT);
}
//+------------------------------------------------------------------+

Ve son olarak, komut dosyası. Yerel sunucu oluşturmanın yerini alacak ve aslında sunucunun işini yapacaktır.

#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
#include <Inner Channel.mqh>
//+------------------------------------------------------------------+
void OnStart()
{
        CreateInnerChannel();
        while (!IsStopped())
        {
                SetInfoInnerChannel(GetDataURL("https://tradingeconomics.com/stocks", 100, "<!doctype html>", 2, "INDU:IND", 172783, 173474, 0x0D));
                Sleep(200);
        }
        RemoveInnerChannel();
}
//+------------------------------------------------------------------+
string GetDataURL(const string url, const int timeout, const string szTest, int iTest, const string szFind, int iPos, int iInfo, char cLimit)
{
        string  headers, szInfo = "";
        char    post[], charResultPage[];
        int     counter;
   
        if (WebRequest("GET", url, NULL, NULL, timeout, post, 0, charResultPage, headers) == -1) return "Bad";
        for (int c0 = 0, c1 = StringLen(szTest); (!_StopFlag) && (c0 < c1); c0++) if (szTest[c0] != charResultPage[iTest + c0]) return "Failed";
        for (int c0 = 0, c1 = StringLen(szFind); (!_StopFlag) && (c0 < c1); c0++) if (szFind[c0] != charResultPage[iPos + c0]) return "Error";
        for (counter = 0; (!_StopFlag) && (charResultPage[counter + iInfo] == 0x20); counter++);
        for (;(!_StopFlag) && (charResultPage[counter + iInfo] != cLimit); counter++) szInfo += CharToString(charResultPage[counter + iInfo]);
        
        return (_StopFlag ? "" : szInfo);
}
//+------------------------------------------------------------------+

Burada, Uzman Danışmanın görebileceği, komut dosyası tarafından oluşturulan bir nesneye sahibiz. Fikir şudur: Uzman Danışman ve komut dosyası aynı grafikte bir arada bulunabilir, o zaman bu nesne Uzman Danışman ve komut dosyası arasındaki iletişim kanalı olacaktır. Uzman Danışman bir istemci, komut dosyası bir sunucu ve nesne de bunlar arasındaki bir iletişim kanalı olacaktır. Böylece, komut dosyası uzak web sunucusundaki değerleri yakalayacak ve istenilen değeri nesneye yerleştirecektir. Uzman Danışman zaman zaman nesnede hangi değerin olduğunu görecektir (nesne varsa), çünkü komut dosyası çalışmıyorsa nesne mevcut olmamalıdır. Uzman Danışmanın nesnedeki değere baktığı anlar, komut dosyasının yürütülmesini hiçbir şekilde ihlal etmez. Komut dosyası uzak sunucudan yanıt beklediği için engellenirse, bu durum Uzman Danışmanı etkilemez, çünkü komut dosyası ne yaparsa yapsın çalışmaya devam eder.

Bu harika bir çözüm olsa da mükemmel değildir: sorun komut dosyasındadır.

Bunu anlamak için aşağıdaki videoyu her ayrıntıya dikkat ederek izleyin.


Her şey harika çalışıyor. Bu beklenen bir şeydi, çünkü bu tür bir çözüm programlamada, birinin diğerini engellemesini istemediğimiz istemci-sunucu tipi programlar geliştirirken yaygın olarak kullanılmaktadır. Başka bir deyişle, işlemler arasında iletişim kurmak için bir kanal kullanıyoruz. Genellikle, aynı ortamda olduklarında, kanal bellek kullanılarak oluşturulur - bunun için özel olarak izole edilmiş bir alan tahsis edilir, ancak bu alan paylaşılır durumdadır, yani hem istemci hem de sunucu tarafından görülebilir. Sunucu buraya verileri ekler, istemci de mevcut verileri almak için bu alanı ziyaret eder. Dolayısıyla, her ikisi de birbiriyle ilişkili olsa da, biri diğerine bağımlı değildir.

Buradaki fikir aynı prensibi kullanmaktır. Ancak komut dosyasının çalışma şekli bir sorun oluşturuyor. Zaman dilimini değiştirdiğimizde komut dosyası kapanıyor; sonsuz bir döngü kullandığımızda bile MetaTrader 5 tarafından kapatılıyor. Bu olduğunda, komut dosyasını yeniden başlatarak grafiğe yeniden eklememiz gerekiyor. Ancak sürekli olarak zaman dilimini değiştirmemiz gerekirse, bu bir sorun teşkil edecektir, çünkü her seferinde komut dosyasını grafikte yeniden başlatma ihtiyacı ortaya çıkacaktır.

Ayrıca, komut dosyasının grafikte olup olmadığını kontrol etmeyi unutabiliriz ve bu nedenle, Uzman Danışmanın kodlanma şeklinden dolayı komut dosyasının grafikte olup olmadığını bilemeyeceğimiz için yanlış bilgileri kullanmış oluruz. Bunu, komut dosyasının grafikte olup olmadığı kontrol edecek şekilde Uzman Danışmanın kodunu iyileştirerek çözebiliriz. Bu görev zor değildir: nesneye komut dosyasının son gönderisinin zamanının kontrolünü yazmamız yeterlidir. Bu sorunu çözecektir.

Bununla birlikte, çok daha iyi bir çözüm oluşturmak mümkündür (en azından bazı durumlarda) ve dürüst olmak gerekirse, bu neredeyse ideal çözümdür ve yukarıda sunulan aynı konsepti kullanacağız, sadece komut dosyası yerine hizmet kullanacağız.


3. Hizmet oluşturma

Bu ekstrem bir çözümdür, ancak komut dosyasının her zaman dilimi değişikliğinde kapanma sorunu olduğu için başka bir yöntem kullanmamız gerekiyor. Ancak bir sorunu çözerken başka bir sorun oluşturuyoruz. Ne olursa olsun, hangi çözümlerin mümkün olduğunu ve nasıl kullanılabileceklerini bilmek iyidir. Ancak asıl önemli olan, her bir çözümün sunduğu sınırlamaları bilmek ve böylece sorunu mümkün olan en iyi şekilde çözmeye olanak sağlayan bir orta yol bulmaya çalışmaktır.

Programlama öyle bir şeydir ki, bir sorunu çözmeye çalıştığımızda yeni bir sorun meydana getirebiliyoruz.

Amacımız aşağıdaki görüntüye benzer bir şey oluşturmaktır:

Bu basit bir mesele gibi görünse de, burada yer alan kaynaklar genellikle çok az araştırılmıştır. Dolayısıyla, bu kaynaklarla nasıl çalışılacağı hakkında daha fazla bilgi edinmek isteyen herkese yardımcı olmak adına ayrıntılara girmeye çalışacağım.


3.1. Global değişkenlere erişme

Bu kısım o kadar az çalışılmıştır ki, ilk başta sadece bu fonksiyonu desteklemek için bir dll oluşturmayı bile düşündüm, ancak MQL5 dokümantasyonuna baktıktan sonra onu buldum. Sorun şu ki, hizmet ile Uzman Danışman arasında ortak bir noktaya erişmemiz veya ortak bir nokta oluşturmamız gerekiyor. Bir komut dosyası kullandığımızda bu nokta bir nesneydi, ancak bir hizmet kullandığımızda aynı şeyi yapamıyoruz. Çözüm harici bir değişken kullanmak olabilirdi, ancak bunu yapmaya çalıştığımda performans beklendiği gibi olmadı. Daha fazla ayrıntı için harici değişkenlerle ilgili dokümantasyonu okuyabilirsiniz. Ne yapılacağını açıklamaktadır.

Bu fikir iyi değildi, bu yüzden tekrar dll kullanmaya karar verdim. Ancak yine de MetaTrader 5 ve MQL5'i biraz daha keşfetmek istedim, bu yüzden terminale bakarken aşağıdaki görüntüdeki şeyi buldum:

         

Aradığımız şey buydu: bu prosedürün nasıl yapılandırılabileceğini kontrol edebilmek için bir değişken ekledik. Ancak, yalnızca double türü değerler kullanabiliyoruz. Bunun bir sorun olduğunu düşünebilirsiniz (evet bu gerçekten bir sınırlama olsa da), fakat bizim durumumuzda olduğu gibi kısa mesajlar iletmek istediğimizde bu yeterli olacaktır. double türü, 8 karakterlik kısa bir dizgedir, böylece programlar arasında değerler veya kısa mesajlar iletebilir.

Böylece sorunun ilk kısmı çözülmüş oldu. MetaTrader 5, bir dll oluşturmak zorunda kalmadan bir kanal oluşturmak için yöntemler sağlamaktadır, ancak şimdi başka bir sorunumuz var: bu değişkenlere program aracılığıyla nasıl erişilir? Program içerisinde - bir Uzman Danışman, bir komut dosyası, bir gösterge veya bir hizmet içerisinde - global değişkenler oluşturmak mümkün müdür? Yoksa sadece terminalde bildirilenleri mi kullanmamız gerekiyor?

Bu çözümü gerçekten kullanmak istiyorsak bu sorular çok önemlidir. Çünkü onları programlar aracılığıyla kullanmak mümkün değilse, dll'ler kullanmak zorunda kalacağız. Ancak bu mümkündür. Daha fazla bilgi için Terminalin Global Değişkenleri bölümüne bakın.


3.2. Bilgi alışverişi terminal değişkeni kullanma

Artık temel bilgilere sahip olduğumuza göre, terminal değişkenleri kullanma sürecinin pratikte nasıl çalışacağını test edip anlayabilmek için basit bir şey oluşturalım.

Bu amaçla aşağıdaki kodları oluşturdum. İlki header dosyasıdır:

#property copyright "Daniel Jose"
//+------------------------------------------------------------------+
#define def_GlobalNameChannel   "InnerChannel"
//+------------------------------------------------------------------+

Burada, terminalde çalışacak iki işlem için de aynı olacak global terminal değişkeninin adını tanımlıyoruz.

Aşağıda çalıştırılacak hizmeti temsil eden kod yer almaktadır:

#property service
#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
#include <Inner Channel.mqh>
//+------------------------------------------------------------------+
void OnStart()
{
        double count = 0;
        while (!IsStopped())
        {
                if (!GlobalVariableCheck(def_GlobalNameChannel)) GlobalVariableTemp(def_GlobalNameChannel);
                GlobalVariableSet(def_GlobalNameChannel, count);
                count += 1.0;
                Sleep(1000);
        }
}
//+------------------------------------------------------------------+

Çalışması basittir: değişkenin önceden bildirilip bildirilmediğini kontrol eder (bu, GlobalVariableCheck tarafından gerçekleştirilir). Değişken mevcut değilse, GlobalVariableTemp fonksiyonu tarafından geçici olarak oluşturulur ve GlobalVariableSet fonksiyonundan bir değer alır. Başka bir deyişle, bilgileri test ediyor, oluşturuyor ve yazıyoruz, hizmet tıpkı komut dosyası tarafından yapıldığı gibi bir sunucu olarak çalışıyor, sadece henüz web sitesine erişmiyoruz. Bu konuda acele etmeyelim, öncelikle sistemin nasıl işlediğini anlamalıyız.

Bir sonraki adım, bizim durumumuzda Uzman Danışman olan bir istemci oluşturmaktır:

#property copyright "Daniel Jose"
#property description "Testing internal channel\nvia terminal global variable"
#property version "1.03"
//+------------------------------------------------------------------+
#include <Inner Channel.mqh>
//+------------------------------------------------------------------+
int OnInit()
{
        EventSetTimer(1);
        
        return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
        EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick()
{
}
//+------------------------------------------------------------------+
void OnTimer()
{
        double value;
        if (GlobalVariableCheck(def_GlobalNameChannel))
        {
                GlobalVariableGet(def_GlobalNameChannel, value);
                Print(value);           
        }
}
//+------------------------------------------------------------------+

Kod basittir: Uzman Danışman her saniye değişkenin var olup olmadığını kontrol edecektir. Eğer varsa, Uzman Danışman GlobalVariableGet’i kullanarak değeri okuyacak ve bu değeri terminale çıktı olarak verecektir.

Bu sürecin nasıl uygulanabileceğini görelim. Önce hizmeti çalıştırıyoruz. Bu, şu şekilde yapılır:

Ancak hizmet durduğunda ve onu yeniden başlattığımızda başka bir senaryo da mümkündür. Bu durumda aşağıdaki şekilde ilerleyeceğiz:

Devamında, terminal değişkenlerini kontrol ediyoruz ve aşağıdaki sonucu elde ediyoruz:

Sistem çalışıyor olarak görünüyor, ancak şimdi Uzman Danışmanı grafiğe yerleştirmemiz, değerleri almamız ve böylece kanal üzerinden bağlantıyı onaylamamız gerekiyor. Uzman Danışmanı grafiğe yerleştirdikten sonra aşağıdaki sonucu elde ediyoruz:

Hepsi bu kadar, sistem istediğimiz şekilde çalışıyor. Aşağıda gösterilen modele sahibiz. Bu tipik bir istemci-sunucu formatıdır ve bizim yapmak istediğimiz de tam olarak budur. Daha önce bahsettiğim avantajlar nedeniyle tam olarak bu formatı uygulamaya çalışıyoruz.

Şimdi tek yapmamız gereken, internetten değerleri okumak ve almak için hizmete bir sistem eklemektir. Böylece test etmek için nihai modele sahip olacağız. Bu kısım oldukça kolaydır: en başından beri kullandığımız kodu hizmete ekleyeceğiz. Testi gerçekleştirmek için, web sitesinden değeri okuyacak ve bu değeri istemcinin okuması için yayınlayacak şekilde sunucu dosyasını değiştirmemiz yeterlidir. Yeni hizmet kodu aşağıdaki gibidir.

#property service
#property copyright "Daniel Jose"
#property version   "1.00"
//+------------------------------------------------------------------+
#include <Inner Channel.mqh>
//+------------------------------------------------------------------+
void OnStart()
{
        string szRet;
        
        while (!IsStopped())
        {
                if (!GlobalVariableCheck(def_GlobalNameChannel)) GlobalVariableTemp(def_GlobalNameChannel);
                szRet = GetDataURL("https://tradingeconomics.com/stocks", 100, "<!doctype html>", 2, "INDU:IND", 172783, 173474, 0x0D);
                GlobalVariableSet(def_GlobalNameChannel, StringToDouble(szRet));
                Sleep(1000);
        }
}
//+------------------------------------------------------------------+
string GetDataURL(const string url, const int timeout, const string szTest, int iTest, const string szFind, int iPos, int iInfo, char cLimit)
{
        string  headers, szInfo = "";
        char    post[], charResultPage[];
        int     counter;
   
        if (WebRequest("GET", url, NULL, NULL, timeout, post, 0, charResultPage, headers) == -1) return "Bad";
        for (int c0 = 0, c1 = StringLen(szTest); c0 < c1; c0++) if (szTest[c0] != charResultPage[iTest + c0]) return "Failed";
        for (int c0 = 0, c1 = StringLen(szFind); c0 < c1; c0++) if (szFind[c0] != charResultPage[iPos + c0]) return "Error";
        for (counter = 0; charResultPage[counter + iInfo] == 0x20; counter++);
        for (;charResultPage[counter + iInfo] != cLimit; counter++) szInfo += CharToString(charResultPage[counter + iInfo]);
        
        return szInfo;
}
//+------------------------------------------------------------------+

Artık aşağıdaki görüntüde gösterildiği gibi çalışan bir sisteme sahibiz:

Sistemimiz neredeyse tamamlandı ve çalıştırdığımızda aşağıdaki sonuçları alıyoruz. Ayrıca, zaman dilimini değiştirmek de artık sorun olmayacak.



Sonuç

Bugün, MetaTrader 5 platformunda daha önce çok az keşfedilmiş birkaç özelliği inceledik. Bunlardan biri iletişim kanallarıdır. Ancak, bu özellikten hala tam olarak faydalanamıyoruz. Daha da ileriye gidebiliriz - bunu bir sonraki makalede yapacağız. Bu makale serisinde şimdiye kadar gördüğümüz her şey bize MetaTrader 5 platformunda ne kadar çok şey yapabileceğimizi gösteriyor. Sadece bir yol seçmeli ve istediğimiz sonuçları elde edene kadar bu yolda devam etmeliyiz; bu süreçte olası yolların her biriyle ilişkili sınırlamaların, faydaların ve risklerin de farkında olmalıyız.


MetaQuotes Ltd tarafından Portekizceden çevrilmiştir.
Orijinal makale: https://www.mql5.com/pt/articles/10442

Ekli dosyalar |
Script_e_EA.zip (3.03 KB)
Serviso_e_EA.zip (2.39 KB)
Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 17): İnternetteki verilere erişme (III) Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 17): İnternetteki verilere erişme (III)
Bu makalede, internetten nasıl veri elde edileceğini ve Uzman Danışmanda nasıl kullanılacağını ele almaya devam ediyoruz. Bu kez alternatif bir sistem geliştireceğiz.
Veri Bilimi ve Makine Öğrenimi (Bölüm 06): Gradyan İniş Veri Bilimi ve Makine Öğrenimi (Bölüm 06): Gradyan İniş
Gradyan iniş, sinir ağlarının ve çeşitli makine öğrenimi algoritmalarının eğitiminde önemli bir rol oynamaktadır - hızlı ve akıllı bir algoritmadır. Etkileyici bir şekilde çalışmasına rağmen, birçok veri bilimci tarafından hala yanlış anlaşılmaktadır. Bu makalemizde onu detaylıca inceleyerek daha iyi anlayacağız.
Standard Deviation göstergesine dayalı bir ticaret sistemi nasıl geliştirilir? Standard Deviation göstergesine dayalı bir ticaret sistemi nasıl geliştirilir?
MetaTrader 5 işlem platformunda kullanılmak üzere en popüler teknik göstergelere dayalı ticaret sistemleri geliştirdiğimiz serimizin yeni makalesindeyiz. Bu yeni makalede, Standard Deviation göstergesine dayalı bir ticaret sisteminin nasıl tasarlanacağını öğreneceğiz.
CCI göstergesi: Yeni hesaplama yöntemleri CCI göstergesi: Yeni hesaplama yöntemleri
Bu makalede, CCI göstergesini yeni hesaplama yöntemleriyle iyileştirmeye çalışacağız.