1 beğenilme 0 beğenilmeme
972 kez görüntülendi
Merhabalar C# konusunda minimum bilgiye sahibim. Parabolic SAR, RSI ve MACD ile parametreleri ayarlayabileceğim şekilde bir strateji yazabilir misiniz?

Teşekkürler.
Algoritmik Trading kategorisinde (32 puan) tarafından | 972 kez görüntülendi

1 cevap

5 beğenilme 0 beğenilmeme
En İyi Cevap
Merhaba,
aşırı kompleks bir  strateji değilse yardımcı olmak isterim.
(402 puan) tarafından
tarafından seçilmiş
0 0

Mevcut ParabolicSAR stratejisine aşağıdaki şekilde eklemeye çalıştım.  Sanırım amacım az çok anlaşılıyordur. 

Teşekkürler

using System;
using System.Collections.Generic;
using System.Linq;
using Matriks.Data.Symbol;
using Matriks.Engines;
using System.Windows.Media;
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**********************************************************//
//Parabolic SAR indikatorunun al/sat durumuna gore islem yapar. Sadece uzun pozisyon acip kapatir (SendOrderSequential(true); //
//ile ayarlanmistir. 60dk'lik Parabolic SAR alt kanaldaysa alim yapar, ust kanaldaysa pozisyondan cikar. 					  //
//Parabolic SAR ve sembol icin periyotlar degistirilebilir.	


namespace Matriks.Lean.Algotrader
{
	public class Parabol : 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("GARAN")]
		public string Symbol;
		[Parameter(100)]
		public int Quantity;
		[Parameter(SymbolPeriod.Min)]
		public SymbolPeriod SymbolPeriod;

		[Parameter(0.02)]
		public decimal Acceleration_factor;
		[Parameter(0.2)]
		public decimal MaxAcc;

		[Parameter(SymbolPeriod.Min60)]
		public SymbolPeriod PSar_Period;
		ParabolicSAR parabolicSar;
		
		[Parameter(7)]
		public int MACDPeriod;

		[Parameter(18)]
		public int MACDPeriod2;

		[Parameter(9)]
		public int MACDTrigger;
		
		[Parameter(14)] 
		public int RsiPeriod;
		
		RSI rsi;

		MACD macd;

		public override void OnInit()
		{
			macd = MACDIndicator(Symbol, SymbolPeriod, OHLCType.Close, MACDPeriod, MACDPeriod2, MACDTrigger);

			rsi = RSIIndicator(Symbol, SymbolPeriod, OHLCType.Close, RsiPeriod);

			AddSymbol(Symbol, SymbolPeriod);
			//AddSymbol(Symbol, PSar_Period);
			parabolicSar = ParabolicSARIndicator(Symbol, PSar_Period, Acceleration_factor, MaxAcc);


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

		/// <summary>
		/// Init islemleri tamamlaninca, bardatalar kullanmaya hazir hale gelince bu fonksiyon tetiklenir. Data uzerinde bir defa yapilacak islemler icin kullanilir
		/// </summary>
		public override void OnInitComplated()
		{

		}

		/// <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 barDataModel = GetBarData();
			var close = barDataCurrentValues.LastUpdate.Close;
			if (parabolicSar.CurrentValue < close && CrossAbove(macd, macd.MacdTrigger) && CrossAbove(rsi, rsi.UpLevel))
			{
				Debug($"Parabolic SAR {PSar_Period} @{parabolicSar.CurrentValue} < close @ {close}");
				SendMarketOrder(Symbol, Quantity, OrderSide.Buy);
				Debug($"Alis emri gonderildi");
			}
			else if (parabolicSar.CurrentValue > close && CrossAbove(macd, macd.MacdTrigger) && CrossBelow(rsi, rsi.UpLevel)) 
			{
				Debug($"Parabolic SAR {PSar_Period} @{parabolicSar.CurrentValue} > close @ {close}");
				SendMarketOrder(Symbol, Quantity, OrderSide.Sell);
				Debug($"Satis emri gonderildi");
			}

		}

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

			}
		}
	}
}

 

1 0
bu stratejide crossların aynı anda gerçekleşme ihtimali zayıf olduğu için muhtemelen işlem yapmayacaktır fakat
ne yapmak istediğinizi anladım. Çalışan şekilde yazdığımda buradan paylaşacağım.
İyi Akşamlar.
1 0
İlginize çok teşekkür ediyorum

İyi akşamlar
2 0

 

Merhaba operator,
stratejinizi yazmayı bitirdim buyrun.

 

using System;
using System.Collections.Generic;
using System.Linq;
using Matriks.Data.Symbol;
using Matriks.Engines;
using System.Windows.Media;
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 Operator : 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("GARAN")]
		public string Symbol;

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

		ParabolicSAR parabolicSar;

		[Parameter(0.02)]
		public decimal pSar1;

		[Parameter(0.2)]
		public decimal pSarMax;

		MACD macd;
		[Parameter(40)]
		public int macDLongPeriod;
		[Parameter(20)]
		public int macDShortPeriod;
		[Parameter(6)]
		public int macDTriggerPeriod;

		RSI rsi;
		[Parameter(50)]
		public int rsiBuyLevel;
		[Parameter(85)]
		public int rsiBuyLevelMax;
		[Parameter(0)]
		public int rsiSellLevel;
		[Parameter(70)]
		public int rsiSellLevelMax;

		[Parameter(1000)]
		public decimal bakiye;
		[Parameter(0.001)]
		public decimal komisyon;
		[Parameter(false)]
		public bool aldikMi;
		[Parameter(0)]
		public int elimizdekiSenetMiktari;
		public bool macDCalistir = false;

		/// <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()
		{
			rsi = RSIIndicator(Symbol, SymbolPeriod, OHLCType.Close, 14);

			macd = MACDIndicator(Symbol, SymbolPeriod, OHLCType.Close, macDLongPeriod, macDShortPeriod, macDTriggerPeriod);

			parabolicSar = ParabolicSARIndicator(Symbol, SymbolPeriod, pSar1, pSarMax);

			AddSymbol(Symbol, SymbolPeriod);

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

		/// <summary>
		/// Init islemleri tamamlaninca, bardatalar kullanmaya hazir hale gelince bu fonksiyon tetiklenir. Data uzerinde bir defa yapilacak islemler icin kullanilir
		/// </summary>
		public override void OnInitComplated()
		{

		}

		/// <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 bardata = GetBarData();
			var close = Ref(bardata, OHLCType.Close, 0);
			var open = Ref(bardata, OHLCType.Open, 0);

			bool rsiOkeyBuy = false;
			if (Ref(rsi, 0) >rsiBuyLevel && Ref(rsi, 0) <rsiBuyLevelMax)
			{
				rsiOkeyBuy = true;
			}
			bool rsiOkeySell = false;

			if (Ref(rsi, 0) >rsiSellLevel && Ref(rsi, 0) <rsiSellLevelMax)
			{
				rsiOkeySell = true;
			}
			bool macDbuyOkey = false;
			bool macDsellOkey = false;
			if (Ref(macd.MacdTrigger, -1) > Ref(macd.Macd, -1) && Ref(macd.MacdTrigger, 0) < Ref(macd.Macd, 0))
			{
				macDCalistir = true;

				
			}else if (Ref(macd.MacdTrigger, -1) < Ref(macd.Macd, -1) && Ref(macd.MacdTrigger, 0) > Ref(macd.Macd, 0))
			{
				macDCalistir = true;
				
			}
			    
			if(macDCalistir){
				
				if(Ref(macd.MacdTrigger, 0) > Ref(macd.Macd, 0)){
					macDsellOkey = true;
				}
				if(Ref(macd.MacdTrigger, 0) < Ref(macd.Macd, 0)){
					macDbuyOkey = true;
				}
				
				
			}




			bool paraSarOkeyBuy = false;
			if (Ref(parabolicSar, 0) < close)
			{

				paraSarOkeyBuy = true;
			}

			if (rsiOkeyBuy && macDbuyOkey && paraSarOkeyBuy && !aldikMi)
			{
				bakiye -= bakiye * komisyon;
				int senetMiktari2 = (int)((bakiye) / close) -1;
				bakiye -= senetMiktari2 * close;
				SendMarketOrder(Symbol, senetMiktari2, OrderSide.Buy, ChartIcon.Buy);
				elimizdekiSenetMiktari = senetMiktari2;
				Debug("--------------------------------------");
				Debug("ALIŞ EMRİ GÖNDERİLDİ !   " + close);
				Debug("Senet Adet  =" + elimizdekiSenetMiktari);
				aldikMi = true;
			}else if (!paraSarOkeyBuy && aldikMi && macDsellOkey && rsiOkeySell)
			{
				aldikMi = false;
				bakiye -= ((decimal) elimizdekiSenetMiktari * close) * komisyon;
				SendMarketOrder(Symbol, elimizdekiSenetMiktari, OrderSide.Sell, ChartIcon.Sell);
				Debug("SATIŞ EMRİ GÖNDERİLDİ !" + close);

				bakiye += ((decimal) elimizdekiSenetMiktari) * close;



				elimizdekiSenetMiktari = 0;
				Debug("bakiye = " + bakiye);
			}


		}

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

			}
		}
	}
}

 

1 0

Bu da backtest sonucu. Yataydaki işlemleri engelleyecek bir yöntem bulursanız iş yapar stratejiniz :)

1 0
Elinize emeğinize sağlık

Düşündüğümden çok daha güzel bir çalışma olmuş.

Henüz çok yeniyim yataydaki işlemler düşündürücü umarım ilerde çözüm bulabilirim.

Teşekkür ederim. İyi Geceler.
1 0
ne demek benim için zevkti. İleriki dönemde yatay konusunu çözersem size mesajla bildireceğim.  iyi geceler dilerim.
1 0
Umarım çözülür :)

tekrar teşekkürler iyi geceler
1 0

İyi akşamlar gimmemore

yatayda işlemleri oldukça azaltabilecek Kıvanç Bey'in paylaştığı Pmax indikatörü kullanılabilir diye düşünüyorum, tabi mantık olarak doğru gelse de teknik açıdan nasıl olur bilemiyorum. 4 indikatörün al ve sat bölgeleri teoride çok güzel duruyor :)

Edit: Komisyon oranı girildiğinde Alım satım lot sayısı gittikçe düşüyor. Bir de aldikMi fonksiyonunu kavrayamadım indecision

1 0
aldikmi yı koymamın sebebi şudur:
eğer stratejimiz alış yapmış ve elektrik gitmişse veya herhangi bir sebepten strateji durmuşsa tekrar başlatırken elimizdeki senet sayısını ve almış olduğumuzu parametre ekranında belirtip işlem yönünü ona göre doğru seçilmesini sağlamak. Bunun doğru çalışması için SendOrderSequential(true); satırını silmek gerekiyor onu atlamışım.

pmaxi yatay piyasası engelleyecek şekilde optimize ettiğimizde  diğer karlı işlemlere giriş ve çıkışlar baya geç kalıyor. Daha güzel bir yöntem bulunabilir :)
0 0
Bilgilendirme için teşekkür ederim.

Evet pmax çok geç kalıyor :(
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.



7,988 soru
7,961 cevap
4,543 yorum
13,285 kullanıcı