English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
preview
Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 18): Yeni emir sistemi (I)

Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 18): Yeni emir sistemi (I)

MetaTrader 5Ticaret | 26 Haziran 2023, 09:21
356 0
Daniel Jose
Daniel Jose

Giriş

Uzman Danışmanımızı ilk makaleden (Sıfırdan bir ticaret Uzman Danışmanı geliştirme) itibaren makalelerimizde belgelemeye başladığımızdan beri, çeşitli değişiklikler ve iyileştirmelerden geçti, ancak aynı grafik üzeri emir sistemi modelini korudu. Bu model çok basit ve işlevseldir. Ancak, birçok durumda gerçek ticaret için uygun değildir.

Elbette orijinal sisteme bazı şeyler ekleyebiliriz, böylece hem açık hem de bekleyen emirler hakkında daha fazla bilgi sahibi olabiliriz. Ancak bir bakıma bu, kodumuzu bir Frankenstein'a dönüştürecek ve nihayetinde iyileştirme sürecini de gerçek bir kabus haline getirecektir. Kendi metodolojiniz olsa bile, kod çok büyük ve çok karmaşık hale geldikçe bu düzen zamanla kaybolacaktır.

Dolayısıyla, kullandığımız emir modeli açısından tamamen farklı bir sistem oluşturmamız gerekmektedir. Aynı zamanda, güvenli bir şekilde çalışmak için ihtiyaç duyulan tüm bilgileri sağlarken, yatırımcının anlaması da kolay olmalıdır.


Önemli not

Bu makalede anlattığım sistem, sembol başına yalnızca bir açık pozisyona izin veren netting hesapları ACCOUNT_MARGIN_MODE_RETAIL_NETTING için tasarlanmıştır. Bir hedging hesabı ACCOUNT_MARGIN_MODE_RETAIL_HEDGING kullanıyorsanız, makale Uzman Danışmana hiçbir katkı sağlamayacaktır, çünkü bu durumda aynı anda ihtiyacınız olduğu kadar biri diğerine müdahale etmeyen açık pozisyona sahip olabileceksiniz. Dolayısıyla, son koddaki tüm değişiklikleri sıfırlayabilir ve kaldırabilirsiniz.

ACCOUNT_MARGIN_MODE_RETAIL_HEDGING modu çoğunlukla Uzman Danışmanın otomatik olarak çalışmasını, sizin katılımınız olmadan pozisyonlar açıp kapatmasını ve aynı zamanda da manuel olarak ticaret işlemleri gerçekleştirmeye devam etmek istediğinizde kullanılır. Bunu yaparken, Uzman Danışmanın ticaret yaptığı aynı varlıkla ticaret yapabilirsiniz. Hedging ile Uzman Danışmanın faaliyetleri hiçbir işleminizi etkilemez, bu sayede bağımsız pozisyonlara sahip olabilirsiniz.

Bu nedenle, değiştirilen veya eklenen tüm kod parçalarını vurgulayacağım. Tüm değişiklikleri ve eklemeleri yavaş ve kademeli olarak uygulayacağız, böylece koddan herhangi bir şeyi kaldırmanız gerekirse, ilgili kod parçalarını kolayca bulabileceksiniz.

Değişiklikler kaldırılabilse de sistemi test edeceğim bir kısım vardır. Burada ele alacağımız değişiklikleri kaydetseniz bile, bu Uzman Danışmanı netting veya hedging herhangi bir türdeki işlem hesabında kullanabilirsiniz, çünkü Uzman Danışman ilgili modeli kontrol edecek ve buna göre ayarlamalar yapacaktır.


1.0. Planlama

Aslında yapılması gereken ilk şey, sisteme eklenen ve uygun fiyatlara ulaştıklarında yerine getirilen emirlere ne olduğunu anlamaktır. Birçok yatırımcı bunu bilmiyor olabilir ya da daha doğrusu bunu hiç düşünmemiş olabilir ve bu nedenle fikri anlamak ve ardından yeterli ama güvenilir bir sistem uygulamak için herhangi bir test yapmamış olabilir.

Gerçekte ne olduğunu anlamak için basit bir örneği analiz edelim: belirli bir varlık için 1 lotluk bir alış pozisyonuna sahip olduğumuzu varsayalım. Ardından, biraz daha yüksek bir fiyattan 2 lotluk yeni bir alış emri yerleştiriyoruz. Şimdiye kadar iyi, özel bir şey yok. Ancak bu 2 lot alınır alınmaz bir şeyler olacak; işte sorun da burada yatıyor.

Bu 2 lot alındığında, 3 lota sahip olacağız ve sistem başlangıç fiyatımızı ortalama fiyata güncelleyecektir. Şimdi burası net görünüyor ve herkes anlıyor. Ancak peki yeni pozisyonun zararı durdur ve kârı al seviyelerine ne olacak?

Birçok yatırımcı cevabı bilmiyor, ancak bunun dikkate alınması önemlidir. Tüm işlemlerde OCO emir sistemini (One Cancel the Other, biri diğerini iptal eder) kullanıyorsanız, toplam işlem hacminin bir kısmıyla her pozisyon açtığınızda veya kapattığınızda ilginç bir şey fark edebilirsiniz.

Çapraz emirler hakkındaki makalede, standart MetaTrader 5 sistemini kullanmadan, kârı al ve zararı durdur seviyelerini doğrudan grafik üzerinde yerleştirmenin bir yolunu sundum. Aslında bu yöntem MetaTrader 5 sistemiyle neredeyse aynıdır, çünkü işlevselliği platformunkine çok yakındır. Ancak, bazı testler yaptıktan sonra, bir açık OCO emrimiz ve bir bekleyen emrimiz olduğunda, fiyat emirde belirtilen değere ulaştığında OCO emrinin de ticaret sistemi tarafından yakalandığını gördüm. Yeni ortalama fiyata ek olarak, kârı al ve zararı durdur değerlerinde de değişiklik olmaktadır - bu değerler, son yakalanan OCO emrinde belirtilen değerlerle değiştirilmektedir. Dolayısıyla, nasıl yapılandırıldığına bağlı olarak, ticaret sistemi yeni kârı al ve zararı durdur değerlerini bildirdikten hemen sonra Uzman Danışman onu kapatacaktır.

Bu, Uzman Danışmanda bulunan aşağıdaki kontrolle gerçekleşir:

inline double CheckPosition(void)
{
        double Res = 0, last, sl;
        ulong ticket;
                                
        last = SymbolInfoDouble(Terminal.GetSymbol(), SYMBOL_LAST);
        for (int i0 = PositionsTotal() - 1; i0 >= 0; i0--) if (PositionGetSymbol(i0) == Terminal.GetSymbol())
        {
                ticket = PositionGetInteger(POSITION_TICKET);
                Res += PositionGetDouble(POSITION_PROFIT);
                sl = PositionGetDouble(POSITION_SL);
                if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
                {
                        if (last < sl) ClosePosition(ticket);
                }else
                {
                        if ((last > sl) && (sl > 0)) ClosePosition(ticket);
                }
        }
        return Res;
};

Vurgulanan satırlar bu kontrolü gerçekleştirir ve fiyatın kârı al ve zararı durdur değerlerinin oluşturduğu kanaldan çıkması durumunda emri kapatır.

Bunu bilmek önemlidir çünkü burada bir Uzman Danışman hatasından, bir ticaret sistemi sorunu veya kusurundan bahsetmiyoruz. Asıl sorun, çoğu zaman olup bitenlere gereken dikkati göstermememiz ve bu gerçeğe göz yummamız artık mümkün olmayana kadar bu tür şeyleri görmezden gelmemizdir.

Ortalama fiyat olmayacak şekilde işlem yapıyorsanız, bu tür bir şeyin gerçekleştiğini görmezsiniz. Ancak, ortalama fiyatın uygun ve hatta gerekli olduğu çok geniş bir işlem yelpazesi vardır. Ve bu durumlarda, yukarıdaki ayrıntıları bilmeden sistemi kullanırsanız, daha önce açık pozisyonun OCO emrini uygun şekilde değiştirmiş olsanız bile, pozisyondan istediğinizden daha erken çıkabilirsiniz. Bekleyen OCO emri yakalandığı anda, eşik değerleri (bundan sonra eşiklerden her bahsettiğimde, önceki kârı al ve zararı durdur değerlerini kastedeceğim) son yakalanan bekleyen OCO emrinde belirtilenlerle değiştirilecektir.

Bunu düzeltmenin veya daha doğrusu bundan kaçınmanın bir yolu vardır: OCO emirlerini kullanmayın, en azından halihazırda bir açık pozisyonunuz varsa. Sisteme iletilen diğer tüm emirler, tanımlı kârı al ve zararı durdur değerleri olmaksızın basit türde olmalıdır.

Temel olarak, hepsi bu kadar. Grafikteki Uzman Danışman, bize yardımcı olmak ve hayatımızı olabildiğince kolaylaştırmak için oradadır. Aksi takdirde, daha sonra kullanmayacaksak, bir Uzman Danışman programlamak için tüm bu çalışmaları yapmanın bir anlamı yoktur.


2.0. Yeni sistemin uygulanması

Sistemi uygulamak ve beklediğimiz şekilde çalışmasını sağlamak için kodda küçük değişiklikler yapmamız gerekiyor - Uzman Danışman bize yardımcı olmalı ve hataları önlemelidir.

Bu değişiklikler, işlemlerimizde ciddi bir karışıklığa neden olabilecek istenmeyen bir anda OCO emri gelmesi riskiyle asla karşılaşmayacağımızı garanti eder.

Aşağıdaki değişikliklerle başlayalım:


2.0.1. C_Router sınıfının değiştirilmesi

C_Router sınıfı, emirlerin ayrıştırılmasından ve bize gönderilmesinden sorumludur. Ona bir private değişken ekleyelim. Uzman Danışmanın işlem gerçekleştirdiği varlıkta bir açık pozisyon bulunduğunda, bu değişken ilgili bilgileri depolayacaktır. Uzman Danışman, bir açık pozisyon olup olmadığını her öğrenmek istediğinde, bize bunu söyleyecektir.

Bu uygulama aşağıdaki kodda gösterilmektedir. Ancak, bu kod makale boyunca daha da değiştirilecektir. Değişiklik sürecinin gerçekte nasıl ilerlediğini anlayabilmeniz için tüm değişiklikleri adım adım göstermek istiyorum.

//+------------------------------------------------------------------+
inline bool ExistPosition(void) const { return m_bContainsPosition; }
//+------------------------------------------------------------------+
void UpdatePosition(void)
{
        static int memPositions = 0, memOrder = 0;
        ulong ul;
        int p, o;
                                
        p = PositionsTotal();
        o = OrdersTotal();
        if ((memPositions != p) || (memOrder != o))
        {
                ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, false);
                RemoveAllsLines();
                ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, true);
                memOrder = o;
                memPositions = p;
                m_bContainsPosition = false;
        };
        for(int i0 = p; i0 >= 0; i0--) if(PositionGetSymbol(i0) == Terminal.GetSymbol())
        {
                ul = PositionGetInteger(POSITION_TICKET);
                m_bContainsPosition = true;
                SetLineOrder(ul, PositionGetDouble(POSITION_PRICE_OPEN), HL_PRICE, false);
                SetLineOrder(ul, PositionGetDouble(POSITION_TP), HL_TAKE, true);
                SetLineOrder(ul, PositionGetDouble(POSITION_SL), HL_STOP, true);
        }
        for (int i0 = o; i0 >= 0; i0--) if ((ul = OrderGetTicket(i0)) > 0) if (OrderGetString(ORDER_SYMBOL) == Terminal.GetSymbol())
        {
                SetLineOrder(ul, OrderGetDouble(ORDER_PRICE_OPEN), HL_PRICE, true);
                SetLineOrder(ul, OrderGetDouble(ORDER_TP), HL_TAKE, true);
                SetLineOrder(ul, OrderGetDouble(ORDER_SL), HL_STOP, true);
        }
};
//+------------------------------------------------------------------+


Vurgulanan satırlar, Uzman Danışman kodunun belirli yerlerine daha sonra eklenecek kontrolleri çalıştırmak için gerekli eklemeleri göstermektedir.

Bir bakıma, tüm kontrolleri ve ayarlamaları sadece C_Router sınıfında uygulayabilirdik, ancak bu yeterli olmayacaktır. Bunu daha sonra açıklayacağım. Şimdi değişikliklere devam edelim. Yukarıdaki kontrolü oluşturduktan sonra, yeni eklenen değişkeni düzgün bir şekilde başlatmak için bir yapıcı ekleyelim.

C_Router() : m_bContainsPosition(false) {}


Şimdi bekleyen emirleri yerleştiren fonksiyonu aşağıdaki gibi düzenliyoruz:

ulong CreateOrderPendent(const bool IsBuy, const double Volume, const double Price, const double Take, const double Stop, const bool DayTrade = true)
{
        double last = SymbolInfoDouble(Terminal.GetSymbol(), SYMBOL_LAST);
                                
        ZeroMemory(TradeRequest);
        ZeroMemory(TradeResult);
        TradeRequest.action             = TRADE_ACTION_PENDING;
        TradeRequest.symbol             = Terminal.GetSymbol();
        TradeRequest.volume             = Volume;
        TradeRequest.type               = (IsBuy ? (last >= Price ? ORDER_TYPE_BUY_LIMIT : ORDER_TYPE_BUY_STOP) : (last < Price ? ORDER_TYPE_SELL_LIMIT : ORDER_TYPE_SELL_STOP));
        TradeRequest.price              = NormalizeDouble(Price, Terminal.GetDigits());
        TradeRequest.sl                 = NormalizeDouble((m_bContainsPosition ? 0 : Stop), Terminal.GetDigits());
        TradeRequest.tp                 = NormalizeDouble((m_bContainsPosition ? 0 : Take), Terminal.GetDigits());
        TradeRequest.type_time          = (DayTrade ? ORDER_TIME_DAY : ORDER_TIME_GTC);
        TradeRequest.stoplimit          = 0;
        TradeRequest.expiration         = 0;
        TradeRequest.type_filling       = ORDER_FILLING_RETURN;
        TradeRequest.deviation          = 1000;
        TradeRequest.comment            = "Order Generated by Experts Advisor.";
        if (!Send()) return 0;
                                                                
        return TradeResult.order;
};


Vurgulanan kısımlar uygulanan değişikliklerdir.

Şimdi yeni bir değişiklik yapmak için güncelleme koduna geri dönelim. OnTrade fonksiyonu tarafından ve her emir değişikliğinde çağrıldığını unutmayın. Bu, aşağıdaki kodda görülebilir:

void UpdatePosition(void)
{
        static int memPositions = 0, memOrder = 0;
        ulong ul;
        int p, o;
                                
        p = PositionsTotal();
        o = OrdersTotal();
        if ((memPositions != p) || (memOrder != o))
        {
                ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, false);
                RemoveAllsLines();
                ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, true);
                memOrder = o;
                memPositions = p;
                m_bContainsPosition = false;
        };
        for(int i0 = p; i0 >= 0; i0--) if(PositionGetSymbol(i0) == Terminal.GetSymbol())
        {
                ul = PositionGetInteger(POSITION_TICKET);
                m_bContainsPosition = true;
                SetLineOrder(ul, PositionGetDouble(POSITION_PRICE_OPEN), HL_PRICE, false);
                SetLineOrder(ul, PositionGetDouble(POSITION_TP), HL_TAKE, true);
                SetLineOrder(ul, PositionGetDouble(POSITION_SL), HL_STOP, true);
        }
        for (int i0 = o; i0 >= 0; i0--) if ((ul = OrderGetTicket(i0)) > 0) if (OrderGetString(ORDER_SYMBOL) == Terminal.GetSymbol())
        {
                if (m_bContainsPosition)
                {
                        ModifyOrderPendent(ul, OrderGetDouble(ORDER_PRICE_OPEN), 0, 0);
                        (OrderSelect(ul) ? 0 : 0);
                }
                SetLineOrder(ul, OrderGetDouble(ORDER_PRICE_OPEN), HL_PRICE, true);
                SetLineOrder(ul, OrderGetDouble(ORDER_TP), HL_TAKE, true);
                SetLineOrder(ul, OrderGetDouble(ORDER_SL), HL_STOP, true);
        }
};

Şimdi, kullanıcının halihazırda bir açık pozisyon varken basit bir bekleyen emri bir bekleyen OCO emrine dönüştürmediğinden emin olmamız gerekir, yani kullanıcı araç kutusunu açıp kârı al veya zararı durdur seviyelerini düzenlemeye çalıştığında haberimiz olmalıdır. Kullanıcı bunu yapmaya çalıştığında, işlem sunucusu OnTrade fonksiyonu aracılığıyla bizi bilgilendirecektir, böylece Uzman Danışman değişikliği hemen öğrenecek ve kullanıcı tarafından yapılan bu değişikliği iptal ederek sistemin güvenilirliğini sağlayacaktır.

Ancak değiştirilmesi gereken bir şey daha vardır; o da piyasa emirleriyle ilgilidir. Kontrollerle ilgili herhangi bir düzenleme gerektirmediği için bu çok basit bir değişikliktir. Yeni fonksiyon kodu aşağıda gösterilmektedir:

ulong ExecuteOrderInMarket(const bool IsBuy, const double Volume, const double Price, const double Take, const double Stop, const bool DayTrade = true)
{
        ZeroMemory(TradeRequest);
        ZeroMemory(TradeResult);
        TradeRequest.action             = TRADE_ACTION_DEAL;
        TradeRequest.symbol             = Terminal.GetSymbol();
        TradeRequest.volume             = Volume;
        TradeRequest.type               = (IsBuy ? ORDER_TYPE_BUY : ORDER_TYPE_SELL);
        TradeRequest.price              = NormalizeDouble(Price, Terminal.GetDigits());
        TradeRequest.sl                 = NormalizeDouble((m_bContainsPosition ? 0 : Stop), Terminal.GetDigits());
        TradeRequest.tp                 = NormalizeDouble((m_bContainsPosition ? 0 : Take), Terminal.GetDigits());
        TradeRequest.type_time          = (DayTrade ? ORDER_TIME_DAY : ORDER_TIME_GTC);
        TradeRequest.stoplimit          = 0;
        TradeRequest.expiration         = 0;
        TradeRequest.type_filling       = ORDER_FILLING_RETURN;
        TradeRequest.deviation          = 1000;
        TradeRequest.comment            = "[ Order Market ] Generated by Experts Advisor.";
        if (!Send()) return 0;
                                                
        return TradeResult.order;
};


Garip görünse de, bu değişiklikler, Uzman Danışmanın işlem gerçekleştirdiği varlıkta halihazırda bir açık pozisyon bulunduğunda, aynı varlık için bir OCO, bekleyen veya piyasa emrini kaçırmamaya olanak sağlayan yeterli düzeyde (en azından kabul edilebilir düzeyde) bir güvenlik zaten sağlamaktadır. Böylece, Uzman Danışman aslında emir gönderme sistemiyle ilgilenecektir.

Her şey gerçek olamayacak kadar güzel ve harika, değil mi? Bunun size zaten iyi bir güvenlik marjı sağlayacağını düşünebilirsiniz, ancak durum pek de öyle değildir. Bu değişiklikler, bir açık pozisyonumuz olduğunda OCO emrinin beklemede kalmamasını veya piyasaya girmemesini sağlar. Ancak bu değişikliklerde ciddi bir kusur vardır ve uygun şekilde düzeltilmezse, bu kusur size büyük bir baş ağrısı ve muazzam bir kayıp yaşatabilir: işlem hesabınızın tamamen boşalmasına veya teminat eksikliği nedeniyle pozisyonunuzun broker tarafından kapatılmasına neden olabilir.

Bekleyen emrin açık pozisyonun eşikleri içerisinde olup olmadığının kontrol edilmediğini unutmayın ve bu çok tehlikelidir çünkü sistemin mevcut durumunda, açık pozisyonun eşiklerinin dışarısına bir bekleyen OCO emri eklediğinizde, Uzman Danışman bu emrin OCO türünde olmasına izin vermeyecektir. Başka bir deyişle: emir eşiksiz olacaktır, yani kârı al veya zararı durdur seviyelerine sahip olmayan bir emir olacaktır, dolayısıyla bir pozisyonu kapatıp bu bekleyen emri girdiğinizde, bu seviyeleri olabildiğince çabuk ayarlamanız gerekecektir. Bunu yapmayı unutursanız, eşiksiz bir açık pozisyona sahip olma riskiyle karşı karşıya kalırsınız.

Eşikleri ayarlamak için mesaj penceresine gitmeniz, emri açmanız ve seviyeleri düzenlemeniz gerekecektir. Bu yakında düzeltilecektir. Şimdi önce mevcut sorunu çözelim.

Uzman Danışmanın bekleyen emirlerle çalışma şeklini değiştirmemiz gerekmektedir, çünkü kullanıcı eşikler olmadan bir emir oluşturmak isterse, Uzman Danışman bunu normal bir şey olarak ele alacaktır, ancak eşikli bir emir oluşturmak isterse, Uzman Danışman emri uygun şekilde ayarlamak zorunda kalacaktır: emir açık pozisyonun dışarısına yerleştirilirse eşikleri ayarlayarak veya emir açık pozisyonun içerisine yerleştirilirse bekleyen emrin eşiklerini kaldırarak.


2.0.2. Eşiklerin içerisinde çalışma

Yapacağımız ilk şey doğrulama eşikleri oluşturmaktır. Bunu yapmak çok basittir. Ancak, ayrıntılara çok dikkat edilmesi gerekir,, çünkü daha fazla duruma genişletilebilecek iki olası durum vardır. Ne yapılması gerektiğini anlamak için bu iki durum yeterlidir.


İlk durum yukarıda gösterilmektedir. Eşiklerin dışarısında bir bekleyen emrimiz (bu durumda eşik alanı, gradyandaki alandır), bir pozisyonumuz (alış veya satış) ve bir üst eşiğimiz vardır. Fiyat bu eşiğe ulaştığında veya bu eşiği aştığında, pozisyon kapatılacaktır. Bu durumda, bekleyen emir kullanıcı tarafından bir OCO emri olarak yapılandırılabilir ve Uzman Danışman, ister bir basit emir ister bir OCO emri olsun, emrin kullanıcı tarafından yapılandırılma şeklini kabul etmelidir - Uzman Danışman bu durumda müdahale etmemelidir.

İkinci durum aşağıda gösterilmektedir. Burada bekleyen emir, açık pozisyonun eşik alanındadır. Bu durumda Uzman Danışman, kullanıcı tarafından yapılandırılabilecek eşikleri kaldırmalıdır.


Eşik ne kadar ileri giderse gitsin, ister alış ister satış durumunda, bekleyen emir bu alana girdiğinde Uzman Danışman bekleyen emirden eşik değerlerini kaldırmalıdır. Ancak bu alandan ayrılırsa Uzman Danışman, emri kullanıcı tarafından yapılandırıldığı şekilde bırakmalıdır.

Bunu tanımladıktan sonra, aşağıda gösterilen bazı değişkenleri oluşturmamız gerekmektedir:

class C_Router : public C_HLineTrade
{
        protected:
                MqlTradeRequest TradeRequest;
                MqlTradeResult  TradeResult;
        private  :
                bool            m_bContainsPosition;
                struct st00
                {
                        double  TakeProfit,
                                StopLoss;
                        bool    IsBuy;
                }m_Limits;

// ... Rest of the code

Artık OnTrade emir tetikleme olayının gerçekleştiği aşamada eşikleri kontrol etmenin bir yolu vardır. Bu yüzden, bir kez daha C_Router sınıfının güncelleme fonksiyonunu değiştiriyoruz.

// Rest of the code....

//+------------------------------------------------------------------+
#define macro_MAX(A, B) (A > B ? A : B)
#define macro_MIN(A, B) (A < B ? A : B)
void UpdatePosition(void)
{
        static int      memPositions = 0, memOrder = 0;
        ulong           ul;
        int             p, o;
        double          price;
        bool            bTest;
                                
        p = PositionsTotal();
        o = OrdersTotal();
        if ((memPositions != p) || (memOrder != o))
        {
                ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, false);
                RemoveAllsLines();
                ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, true);
                memOrder = o;
                memPositions = p;
                m_bContainsPosition = false;
                m_Limits.StopLoss = -1;
                m_Limits.TakeProfit = -1;
                m_Limits.IsBuy = false;
        };
        for(int i0 = p; i0 >= 0; i0--) if(PositionGetSymbol(i0) == Terminal.GetSymbol())
        {
                ul = PositionGetInteger(POSITION_TICKET);
                m_bContainsPosition = true;
                SetLineOrder(ul, PositionGetDouble(POSITION_PRICE_OPEN), HL_PRICE, false);
                SetLineOrder(ul, m_Limits.TakeProfit = PositionGetDouble(POSITION_TP), HL_TAKE, true);
                SetLineOrder(ul, m_Limits.StopLoss = PositionGetDouble(POSITION_SL), HL_STOP, true);
                m_Limits.IsBuy = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY;
        }
        for (int i0 = o; i0 >= 0; i0--) if ((ul = OrderGetTicket(i0)) > 0) if (OrderGetString(ORDER_SYMBOL) == Terminal.GetSymbol())
        {
                price = OrderGetDouble(ORDER_PRICE_OPEN);
                if ((m_Limits.StopLoss == -1) && (m_Limits.TakeProfit == -1)) bTest = false; else
                {
                        bTest = ((!m_Limits.IsBuy) && (m_Limits.StopLoss > price));
                        bTest = (bTest ? bTest : (m_Limits.IsBuy) && (m_Limits.StopLoss < price));
                        bTest = (bTest ? bTest : ((macro_MAX(m_Limits.TakeProfit, m_Limits.StopLoss) > price) && (macro_MIN(m_Limits.TakeProfit, m_Limits.StopLoss) < price)));
                }
                if ((m_bContainsPosition) && (bTest))
                {
                        ModifyOrderPendent(ul, price, 0, 0);
                        (OrderSelect(ul) ? 0 : 0);
                }
                SetLineOrder(ul, price, HL_PRICE, true);
                SetLineOrder(ul, OrderGetDouble(ORDER_TP), HL_TAKE, true);
                SetLineOrder(ul, OrderGetDouble(ORDER_SL), HL_STOP, true);
        }
};
#undef macro_MAX
#undef macro_MIN
//+------------------------------------------------------------------+

// ... The rest of the code...

Artık sınıf, bekleyen pozisyonları, OCO türünde bekleyen emirlerin bulunmadığı bir alan içerisinde olup olmadıklarını ayırt etmek için işleyecektir. Bu fonksiyonun emir sistemindeki her durum değişikliğinde çağrılacağını unutmayın. Yapacağı ilk şey, değişkenleri uygun şekilde başlatmaktır.

m_Limits.StopLoss = -1;
m_Limits.TakeProfit = -1;
m_Limits.IsBuy = false;


Bu yapıldıktan sonra, bir açık pozisyon olup olmadığını kontrol edeceğiz. Bu herhangi bir zamanda yapılabilir. Bir açık pozisyonumuz olur olmaz, OCO türünde bekleyen emirlerin bulunmasının mümkün olmayacağı alanı sınırlandıracaktır.

SetLineOrder(ul, m_Limits.TakeProfit = PositionGetDouble(POSITION_TP), HL_TAKE, true);
SetLineOrder(ul, m_Limits.StopLoss = PositionGetDouble(POSITION_SL), HL_STOP, true);
m_Limits.IsBuy = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY;


Şimdi, eşik alanı içerisinde olup olmadıklarını öğrenmek için bekleyen emirlerin her birini kontrol edebiliriz. Önemli bir not: burada emrin alış mı yoksa satış mı olduğunu bilmemiz gerekir, çünkü kârı ala sahip olmayabiliriz ancak zararı durdura sahip olabiliriz. Dolayısıyla, bu durumda pozisyonun türünü bilmek gerekir. Bunu daha iyi anlamak için aşağıdaki görüntülere bakalım:

 

Eğer bu bir satış pozisyonuysa, zararı durdur üst eşiktir.

 

Alış pozisyonları için de zararı durdur alt eşiktir.

Diğer bir deyişle, bazı durumlarda, bekleyen emirler belirlenen maksimumun üzerinde yerleştirildiğinde OCO türünde olabilir. Diğer durumlarda, belirlenen minimumun altında yerleştirilmelidirler. Ancak, aşağıda gösterildiği gibi, bekleyen emirlerin OCO türünde olabileceği başka bir durum da olabilir:

 

Tipik bir durum olan, eşikler dışarısında bekleyen emirler.

Bunu kontrol etmek için aşağıdaki kod parçasını kullanırız.

price = OrderGetDouble(ORDER_PRICE_OPEN);
if ((m_Limits.StopLoss == -1) && (m_Limits.TakeProfit == -1)) bTest = false; else
{
        bTest = ((!m_Limits.IsBuy) && (m_Limits.StopLoss > price));
        bTest = (bTest ? bTest : (m_Limits.IsBuy) && (m_Limits.StopLoss < price));
        bTest = (bTest ? bTest : ((macro_MAX(m_Limits.TakeProfit, m_Limits.StopLoss) > price) && (macro_MIN(m_Limits.TakeProfit, m_Limits.StopLoss) < price)));
}

Herhangi bir açık pozisyon olup olmadığını kontrol edecektir. Bir açık pozisyon yoksa, Uzman Danışman, kullanıcı tarafından belirtilen emir ayarlarına uymak zorundadır. Bir açık pozisyon bulunması durumunda da aşağıdaki kontroller ilgili sırayla gerçekleştirilecektir:

  1. Eğer satış pozisyonuysa, bekleyen emrin yerleştirileceği fiyat, açık pozisyonun zararı durdur değerinden daha yüksekte olmalıdır;
  2. Eğer alış pozisyonuysa, bekleyen emrin yerleştirileceği fiyat, açık pozisyonun zararı durdur değerinden daha düşükte olmalıdır;
  3. Eğer sistem emri hala OCO türünde olarak kabul ediyorsa, emrin pozisyon eşiklerinin dışarısında olup olmadığını belirlemek adına son bir kontrol yaparız.

Sonrasında, bekleyen emrin kullanıcının yapılandırdığı şekilde bırakılıp bırakılamayacağından emin olacağız ve böylece hayat devam edecek... Ancak bir sonraki adıma geçmeden önce son bir ekleme daha yapmamız gerekiyor. Aslında bu, makalenin başında bahsettiğim ve aşağıdaki kod parçasında yer alan son kontroldür:

void UpdatePosition(void)
{

// ... Internal code...

        for(int i0 = p; i0 >= 0; i0--) if(PositionGetSymbol(i0) == Terminal.GetSymbol())
        {
                ul = PositionGetInteger(POSITION_TICKET);
                m_bContainsPosition = true;
                SetLineOrder(ul, PositionGetDouble(POSITION_PRICE_OPEN), HL_PRICE, false);
                SetLineOrder(ul, m_Limits.TakeProfit = PositionGetDouble(POSITION_TP), HL_TAKE, true);
                SetLineOrder(ul, m_Limits.StopLoss = PositionGetDouble(POSITION_SL), HL_STOP, true);
                m_Limits.IsBuy = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY;
        }
        if (AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
                m_bContainsPosition = false;
        for (int i0 = o; i0 >= 0; i0--) if ((ul = OrderGetTicket(i0)) > 0) if (OrderGetString(ORDER_SYMBOL) == Terminal.GetSymbol())
        {
                price = OrderGetDouble(ORDER_PRICE_OPEN);
                if (m_bContainsPosition)
                {
                        if ((m_Limits.StopLoss == -1) && (m_Limits.TakeProfit == -1)) bTest = false; else
                        {
                                bTest = ((!m_Limits.IsBuy) && (m_Limits.StopLoss > price));
                                bTest = (bTest ? bTest : (m_Limits.IsBuy) && (m_Limits.StopLoss < price));
                                bTest = (bTest ? bTest : ((macro_MAX(m_Limits.TakeProfit, m_Limits.StopLoss) > price) && (macro_MIN(m_Limits.TakeProfit, m_Limits.StopLoss) < price)));
                        }
                        if (bTest)
                        {
                                ModifyOrderPendent(ul, price, 0, 0);
                                (OrderSelect(ul) ? 0 : 0);
                        }
                }
                SetLineOrder(ul, price, HL_PRICE, true);
                SetLineOrder(ul, OrderGetDouble(ORDER_TP), HL_TAKE, true);
                SetLineOrder(ul, OrderGetDouble(ORDER_SL), HL_STOP, true);
        }
};


Vurgulanan kısımda, hesap türünün hedging olup olmadığını kontrol ediyoruz. Eğer öyleyse, değişken eşiklerle çalışmamız gerektiğini belirtse bile, bu noktada onlarla çalışmamız gerekmediğini ifade edecektir. Böylece Uzman Danışman, ortaya çıkabilecek kısıtlamaları göz ardı edecek ve emirleri kullanıcı tarafından yapılandırıldıkları şekilde ele alacaktır. Bu çok basit bir kontroldür, ancak tüm sistemimizin düzgün çalışmasını sağlamak için bu aşamada yapılması gerekir.


2.1.0. Konumlandırma sisteminin ayarlanması

Sorunların çoğu C_Router nesne sınıfının ayarlanmasıyla çözülmüş olsa da, hala yeterli bir sisteme sahip değiliz. Çözülmesi gereken bir başka sorun daha vardır: fare konumlandırma sisteminin düzeltilmesi, ki bu da aynı derecede önemli bir adımdır. C_OrderView sınıfında bulunan sistemin nasıl çalışması gerektiğini tanımlamamız gerektiğinden, bunun birkaç anlamı vardır.

Asıl soru (gerçekte nasıl ticaret yapmak istediğinize bağlıdır), C_OrderView sınıfının, açık pozisyonun eşiklerini terk ettiklerinde bekleyen emirler için eşikler oluşturup oluşturmayacağıdır.

Her seferinde bunu yapmak cazip gelse de, bu kararı verirken dikkate alınması gereken şeyler vardır. Şimdi parça parça ilerleyelim. Temel olarak, C_OrderView sınıfında yapmamız gereken tek gerçek değişiklik aşağıdaki kodda gösterilmektedir:


inline void MoveTo(uint Key)
{
        static double local = 0;
        datetime dt;
        bool    bEClick, bKeyBuy, bKeySell, bCheck;
        double  take = 0, stop = 0, price;
                                
        bEClick  = (Key & 0x01) == 0x01;    //Left click
        bKeyBuy  = (Key & 0x04) == 0x04;    //SHIFT pressed
        bKeySell = (Key & 0x08) == 0x08;    //CTRL pressed                          
        Mouse.GetPositionDP(dt, price);
        if (bKeyBuy != bKeySell)
        {
                Mouse.Hide();
                bCheck = CheckLimits(price);
        } else Mouse.Show();
        ObjectMove(Terminal.Get_ID(), m_Infos.szHLinePrice, 0, 0, price = (bKeyBuy != bKeySell ? price : 0));
        ObjectMove(Terminal.Get_ID(), m_Infos.szHLineTake, 0, 0, take = (bCheck ? 0 : price + (m_Infos.TakeProfit * (bKeyBuy ? 1 : -1))));
        ObjectMove(Terminal.Get_ID(), m_Infos.szHLineStop, 0, 0, stop = (bCheck ? 0 : price + (m_Infos.StopLoss * (bKeyBuy ? -1 : 1))));
        if((bEClick) && (bKeyBuy != bKeySell) && (local == 0)) CreateOrderPendent(bKeyBuy, m_Infos.Volume, local = price, take, stop, m_Infos.IsDayTrade);
        local = (local != price ? 0 : local);                           
        ObjectSetInteger(Terminal.Get_ID(), m_Infos.szHLinePrice, OBJPROP_COLOR, (bKeyBuy != bKeySell ? m_Infos.cPrice : clrNONE));
        ObjectSetInteger(Terminal.Get_ID(), m_Infos.szHLineTake, OBJPROP_COLOR, (take > 0 ? m_Infos.cTake : clrNONE));
        ObjectSetInteger(Terminal.Get_ID(), m_Infos.szHLineStop, OBJPROP_COLOR, (stop > 0 ? m_Infos.cStop : clrNONE));
};

Hepsi bu kadar mı? Evet, tüm yapmamız gereken bu. Mantığın geri kalanı C_Router sınıfındadır. Değiştirilmeyenler MetaTrader 5'in kendi mesajlaşma sistemi tarafından yürütülür, çünkü emir listesinde (bekleyen veya pozisyonlar) bir değişiklik olduğunda, OnTrade fonksiyonu çağrılacaktır. Bu olduğunda, gerekli ayarlamaları yapacak olan C_Router sınıfındaki güncelleme rutinini tetikleyecektir. Ancak bu fonksiyonda ortaya çıkan ve nerede olduğunu ararken çıldırmanıza neden olabilecek bir kod vardır. Aslında, C_Router sınıfındadır, aşağıda görülmektedir:

#define macro_MAX(A, B) (A > B ? A : B)
#define macro_MIN(A, B) (A < B ? A : B)
inline bool CheckLimits(const double price)
{
        bool bTest = false;
                                
        if ((!m_bContainsPosition) || ((m_Limits.StopLoss == -1) && (m_Limits.TakeProfit == -1))) return bTest;
        bTest = ((macro_MAX(m_Limits.TakeProfit, m_Limits.StopLoss) > price) && (macro_MIN(m_Limits.TakeProfit, m_Limits.StopLoss) < price));
        if (m_Limits.TakeProfit == 0)
        {
                bTest = (bTest ? bTest : (!m_Limits.IsBuy) && (m_Limits.StopLoss > price));
                bTest = (bTest ? bTest : (m_Limits.IsBuy) && (m_Limits.StopLoss < price));
        }
        return bTest;
};
#undef macro_MAX
#undef macro_MIN


Bu kod, C_Router sınıfının güncelleme fonksiyonundaydı. Oradan kaldırıldı ve yerine bir çağrı eklendi.


2.2.0. Eşikli ya da eşiksiz, işte bütün mesele bu

Çalışmamız neredeyse tamamlandı, ancak çözülmesi gereken son bir soru kaldı ki bu belki de şu anda en zor olanıdır. Bu noktaya kadar içeriği takip ettiyseniz ve anladıysanız, sistemin çok iyi çalıştığını fark etmişsinizdir, ancak OCO olarak yapılandırılmış bir bekleyen emir, bir açık pozisyonun eşiklerine girdiğinde, emir kendisi için yapılandırılmış eşikleri kaybetmektedir. Bu her zaman böyle olacaktır.

Ancak, yatırımcı şans eseri açık pozisyonun eşiklerini değiştirirse veya önceden OCO olan ve artık basit bir emir olan bir emir bu eşiklerin ötesine geçerse, yine de bir basit emir olacaktır. Yani potansiyel bir sorunumuz vardır.

Bir başka büyük ayrıntı: Uzman Danışman nasıl davranmalıdır? Yatırımcıya varlıkta az önce bir basit emrin ortaya çıktığını bildirmeli mi? Yoksa sadece emir için eşikler belirleyip onu OCO'ya mı dönüştürmeli?

Uzman Danışmanın ticarette size gerçekten yardımcı olmasını istiyorsanız bu konu son derece önemlidir. Uzman Danışmanın bizi neler olduğu konusunda bilgilendiren bir uyarı yayınlaması iyi olacaktır. Ancak, volatilitenin yüksek olduğu bir dönemde bir varlıktaysanız, Uzman Danışmanın emir için otomatik olarak belirli bir eşik oluşturması da iyidir, böylece daha neler olup bittiğini anlamadan büyük zarar oluşturabilecek bir durumdan kaçınmış oluruz.

Bu nedenle, bu sorunu çözmek için sistem son bir değişiklikten geçti, ancak yukarıda açıkladığım gibi, bu sorunla gerçekten nasıl başa çıkacağınızı ciddi olarak düşünmelisiniz. Aşağıda olası bir çözümü nasıl uyguladığımı görelim.

İlk olarak, yatırımcının Uzman Danışmana hangi prosedürün gerçekleştirileceğini bildirebileceği yeni bir değişken ekledim. Aşağıda gösterilmektedir:

// ... Code ...

input group "Chart Trader"
input int       user20   = 1;              //Leverage factor
input int       user21   = 100;            //Take Profit (financial)
input int       user22   = 75;             //Stop Loss (financial)
input color     user23   = clrBlue;        //Price line color
input color     user24   = clrForestGreen; //Take Profit line color
input color     user25   = clrFireBrick;   //Stop Loss line color
input bool      user26   = true;           //Day Trade?
input bool      user27   = true;           //Always set loose order limits

// ... Rest of the code...

void OnTrade()
{
        Chart.DispatchMessage(CHARTEVENT_CHART_CHANGE, 0, OrderView.UpdateRoof(), C_Chart_IDE::szMsgIDE[C_Chart_IDE::eROOF_DIARY]);
        OrderView.UpdatePosition(user27);
}

// ... Rest of the code...

Şimdi C_Router sınıfına geri dönmemiz ve ona 3 yeni fonksiyon eklememiz gerekiyor. Aşağıdan görülebilirler:

//+------------------------------------------------------------------+
void SetFinance(const int Contracts, const int Take, const int Stop)
{
        m_Limits.Contract = Contracts;
        m_Limits.FinanceTake = Take;
        m_Limits.FinanceStop = Stop;
}
//+------------------------------------------------------------------+
inline double GetDisplacementTake(const bool IsBuy, const double Vol) const
{
        return (Terminal.AdjustPrice(m_Limits.FinanceTake * (Vol / m_Limits.Contract) * Terminal.GetAdjustToTrade() / Vol) * (IsBuy ? 1 : -1));
}
//+------------------------------------------------------------------+
inline double GetDisplacementStop(const bool IsBuy, const double Vol) const
{
        return (Terminal.AdjustPrice(m_Limits.FinanceStop * (Vol / m_Limits.Contract) * Terminal.GetAdjustToTrade() / Vol) * (IsBuy ? -1 : 1));
}
//+------------------------------------------------------------------+

Kod, bir sonraki görüntüden görülebileceği gibi, ticaret arayüzünde bildirilen değerleri koruyacak, ancak aynı zamanda OCO türünde bekleyen emirlerde eşik olarak kullanmamız gereken değeri de orantılı olarak düzeltecektir.

Diğer bir deyişle, bekleyen emir tetiklendiğinde Uzman Danışmanın OCO emrini minimum düzeyde yapılandırabilmesi için kullanacağımız değerleri nereden alacağımıza zaten sahibiz. Fakat, tahmin edebileceğiniz gibi, C_Router sınıfının güncelleme kodunda yeni bir değişiklik yapmamız gerekecektir. Değişiklik aşağıda gösterilmektedir:

void UpdatePosition(bool bAdjust)
{
        static int      memPositions = 0, memOrder = 0;
        ulong           ul;
        int             p, o;
        long            info;
        double          price, stop, take, vol;
        bool            bIsBuy, bTest;
                        
        p = PositionsTotal();
        o = OrdersTotal();
        if ((memPositions != p) || (memOrder != o))
        {
                ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, false);
                RemoveAllsLines();
                ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, true);
                memOrder = o;
                memPositions = p;
                m_bContainsPosition = false;
                m_Limits.StopLoss = -1;
                m_Limits.TakeProfit = -1;
                m_Limits.IsBuy = false;
        };
        for(int i0 = p; i0 >= 0; i0--) if(PositionGetSymbol(i0) == Terminal.GetSymbol())
        {
                ul = PositionGetInteger(POSITION_TICKET);
                m_bContainsPosition = true;
                SetLineOrder(ul, PositionGetDouble(POSITION_PRICE_OPEN), HL_PRICE, false);
                SetLineOrder(ul, take = PositionGetDouble(POSITION_TP), HL_TAKE, true);
                SetLineOrder(ul, stop = PositionGetDouble(POSITION_SL), HL_STOP, true);
                m_Limits.IsBuy = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY;
                m_Limits.TakeProfit = (m_Limits.TakeProfit < 0 ? take : (m_Limits.IsBuy ? (m_Limits.TakeProfit > take ? m_Limits.TakeProfit : take) : (take > m_Limits.TakeProfit ? m_Limits.TakeProfit : take)));
                m_Limits.StopLoss = (m_Limits.StopLoss < 0 ? stop : (m_Limits.IsBuy ? (m_Limits.StopLoss < stop ? m_Limits.StopLoss : stop) : (stop < m_Limits.StopLoss ? m_Limits.StopLoss : stop)));
        }
        if ((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
                m_bContainsPosition = false;
        for (int i0 = o; i0 >= 0; i0--) if ((ul = OrderGetTicket(i0)) > 0) if (OrderGetString(ORDER_SYMBOL) == Terminal.GetSymbol())
        {
                price = OrderGetDouble(ORDER_PRICE_OPEN);
                take = OrderGetDouble(ORDER_TP);
                stop = OrderGetDouble(ORDER_SL);
		bTest = CheckLimits(price);
                if ((take == 0) && (stop == 0) && (bAdjust) && (!bTest))
                {
                        info = OrderGetInteger(ORDER_TYPE);
                        vol = OrderGetDouble(ORDER_VOLUME_CURRENT);
                        bIsBuy = ((info == ORDER_TYPE_BUY_LIMIT) || (info == ORDER_TYPE_BUY_STOP) || (info == ORDER_TYPE_BUY_STOP_LIMIT) || (info == ORDER_TYPE_BUY));
                        take = price + GetDisplacementTake(bIsBuy, vol);
                        stop = price + GetDisplacementStop(bIsBuy, vol);
                        ModifyOrderPendent(ul, price, take, stop);
                }
                if ((take != 0) && (stop != 0) && (bTest))
                        ModifyOrderPendent(ul, price, take = 0, stop = 0);
                SetLineOrder(ul, price, HL_PRICE, true);
                SetLineOrder(ul, take, HL_TAKE, true);
                SetLineOrder(ul, stop, HL_STOP, true);
        }
};

Vurgulanan satırlar, emrin eşiksiz olup olmadığını ve Uzman Danışmanın ona müdahale etmesi gerekip gerekmediğini kontrol edecektir. Uzman Danışman müdahale ederse, hesaplama ticaret arayüzünde sunulan finansal değere ve bekleyen emir hacmine göre yapılacaktır. Basit bekleyen emir daha sonra toplanan bilgilere göre hesaplanan eşiklere sahip olacaktır. Uzman Danışman, eşiklerin oluşturulacağını bildiren satırlar oluşturacak ve böylece basit bekleyen emri OCO türünde bekleyen emre dönüştürecektir.


Sonuç

Sistemin işlem hesabının türünü hedging olarak tanıyıp tanımadığını test etmeye yönelik yaptığım tüm girişimlere rağmen, bu aşamada başarılı olamadım. MetaTrader 5 platformu, işlem hesabının hedging türünde olduğunu bildirmesine rağmen, Uzman Danışman, işlem hesabının her zaman netting modunda olduğunu bildirdi. Bu nedenle dikkatli olmalıyız. İstediğimiz gibi çalışmasına rağmen, hedging hesabında bile bekleyen emirler, sanki netting hesabındaymış gibi ayarlanmaktadır.

Video, yukarıda açıklanan her şeyi net bir şekilde göstermektedir. Gördüğünüz gibi, sistemin kullanımı oldukça ilginçtir.




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

Ekli dosyalar |
Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 19): Yeni emir sistemi (II) Sıfırdan bir ticaret Uzman Danışmanı geliştirme (Bölüm 19): Yeni emir sistemi (II)
Bu makalede, grafiksel bir emir sistemi geliştireceğiz. Ama sıfırdan başlamayacağız, ticaret yaptığımız varlığın grafiğine daha fazla nesne ve olay ekleyerek mevcut sistemi değiştireceğiz.
Popülasyon optimizasyon algoritmaları: Parçacık sürüsü optimizasyonu (Particle Swarm Optimization, PSO) Popülasyon optimizasyon algoritmaları: Parçacık sürüsü optimizasyonu (Particle Swarm Optimization, PSO)
Bu makalede, popüler parçacık sürüsü optimizasyonu (Particle Swarm Optimization, PSO) algoritmasını ele alacağız. Bir önceki makalede, optimizasyon algoritmalarının yakınsama, yakınsama oranı, kararlılık, ölçeklenebilirlik gibi önemli özelliklerini tartıştık, ayrıca bir test ortamı geliştirdik ve en basit RNG algoritmasını inceledik.
Force Index göstergesine dayalı bir ticaret sistemi nasıl geliştirilir? Force Index göstergesine dayalı bir ticaret sistemi nasıl geliştirilir?
En popüler teknik göstergelere dayalı ticaret sistemlerini nasıl tasarlayacağımızı öğrendiğimiz serimizin yeni makalesine hoş geldiniz. Bu makalede, yeni bir teknik göstergeyi, Force Index göstergesini kullanarak bir ticaret sisteminin nasıl oluşturulacağını öğreneceğiz.
Popülasyon optimizasyon algoritmaları Popülasyon optimizasyon algoritmaları
Bu makale, optimizasyon algoritması sınıflandırmasına giriş niteliğinde bir makaledir. Makalede, optimizasyon algoritmalarını karşılaştırmaya ve belki de yaygın olarak bilinen algoritmalar arasından en evrensel olanını belirlemeye hizmet edecek bir test ortamı (bir fonksiyon kümesi) oluşturmaya odaklanılmaktadır.