2 beğenilme 0 beğenilmeme
5,802 kez görüntülendi

Merhaba Kıvanç beyin paylaştığı Pmax indikatörünü ekledim, Yeni strateji oluşturdum Pmax Çağırdım.
 

PMax = new PMax();

RegisterUserIndicator(PMax, Symbol, SymbolPeriod, OHLCType.Close, 5);

Bu şekilde geldi optimize edilemez durumda bir şeyler denedim fakat sonuç alamadım . Optimize edilecek şekilde al sat yapabilecek formülü paylaşabilir misiniz. Teşekkür ederim.

Algoritmik Trading kategorisinde (888 puan) tarafından | 5,802 kez görüntülendi

1 cevap

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

Merhaba asagidaki kodu direkt strateji olarak eklerseniz, optimize edebilirsiniz. Indicator builder ile eklenen indikatorlerin strateji icerisinde optimize edilmesiyle ilgili gelistirmeler hala devam etmekte.

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;

//*******************************************************ACIKLAMA*******************************************************//
//Gecici sinyal ile kullaniniz. bufferlength strateji canli calistirildiginda averajlarin onceden hesaplanarak gelmesini//
//saglamaktadir. 200'un altina dusurmeyiniz. Hareketli ortalama PMAX in uzerinde kirdiginda alim, altina kirdiginda		//
//satim yapilmaktadir. Sirali emir gonderimi AKTIFTIR (Strateji ilk olarak alim emri bekleyecek ve sirayla gidecektir) 	//
//Ilk satis sinyali gelirse "Satış emri gönderildi" Debug ekraninda ciksa bile log ekranina baktiginizda Emir sinyali   //
//geldi fakat emirlerin sıralı gitmesi seçeneği aktif olduğundan emir gönderilmedi ifadesini goreceksiniz. 				//
//EMIR GONDERIMI SIRALI OLDUGU ICIN SIRASIZ GELEN EMIR BORSAYA ILETILMEMISTIR.											//


namespace Matriks.Lean.Algotrader
{
	public class PMAX_strat_buffer_release : MatriksAlgo
	{
		// Strateji çalıştırılırken kullanacağımız parametreler. Eğer sembolle ilgili bir parametre ise,
		// "SymbolParameter" ile, değilse "Parameter" ile tanımlama yaparız. Parantez içindeki değerler default değerleridir.

		[SymbolParameter("BTC_USDT_BIN")]
		public string Symbol;
		[Parameter(SymbolPeriod.Min)]
		public SymbolPeriod SymbolPeriod;
		[Parameter(5)]
		public decimal BuySellQuantity;

		[Parameter(14)]
		public int AtrPeriod;
		[Parameter(8)]
		public int MovPeriod;
		[Parameter(2)]
		public decimal Coeff;
		[Parameter(MovMethod.E)]
		public MovMethod MovMethod;
		
		public bool firstrun = true;
		int bufferlength = 200;
		WILDERS wilders;
		MOV mov;

		/// <summary>
		/// Strateji ilk çalıştırıldığında bu fonksiyon tetiklenir. Tüm sembole kayit işlemleri,
		/// indikator ekleme, haberlere kayıt olma işlemleri burada yapılır. 
		/// </summary>
		public override void OnInit()
		{
			AddSymbol(Symbol, SymbolPeriod);
			wilders = new WILDERS(AtrPeriod);
			mov = new MOV(MovPeriod, MovMethod);

			// Algoritmanın kalıcı veya geçici sinyal ile çalışıp çalışmayacağını belirleyen fonksiyondur.
			// true geçerseniz algoritma sadece yeni bar açılışlarında çalışır, bu fonksiyonu çağırmazsanız veya false geçerseniz her işlem olduğunda algoritma tetiklenir.
			WorkWithPermanentSignal(false);

			//Eger emri bir al bir sat seklinde gonderilmesi isteniyor bu true set edilir. 
			//Alttaki satırı silerek veya false geçerek emirlerin sirayla gönderilmesini engelleyebilirsiniz. 
			SendOrderSequential(true);
		}

		Dictionary<int, decimal> fubDict = new Dictionary<int, decimal>();
		Dictionary<int, decimal> flbDict = new Dictionary<int, decimal>();
		Dictionary<int, decimal> PMAX_Dict = new Dictionary<int, decimal>();

		/// <summary>
		/// Eklenen sembollerin bardata'ları ve indikatorler güncellendikçe bu fonksiyon tetiklenir. 
		/// </summary>
		/// <param name="barData">Bardata ve hesaplanan gerçekleşen işleme ait detaylar</param>
		public override void OnDataUpdate(BarDataCurrentValues barDataCurrentValues)
		{
			var currentBar = barDataCurrentValues.LastUpdate.BarDataIndex;
			if (currentBar < AtrPeriod)
			{
				fubDict[currentBar] = 0;
				flbDict[currentBar] = 0;
				PMAX_Dict[currentBar] = 0;
				return ;
			}

			if (firstrun)
			{
				int i = bufferlength;
				fubDict[currentBar - i -1] = 0;
				flbDict[currentBar - i -1] = 0;
				PMAX_Dict[currentBar - i -1] = 0;
				var _barData_ = GetBarData();
				if (currentBar - 1 < 0 || !_barData_.Close.ContainsKey(currentBar - 1) || currentBar<=bufferlength) return ;
				Debug("currentBar = " + currentBar + ", buffer LENGTH = " + bufferlength + " indikator buffer hesaplaniyor");
				for (; i >= 0; i--)
				{
					var _high_ = _barData_.High[currentBar - i];
					var _low_ = _barData_.Low[currentBar - i];
					var _diff_ = _high_ - _low_;
					var _range2_ = Math.Abs(_high_ - _barData_.Close[currentBar - 1 - i]);
					var _range3_ = Math.Abs(_low_ - _barData_.Close[currentBar - 1 - i]);
					var _value_ = Math.Max(_diff_, Math.Max(_range2_, _range3_));

					wilders.Update(_value_, currentBar - i, _barData_.Time[currentBar - i]);
					mov.Update((_high_ + _low_) / 2, (currentBar - i), _barData_.Time[currentBar - i]);
					//Debug($"mov Updated: with value: {(_high_ + _low_) / 2}, @{currentBar - i}, with TIME = {_barData_.Time[currentBar - i]}");
					var _k = mov.Value[0][currentBar - i];
					var _offset = Coeff * wilders.CurrentValue;
					var _str = _k + _offset;
					var _sts = _k - _offset;
					var _prev = PMAX_Dict[currentBar - i -1];
					var _fub = _str<_prev || mov.Value[0][currentBar -1 - i] >_prev? _str:_prev;
					var _flb = _sts>_prev || mov.Value[0][currentBar -1 - i] <_prev? _sts:_prev;
					fubDict[currentBar - i] = _fub;
					flbDict[currentBar - i] = _flb;
					var _pmax = _prev == fubDict[currentBar - i -1] && _k < _fub? _fub : (_prev == fubDict[currentBar - i -1] && _k>_fub? _flb:(_prev == flbDict[currentBar - i -1] && _k>_flb? _flb
								   :(_prev == flbDict[currentBar - i -1] && _k < _flb? _fub:_fub)));
					PMAX_Dict[currentBar - i] = _pmax;
					//Debug($"PMAX = {Math.Round(_pmax,4)}, mov = {Math.Round(mov.Value[0][currentBar-i],4)}, @{currentBar - i}");
				}
				firstrun = false;
			}
			else{
				var barData = GetBarData();
				if (currentBar - 1 < 0 || !barData.Close.ContainsKey(currentBar - 1)) return ;
				var high = barData.High[currentBar];
				var low = barData.Low[currentBar];
				var diff = high - low;
	
				var range2 = Math.Abs(high - barData.Close[currentBar - 1]);
				var range3 = Math.Abs(low - barData.Close[currentBar - 1]);
				var value = Math.Max(diff, Math.Max(range2, range3));
	
				wilders.Update(value, currentBar, barDataCurrentValues.LastUpdate.DTime);
				mov.Update((high + low) / 2, currentBar, barDataCurrentValues.LastUpdate.DTime);
				var k = mov.CurrentValue;
				var offset = Coeff * wilders.CurrentValue;
				var str = k + offset;
				var sts = k - offset;
				var prev = PMAX_Dict[currentBar -1];
				var fub = str<prev || mov.Value[0][currentBar -1] >prev? str:prev;
				var flb = sts>prev || mov.Value[0][currentBar -1] <prev? sts:prev;
				fubDict[currentBar] = fub;
				flbDict[currentBar] = flb;
				var pmax = prev == fubDict[currentBar -1] && k<fub? fub : (prev == fubDict[currentBar -1] && k>fub? flb:(prev == flbDict[currentBar -1] && k>flb? flb
												   :(prev == flbDict[currentBar -1] && k<flb? fub:fub)));
				PMAX_Dict[currentBar] = pmax;
				
				if (barDataCurrentValues.LastUpdate.IsNewBar == true)
				{
					Debug($"PMAX = {Math.Round(pmax,4)}, mov = {Math.Round(mov.Value[0][currentBar],4)}");
					if (mov.Value[0][currentBar -1] <PMAX_Dict[currentBar -1] && mov.Value[0][currentBar] > PMAX_Dict[currentBar])
					{
						SendMarketOrder(Symbol, BuySellQuantity, OrderSide.Buy);
						Debug("Alış emri gönderildi");
					}
		
					if (PMAX_Dict[currentBar -1] <mov.Value[0][currentBar -1] && PMAX_Dict[currentBar] >mov.Value[0][currentBar])
					{
						SendMarketOrder(Symbol, BuySellQuantity, OrderSide.Sell);
						Debug("Satış emri gönderildi");
					}
				}
			}
		}

		/// <summary>
		/// Gönderilen emirlerin son durumu değiştikçe bu fonksiyon tetiklenir.
		/// </summary>
		/// <param name="barData">Emrin son durumu</param>
		public override void OnOrderUpdate(IOrder order)
		{
			if (order.OrdStatus.Obj == OrdStatus.Filled)
			{

			}
		}
	}
}

 

(8,035 puan) tarafından
tarafından düzenlendi
0 0
Matriks IQ için paylaşlan pmax indicator ile bu strateji aynı noktalarda alım satım vermiyor. indikatorde k burada mov olarak geçen değer aynı,  fakat indikatorde "st" burada "pmax" olarak geçen değer arasında sürekli farklılık var. Ayrıca Tradingview ile de farklılık söz konusu
1 0

Cevabınız için teşekkürler Çağlar.

Stratejiyi BTC_USDT_BIN de 1 dakikalık periyodda gerçekte ne olduğunu görmek için şu ayarlarda test ettim. ( atr : 10 --- mov : 8 --- coeff : 1.6
Bu sırada grafik üzerine PMAX i aynı değer ile açtım izledim. Stratejinin AL ve SAT verdiği noktalar grafik üzerindeki al sat noktalarıyla aynı herşey birebir örtüşüyor. Tradingwievde örtüşmediği bazı noktalar olduğu benimde gözüme çarptı. Onun haricinde herhangi bir sorun ile karşılaşmadım. 

Ayrıca yukarıda paylaşılan stratejiden ziyade Kıvanç bey'in dün Youtube da paylaştığı stratejiyi kullanıyorum. 
ikisinin arasında sadece şurada bir fark var. 
 

Kıvanç Bey in paylaştığı 

var _barData_ = GetBarData();
				if (currentBar - 1 < 0 || !_barData_.Close.ContainsKey(currentBar - 1) || currentBar <= bufferlength) return ;



------------------------------


Yukarıda paylaşılan

var _barData_ = GetBarData();
				if (currentBar - 1 < 0 || !_barData_.Close.ContainsKey(currentBar - 1)) return ;


Cevap verdiğiniz konuyu da netleştirmiş oldum. ilk resimde görülen kırmızı ok ile gösterilen yerden yani kapanıştan emir gönderiyor yada ondan sonraki bar'ın açılışından diyebiliriz.
Bu durumda back test kapanış - kapanış olarak seçilip yapılmalıdır.

Bu strateji hakkında başka gözlemleriniz varsa paylaşırsanız sevinirim.
 

1 0
Merhabalar yanıtınız için teşekkürler. Açıkçası yazdığımı okuduğumda eksik ve alelacele bir yazı yazmış olduğumu gördüm. Açıkçası ben backtest'te neredeyse birebir sonuç görüyorum. Bunun yazı sıra tradingview'de yazılan kodalarla karşılaştırınca(pinescript biliyorum) kodların zaten doğru olduğunu düşünüyorum. Hatta python ile aynı kodu yazdım ve binance'de çalıştırdım. Tradingview ile ufak farklılıklar var. Iq içinde aynısı geçerli ancak bunlar çok önemli görünmüyor.

Burada ben bu stratejiyi  2 defa canlıda çalıştırdım. ilki için hatırlayamıyorum ama 2. çalıştırdığımda yaklaşık bir saat boyunca doğru olarak giden pmax değerinin al sonrası yanlış değer üretmesini gördüm. Aynı sorunu ilkinde de yaşadım. Şu an üçüncü defa çalıştırıyorum. Belki spesifik bir olaydır. Aynı sorunu yaşarsam ekran görüntüsü ile paylaşırım. Böylece daha ayrıntılı bakabiliriz. Dediğim gibi koda bakınca ben de hata göremiyorum. Ancak böyle bir durum oluştu. Bu da sürekli al sat sinyali üretmesine sebep oldu. Indicator'de  1 defa al olan zaman dilimde 9 defa alsat yaptı.  

Çalıştırdığım parametreler

10 dk

atrperiod : 14

movperiod: 8

coeff:4

movmethod : wilders
Pmax Stratejisi coeff ondalık sayı problemi
çift pmax lı strateji
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,735 soru
8,680 cevap
4,868 yorum
20,552 kullanıcı