0 beğenilme 0 beğenilmeme
848 kez görüntülendi

Merhaba alttaki varsayılan Pmax Stratejinin sat koşulunu aşağıdaki gibi güncellemek istiyorum yardımlarınızı rica ederim.

Sat koşulu 
Varsayılanda olan : mov, pmax i aşağı keserse

Benim istediğim : "mov, pmax i aşağı keserse" veya " eğer mov > pmax ve bar close < pmax" --- Hangisi önce olursa..

Sonuç olarak strateji hala "al" pozisyonundayken son bar pmax in altında kapanış yaparsa "sat" istiyorum.
Gözlemlerime göre çok büyük olasılıkla pmax altında bar kapanışı olduğunda strateji 1 ve 2 bar sonra sat veriyor.
Dolayısıyla "zarar kes" 1 veya 2 bar geç kalıyor. Yada böyle bir durumda genellikle grafik yatay seyrediyor.
Poziyson yatay seyirde yüksek olasılıkla zarar ediyor.. Amaç bu durumlardan erken kaçmak..
Bu olasılıkta "sat" verdikten sonra pozisyon hala "al" olarak devam edebiliyor ve sonraki yükselişte kaçırılmış bir fırsat olarak önünümze gelebilir. Ancak bu olasılıkta incelediğim grafiklerde nadiren gördüm.
Risk/Ödül oranına göre benim istediğim şekilde sat koşulları eklenirse risk az ödül daha yüksek olacak düşüncesindeyim.
Kullanmak isteyen arkadaşlar olursa düşüncelerimi de aktarmak istedim. Farklı düşüncelerle de geliştirilebilir.

İyi çalışmalar.
 

 

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) 	//


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)) 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)
			{

			}
		}
	}
}





 

Algoritmik Trading kategorisinde (50 puan) tarafından | 848 kez görüntülendi

1 cevap

0 beğenilme 0 beğenilmeme

Merhaba, oncelikle belirtmek isterim sizin post ettiginiz PMAX'in eski versiyonu. Bu versiyonda pmax indikatoru de strateji icinde hesaplanmakta. Daha sonra pmax indikatorunu gomulu indikator olarak ekledigimiz icin, bu gomulu indikatoru kullanan strateji de hazir stratejiler arasinda eklemistik. Asagida yeni versiyonu sizin istediginiz halde editlenmis sekliyle, hazir stratejiler icinde ise editlenmemis hali ile bulabilirsiniz (Yeni versiyonun isleme girme noktasi sizin icin yeterli olabilir).

Ayrica stratejinin isleme girdigi noktalari begenmiyorsaniz backtest optimizasyonu ile ya da parametrelerle direkt kendiniz oynayarak istenilen noktaya getirilebilir, bunun icin kodu/stratejiyi degistirmemiz gerekmez.

***STRATEJILERI TEST/DENEME ORTAMINDA CALISTIRMADAN VE SIZIN ISTEDIGINIZ SEKILDE CALISTIGINA EMIN OLMADAN GERCEK ORTAMDA HIC BIR ZAMAN CALISTIRMAYINIZ***

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Matriks.Data.Symbol;
using Matriks.Engines;
using Matriks.Indicators;
using Matriks.Lean.Algotrader.AlgoBase;
using Matriks.Lean.Algotrader.Models;
using Matriks.Trader.Core;
using Matriks.Trader.Core.Fields;

//*******************************************************ACIKLAMA*******************************************************//
//Kıvanç Özbilgiç'in hazirladigi PMAX indikatorunun kullanildigi bir stratejidir. Alim/Satim sinyalleri Cross Fonksiyonu 
//kullanilarak elde edilir. Strateji LONG/SHORT pozisyon almaktadir. Kalici sinyal ve sirasiz emir ile calismaktadir.
//Ilk emir gonderildiginde isaretlenir, ve daha sonraki emirler ilk emrin 2 kati olarak gonderilir. Boylece pozisyon 1/0 
//seklinde degil, 1/-1 seklinde alinabilmektedir (LONG/NEUTRAL yerine LONG/SHORT). Ek olarak OnOrderUpdate fonksiyonu ile
//Algo icerisinde gercek zamanli pozisyon takibi de yapilmaktadir. AcigaSatisYapilsin kutusu isaretlenmedigi taktirde
//aciga satis yapilmayacaktir ve emirler sirali olarak gonderilecektir.

namespace Matriks.Lean.Algotrader
{
	public class pmax_hazir_mov : 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("XBT_USD_BMEX")]
		public string Symbol;
		[Parameter(SymbolPeriod.Min60)]
		public SymbolPeriod SymbolPeriod;
		[Parameter(100)]
		public decimal BuyOrderQuantity;
		[Parameter(100)]
		public decimal SellOrderQuantity;
		[Parameter(10)]
		public int ATRPeriod;
		[Parameter(10)]
		public int MovPeriod;
		[Parameter(3)]
		public decimal Coefficient;
		[Parameter(MovMethod.E)]
		public MovMethod MovMethod;
		[Parameter(true)]
		public bool AcigaSatisYapilsin;

		int FirstRun = 0;
		int realposition = 0;
		PMaxIndicator pmax;

		public override void OnInit()
		{
			pmax = PMaxIndicators(Symbol, SymbolPeriod, ATRPeriod, MovPeriod, (decimal) Coefficient, MovMethod);

			AddSymbol(Symbol, SymbolPeriod);

			// 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(true);

			//Eger backtestte 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(!AcigaSatisYapilsin);
		}


		/// <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)
		{
			if (!AcigaSatisYapilsin) FirstRun = 0;
			var close = barDataCurrentValues.LastUpdate.Close;
			var pmaxKline = Math.Round(pmax.KLine.CurrentValue, 6);
			var pmaxSTline = Math.Round(pmax.StLine.CurrentValue, 6);

			Debug("***********************************************");
			Debug("pmaxSTline = " + pmaxSTline);
			Debug("pmaxKline = " + pmaxKline);
			if (CrossAbove(pmax.KLine, pmax.StLine) || (pmaxKline<pmaxSTline && close>pmaxSTline)) //
			{
				if (FirstRun == 0)
				{
					SendMarketOrder(Symbol, BuyOrderQuantity, (OrderSide.Buy));
					Debug("Alış emri gonderildi.");
					FirstRun = 1;
				}
				else
				{
					SendMarketOrder(Symbol, BuyOrderQuantity * 2, (OrderSide.Buy));
					Debug("Alış emri gonderildi.");
				}
			}
			if (CrossBelow(pmax.KLine, pmax) || (pmaxKline>pmaxSTline && close<pmaxSTline)) //"mov, pmax i aşağı keserse" veya " eğer mov > pmax ve bar close < pmax"
			{
				if (FirstRun == 0)
				{
					SendMarketOrder(Symbol, SellOrderQuantity, (OrderSide.Sell));
					Debug("Satış emri gonderildi.");
					FirstRun = 1;
				}
				else
				{
					SendMarketOrder(Symbol, SellOrderQuantity * 2, (OrderSide.Sell));
					Debug("Satış emri gonderildi.");
				}
			}
		}

		public override void OnOrderUpdate(IOrder order)
		{
			//Gercek zamanli pozisyon takibi
			if (order.OrdStatus.Obj == OrdStatus.Filled && order.Side.Obj == Side.Buy)
			{
				var positionChange = order.OrderQty;
				realposition += (int) positionChange;
				Debug("[ONORDERUPDATE]: Pozisyon = " + realposition);
			}
			if (order.OrdStatus.Obj == OrdStatus.Filled && order.Side.Obj == Side.Sell)
			{
				var positionChange = order.OrderQty;
				realposition -= (int) positionChange;
				Debug("[ONORDERUPDATE]: Pozisyon = " + realposition);
			}
		}
	}
}

 

(8,035 puan) tarafından
1 0
Hazır stratejilerde pmax olduğunu gördüm teşekkürler.
Düzenlenmiş kodlar tam anlamıyla çalışıyor ellerinize sağlık.

Yalnız siz "alış" stratejisine de "bar close > pmax" olarak ekleme yapmışsınız. :) Ben orasını sildim şimdi tam olarak istediğim gibi çalışıyor sorun yok.. Buradaki amaç Pmax bar kesişiminde al-sat yapmak değildi. Sadece "sat" ekleyerek riski düşürmek, ayrıca pmax'i izleyen stop gibi bir amaçla kullanmak istedim. Yani stratejinin içinde 2 ayrı "stop" oluşturduk. :) Şöyle düşünebilirsiniz. Örneğin ViOP ta ilk stopta (bar close < pmax) "pozisyonu kapat" (aldığın kadar sat)  İkinci stop yani "mov < pmax" de "Short Pozisyonuna geç"  gibi.. Benimle paylaştığınınız kodları spot alım satımda, bu bahsettiğimi de kodları düzenlemeye çalışarak viop da kullanmayı düşünüyorum..

Çok teşekkürler.  iyi çalışmalar.
1 0
Rica ederiz. Evet siz notunuzda sadece satis icin yazdiniz ama alis icin olan tarafi bilincli olarak yazmadiginizdan emin olamayinca al ve sat icin de yazdim. Amacimiz IQ'da kod yazimi ile asina olmaniz. Iyi calismalar dilerim.
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,120 soru
8,077 cevap
4,594 yorum
14,890 kullanıcı