0 beğenilme 0 beğenilmeme
1,309 kez görüntülendi

Merhaba,

Önceki konuda iq'da (aynı formül için) prime sinyallerinden farklı yerlerde emir gelmesi sorunu Orçun Bey sayesinde halldedildi.

Şimdi daha genel bir şey danışmak istiyorum.

iq'da yaklaşık bir saatten fazla emirleri takip ettim, prime ile aynı yerlerde emirlerin geldiğini görünce bir de backtest yapayım dedim.

Backtest sonucunda, canlıda yaptığı işlemlerden tamamen alakasız şeyler geldi.

Bu fark neden olur? Farkın olmaması için ne yapabilirim?

Bu konu çok önemli, çünkü stratejiler canlıya alınınca tamamen farklı işlemler yaparsa backtest yapmamızın anlamı kalmaz...

Ekran görüntüsü : Soldaki backtest, sağdaki canlı işlem. Ekran görüntüsünde 19:32 den beri olan işlemler var.

https://hizliresim.com/EdnHd5

 

Kod:

using System;
using System.Collections.Generic;
using System.Linq;
using Matriks.Data.Symbol;
using System.Windows.Media;
using Matriks.Engines;
using Matriks.Indicators;
using Matriks.Symbols;
using Matriks.AlgoTrader;
using Matriks.Trader.Core;
using Matriks.Trader.Core.Fields;
using Matriks.Trader.Core.TraderModels;
using Matriks.Lean.Algotrader.AlgoBase;
using Matriks.Lean.Algotrader.Models;
using Matriks.Lean.Algotrader.Trading;

 

namespace Matriks.Lean.Algotrader
{
    public class btc_test : MatriksAlgo
    {
        [SymbolParameter("XBT_USD_BMEX")]
        public string Symbol;

        [Parameter(SymbolPeriod.Min)]
        public SymbolPeriod SymbolPeriod;

        [Parameter(10)]
        public decimal Lot;

        [Parameter(1)]
        public int Pm1;
        [Parameter(3)]
        public int Pm2;
        [Parameter(1)]
        public int Pm3;

 


        SMA m1, m2, m3, m4, m5;


        public override void OnInit()
        {

            m1 = SMAIndicator(Symbol, SymbolPeriod, OHLCType.Close, Pm1);
            m2 = SMAIndicator(Symbol, SymbolPeriod, OHLCType.Close, Pm2);
            m3 = SMAIndicator(Symbol, SymbolPeriod, OHLCType.High, Pm3);
            m4 = SMAIndicator(Symbol, SymbolPeriod, OHLCType.Low, Pm3);

 


            AddSymbol(Symbol, SymbolPeriod);
            WorkWithPermanentSignal(true); //Sadece kalıcı sinyallerde işlem yap
            SendOrderSequential(true);//Bir al bir sat kuralı


        }


        public override void OnDataUpdate(BarDataCurrentValues barDataCurrentValues)
        {

            var bardata = GetBarData();
            var close = bardata.Close[barDataCurrentValues.LastUpdate.BarDataIndex -1];

            if (Ref(m1, 0) >Ref(m2, 0) && close<Ref(m3, 0))
            {
                SendMarketOrder(Symbol, Lot, OrderSide.Buy, ChartIcon.Buy);
            }

            if (Ref(m1, 0) <Ref(m2, 0) && close>Ref(m4, 0))
            {
                SendMarketOrder(Symbol, Lot, OrderSide.Sell, ChartIcon.Sell);
            }

 

        }
    }
}

 

Ek bilgi: Stratejinin Prime kodu

(MOV(c,1,s)>MOV(c,3,s)) and (c<MOV(h,1,s))

(MOV(c,1,s)<MOV(c,3,s)) and (c>MOV(l,1,s))

Algoritmik Trading kategorisinde (240 puan) tarafından
tarafından düzenlendi | 1,309 kez görüntülendi

1 cevap

1 beğenilme 0 beğenilmeme
En İyi Cevap

Merhabalar,

Önceki sorunuzda biraz eksik bilgi paylaşmışım. Kapanış değerinin 1 bar öncekini alarak canlıda işinizi görebilirsiniz fakat backtestte işler biraz farklılaşıyor. Backtestte bar açılışı diye bir olay olmadığı için gelen değerler hep bar kapanaşında oluşan değerlerdir. Sizde close değerini 1 önceki bardan almak istediğinizde yanlış sonuçlar ortaya çıkıyor. Bu sorununu çözmek için close değerini biraz değiştirmek yeterli. Close değerini aşağıdaki gibi tanımlarsanız backtest ve canlıda sorun yaşamazsınız.

var close = Ref(bardata,OHLCType.Close,0);

Bir tavsiye olarak lütfen kullandığınız değerleri Debug tabinde yazdırıp grafik ile kıyaslayarak gidin en doğru sonuca bu şekilde varabilirsiniz. Debug tabina verileri yazdırmanız için OnDataUpdate fonksiyonunda aşağıdaki gibi değişiklik yaptım.

public override void OnDataUpdate(BarDataCurrentValues barDataCurrentValues)
{

	var bardata = GetBarData();
	var close = Ref(bardata, OHLCType.Close, 0);
	Debug("**************************");
	Debug("Close : " + close);
	Debug("m1.CurrentValue : " + Ref(m1, 0));
	Debug("m2.CurrentValue : " + Ref(m2, 0));
	Debug("m3.CurrentValue : " + Ref(m3, 0));
	Debug("m4.CurrentValue : " + Ref(m4, 0) + "\n");

    if (Ref(m1, 0) >Ref(m2, 0) && close<Ref(m3, 0))
    {
		SendMarketOrder(Symbol, Lot, OrderSide.Buy, ChartIcon.Buy);
		Debug("Alış emri gerçekleşti.");
	}

	if (Ref(m1, 0) <Ref(m2, 0) && close>Ref(m4, 0))
	{
		SendMarketOrder(Symbol, Lot, OrderSide.Sell, ChartIcon.Sell);
		Debug("Alış emri gerçekleşti.");
	}
}

İyi çalışmalar

(4,555 puan) tarafından
tarafından seçilmiş
0 0

Teşekkür ederim Orçun Bey, kodu güncelleyip hemen canlıda takip etmeye başladım, bir saat kadar sonra bir de backtest yaparım. Umarım gerçekleşen işlemlerle backtest aynı gelir.

Bu arada sormadan edemeyeceğim; Aşağıdaki prime formülünü iq da aynı yerlerde işlem yapacak ve backtesti de doğru gösterecek bir kodu siz nasıl yazarsınız, Belki de ben baştan birşeyleri yanlış yapıyorum.

(MOV(c,1,s)>MOV(c,3,s)) and (c<MOV(h,1,s))

(MOV(c,1,s)<MOV(c,3,s)) and (c>MOV(l,1,s))


 

0 0
Rica ederim. Kodunuzda bir yanlışlık yok. Bende aynı şekilde yazardım.
0 0
Benzer problem bendede mevcut. şu anda sabahtan bari 7 kere al 6 kere sat sat emri gerçekleşti ama backtestte 2 al 1 sat emre mevcut.
0 0
Merhaba, yukarıdaki uyarıları dikkate alarak stratejinizi oluşturduysanız sorun olmaması gerekir.

İsterseniz stratejinizi paylaşın inceleyelim.
0 0
strateji bilgileri olarak aşağıdakilerini girerek test ediyorumki alım satımlardada aynı kriterler mevcut.

Symbol CEMAS

SymbolPeriod Min15

SymbolPeriodShortPeriod Min

SymbolPeriodLongPeriod Min60

BuyOrderQuantity 10000

SellOrderQuantity 10000

EmaPeriodSlow 4

EmaPeriodLong 5

------------------------------------
0 0
Merhaba,

Stratejinizi inceledim. Stratejiniz kalıcı sinyallerle çalışmıyor. Backtestte kullandığınız indikatörlerin değerleri sadece bar kapanışında oluşan değerlerdir. Fakat stratejiyi canlıda çalıştırdığınızda bar açılışından kapanana kadar indikatör değerleri değişiklik gösterir ve her değer için strateji tetiklenir.

Backtest ile canlı çalıştırdığınız stratejinin uyumlu olması için kalıcı sinyalle yani bar kapanışında oluşan değerlerle çalışmanız gerekmektedir. Bunun için OnInıt() fonksiyonuna WorkWithPermanentSignal(true); satırını eklemeniz gerekmektedir.

Ayrıca yukarıdaki cevaplarda da belirttiğim gibi kalıcı sinyalde canlı strateji çalıştırırken indikatör değerlerini Ref(ema ,0); gibi çağırmanız gerekmektedir. Böyle çağırmazsanız kalıcı sinyalle canlıda çalıştırdığınız strateji yeni bar açıldığında tetikleneceği için indikatör değeri yeni açılan bara göre hesaplanacaktır. Bu da backtest ile uyumsuzluk yaratacaktır.

Yukarı da verdiğim cevapta bulunan kodu ve hazır stratejilerimizi iyice incelemenizi tavsiye ederim.

İyi çalışmalar
0 0
WorkWithPermanentSignal(true); bunu atlamışım.

şu şekilde daha önce denemiştim hata almıştım.

if (CrossAbove(Ref(emaLong ,0), Ref(emaShort ,0)))

Birde stratejiyi nasıl incelediniz buraya hepsi kopyalanmamış.
0 0
Stratejiyi düzenlerken silmişim pardon. İlk attığınızda stratejiniz görünüyordu.

if (CrossAbove(Ref(emaLong ,0), Ref(emaShort ,0)))

Bu şekilde kullanımda nasıl bir hata aldınız. Tekrar deneyin isterseniz.
0 0
estğ . ben kendimden birden şüphe ettim çünkü hepsini kopyalamıştım çünkü :)

aşağıdaki gibi bir hata geliyor.

https://hizliresim.com/DtFjPu
1 0

Doğru gözden kaçırmışım. Cross fonksiyonları en az bir indikatör veya bardata almak zorunda. Fakat Ref() kullanımında bize decimal değer döner. Bu nedenle hata oluyor. 

Aşağıdaki kod parçasını Cross fonksiyonlarının yerine kullanabilirsiniz.

			if (Ref(emaLong, 1) <= Ref(emaShort, 1) && Ref(emaLong, 0) > Ref(emaShort, 0))
			{

				SendMarketOrder(Symbol, BuyOrderQuantity, (OrderSide.Buy));
				Debug("Alış emri gönderildi.");
				Debug("Close = " + barData.BarData.Close);
				Debug("Ema = " + Ref(emaShort, 0));
			}

			if (Ref(emaLong, 1) >= Ref(emaShort, 1) && Ref(emaLong, 0) < Ref(emaShort, 0))
			{
				SendMarketOrder(Symbol, SellOrderQuantity, (OrderSide.Sell));
				Debug("Satış emri gönderildi.");
				Debug("Close = " + barData.BarData.Close);
				Debug("Ema = " + Ref(emaShort, 0));
			}

 

0 0
ilk ben buna benzer bir if yazmıştım ama CrossAbove fonk tam olarak nasıl çalıştığını bilmediğimden dolayı daha doğrudur diye onu kullanmıştım.

Yardımlarınız için çok teşekkürler.
0 0
Rica ederim. Aslında Cross fonksiyonlarıyla aynı işlevi görüyor benim yazdığım kod. Fakat Cross fonksiyonlarında o anda gelen indikatör değeri ne ise o işleme giriyor. Bu durumda backtest ile uyumsuzluğa neden oluyor. Yani iki kullanım da yanlış değil yerine göre kullanmak önemli.
Backtest - Canlı Arası Kayma
Hoş geldiniz, Matriks Destek Platformu sizlere sorularınızın hızlıca cevaplanması için bir ortam sağlar. Sorduğunuz ve cevapladığınız soruların ve yorumlarınızın aldığı oylar üzerinden puan kazanırsınız. Puan sistemine bağlı kampanyamızla ücretsiz kullanım avantajlarından faydalanabilirsiniz.



8,636 soru
8,590 cevap
4,821 yorum
19,799 kullanıcı