MatriksIQ Destek
Matriks Destek
Matriks Web Destek
Matriks Mobile Destek
2 beğenilme 0 beğenilmeme
2,663 kez görüntülendi
Merhaba,

Strateji başlangıcında alış ve satış miktarı girmemizi istiyor. Sürekli aynı miktardan al sat yapmasını istemiyorum elimdeki bakiyeye göre al sat yaptırmak istiyorum. Rica etsem yardımcı olabilir misiniz?
Algoritmik Trading kategorisinde (1,654 puan) tarafından | 2,663 kez görüntülendi

2 Cevaplar

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

Merhaba,

Stratejide kullanmak istediğiniz enstrüman adedini ve bakiyeyi belirterek strateji çalıştırıp alış satışlara göre güncel bakiyenizi hesaplatıp al sat yaptırmak için aşağıdaki stratejiyi deneyebilirsiniz.

 

using System;
using System.Collections.Generic;
using System.Linq;
using Matriks.Data.Symbol;
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;

//========================================== by KRIPEX ==========================================//
// Başlangıçta belirlenen bakiyeye ve elinizdeki estrüman adetine göre strateji çalışmaya başlar.//
// Alış sinyali oluştuysa bakiye varsa bakiye kadar alış yapar.                                  //
// Satış sinyali oluştuysa pozisyonunuz varsa hepsini satar.                                     //
// ***** Bu strtaeji Bist ve Binance Spot piyasası için uygundur.                                //

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

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

		[Parameter(3)]
		public int Period;

		[Parameter(2)]
		public decimal Percentage;

		MOST most;

		public override void OnDataUpdate(BarDataEventArgs barData)
		{
			if (CrossAbove(most, most, 1, 0))
			{
				FX_Alis(Symbol);
			}

			if (CrossBelow(most, most, 1, 0))
			{
				FX_Satis(Symbol);
			}
		}

		public override void OnInit()
		{
			AddSymbol(Symbol, SymbolPeriod);

			most = MOSTIndicator(Symbol, SymbolPeriod, OHLCType.Close, Period, Percentage, MovMethod.Exponential);

			WorkWithPermanentSignal(true);

			SendOrderSequential(true, Side.All);

			// Gerekli - Timestamp
			SetTimerInterval(1);
			// #Gerekli - Timestamp
		}

		// Gerekli - Bakiyeye  Göre		
		[Output][Parameter(50)]
		public decimal Bakiye;

		[Parameter(0)]
		public decimal BaslangıctakiEnstrumanAdedi;

		[Parameter(false)]
		public bool KomisyonuDahilEt;

		[Parameter(0.001)]
		public decimal KomisyonOranı;

		public decimal Adet;

		decimal priceStep;
		double tradeFraction;
		double decimalCount;
		int exchangeID;

		public override void OnInitComplated()
		{
			var symbolDetail = GetSymbolDetail(Symbol);

			if (symbolDetail != null)
			{
				tradeFraction = symbolDetail.TradeFraction;
				decimalCount = symbolDetail.DecimalCount;
				exchangeID = symbolDetail.ExchangeDetail.ExchangeID;
			}
		}

		public bool FX_BalanceKontrolu(string sembol)
		{
			bool _sonuc = false;

			if ((int) ExchangeType.Ise == exchangeID)
			{
				_sonuc = (Math.Floor(Bakiye / FX_Sonfiyat(sembol)) >0) ? true: false;
			}else if ((int) ExchangeType.Crypto == exchangeID)
			{
				_sonuc = Bakiye >= 10.5m? true:false;
			}

			return _sonuc;
		}

		public void FX_Alis(string sembol)
		{
			decimal _close = FX_Sonfiyat(sembol);
			decimal _adet = 0;

			if (FX_BalanceKontrolu(sembol) && LastOrderSide.Obj != Side.Buy)
			{
				if ((int) ExchangeType.Ise == exchangeID)
				{
					_adet = Math.Floor(Bakiye / _close);
				}else if ((int) ExchangeType.Crypto == exchangeID)
				{
					_adet = FX_LotAyarla(Bakiye / _close);
				}

				if (_adet != 0)
				{
					SendMarketOrder(sembol, _adet, (OrderSide.Buy));
					Debug("Alış sinyali oluştu. Sinyal fiyatı: " + _close + " - Adet: " + _adet);
				}
			}else
			{
				Debug("XXXXX - Alış sinyali oluştu ama emir gönderilmedi. Bakiye: " + Bakiye);
				Debug("		1 - Bakiyenin işlem açmak için yeterli olup olmadığınız kontrol ediniz.");
				Debug("		2 - Enstrümanın Bist ya da Binance Spot piyasasından olup olmadığını kontrol ediniz.");
			}
		}

		public void FX_Satis(string sembol)
		{
			if (((Adet != 0 || BaslangıctakiEnstrumanAdedi != 0)) && LastOrderSide.Obj != Side.Sell)
			{
				Adet += BaslangıctakiEnstrumanAdedi;

				SendMarketOrder(sembol, Adet, (OrderSide.Sell));
				Debug("Satış sinyali oluştu. Sinyal fiyatı: " + FX_Sonfiyat(sembol) + " - Adet: " + Adet);
			}else
			{
				Debug("Satış sinyali oluştu. Satılacak enstrüman yok. Bakiye: " + Bakiye);
			}
		}

		public decimal FX_LotAyarla(decimal quantity)
		{
			double _kuvvet = Math.Pow(10, tradeFraction);
			return (decimal)(Math.Truncate((double) quantity * _kuvvet) / _kuvvet);
		}

		public decimal FX_FiyatAyarla(decimal price)
		{
			double _kuvvet = Math.Pow(10, decimalCount);
			return (decimal)(Math.Truncate((double) price * _kuvvet) / _kuvvet);
		}

		public decimal FX_Sonfiyat(string sembol)
		{
			return GetSelectedValueFromBarData(GetBarData(sembol, SymbolPeriod), OHLCType.Close);
		}
		// # Gerekli - Bakiyeye  Göre			

		// Gerekli - Timestamp
		public class OrderListTimestamp
		{
			public string ID;
			public string Sembol;
			public decimal Adet;
			public decimal Fiyat;
			public OrdType EmirTipi;
			public OrderSide orderSide;
			public string EmirYonu;
			public DateTime TetiklenmeZamani;
			public int Sayac;
			public bool AktifMI;
		}

		Dictionary<string, OrderListTimestamp> timestampDict = new Dictionary<string, OrderListTimestamp>();

		[Parameter(3)]
		public int AyniEmirKacSeferGonderilsin;

		[Parameter(10)]
		public int KacSaniyeSonraTekrarGonderilsin;

		string orderIDTimestamp = string.Empty;

		public override void OnTimer()
		{
			if ((int) ExchangeType.Crypto == exchangeID)
			{
				var tutt = timestampDict.Where(x => x.Value.AktifMI == true && DateTime.Now >= x.Value.TetiklenmeZamani);

				if (tutt.Count() >0)
				{
					foreach (var deger in tutt)
					{
						LastOrderSide.Obj = deger.Value.orderSide == OrderSide.Buy? Side.Sell:Side.Buy;

						if (deger.Value.EmirTipi.Obj == OrdType.Limit)
						{
							orderIDTimestamp = SendLimitOrder(deger.Value.Sembol, deger.Value.Adet, deger.Value.orderSide, deger.Value.Fiyat);
							Debug(deger.Value.EmirYonu + " emri tekrar gönderildi.");
						}else if (deger.Value.EmirTipi.Obj == OrdType.Market)
						{
							orderIDTimestamp = SendMarketOrder(deger.Value.Sembol, deger.Value.Adet, deger.Value.orderSide);
							Debug(deger.Value.EmirYonu + " emri tekrar gönderildi.");
						}

						deger.Value.ID = orderIDTimestamp;
						deger.Value.AktifMI = false;
						timestampDict[orderIDTimestamp] = deger.Value;
						timestampDict.Remove(deger.Key);

					}
				}
			}
		}
		// #Gerekli - Timestamp

		public override void OnOrderUpdate(IOrder order)
		{
			// Gerekli - Bakiyeye  Göre	
			if (order.OrdStatus.Obj == OrdStatus.Filled && order.Side.Obj == Side.Buy)
			{
				var tutar = order.OrderQty * order.Price;

				Bakiye -= tutar;

				Adet += BaslangıctakiEnstrumanAdedi + order.OrderQty;
				BaslangıctakiEnstrumanAdedi = 0;

				if (KomisyonuDahilEt)
				{
					if ((int) ExchangeType.Ise == exchangeID)
					{
						Bakiye -= (Bakiye * KomisyonOranı);
					}else if ((int) ExchangeType.Crypto == exchangeID)
					{
						Adet = FX_LotAyarla(Adet - (Adet * KomisyonOranı));
					}
				}
				Debug("================ ALIŞ GERÇEKLEŞTİ ================");
				Debug("Adet: " + order.OrderQty + " Fiyat: " + order.Price + " Tutar: " + tutar);
				Debug("Bakiye: " + Bakiye + " Toplam Adet: " + Adet);
			}

			if (order.OrdStatus.Obj == OrdStatus.Filled && order.Side.Obj == Side.Sell)
			{
				var tutar = order.OrderQty * order.Price;

				Bakiye += tutar;

				Adet = 0;
				BaslangıctakiEnstrumanAdedi = 0;

				if (KomisyonuDahilEt)
				{
					Bakiye -= (Bakiye * KomisyonOranı);
				}

				Debug("================ SATIŞ GERÇEKLEŞTİ ================");
				Debug("Adet: " + order.OrderQty + " Fiyat: " + order.Price);
				Debug("Tutar: " + tutar + " - Kalan bakiye: " + Bakiye);
			}
			// # Gerekli - Bakiyeye  Göre	

			// Gerekli - Timestamp			
			if (order.OrdStatus.Obj == OrdStatus.Filled)
			{
				if (timestampDict.ContainsKey(order.CliOrdID))
				{
					timestampDict.Remove(order.CliOrdID);
					Debug("Timestamp hatasına takılan emriniz gerçekleşti.");
				}
			}

			if (order.OrdStatus.Obj == OrdStatus.Rejected)
			{
				if (!timestampDict.ContainsKey(order.CliOrdID))
				{
					OrderListTimestamp orderList = new OrderListTimestamp();
					orderList.ID = order.CliOrdID;
					orderList.Sembol = order.Symbol;
					orderList.Adet = order.OrderQty;
					orderList.Fiyat = order.Price;
					orderList.EmirTipi = order.OrdType;
					orderList.TetiklenmeZamani = DateTime.Now;
					orderList.Sayac = 0;
					orderList.AktifMI = false;

					if (order.Side.Obj == Side.Buy)
					{
						orderList.orderSide = OrderSide.Buy;
						orderList.EmirYonu = "Alış";
					}else
					{
						orderList.orderSide = OrderSide.Sell;
						orderList.EmirYonu = "Satış";
					}

					timestampDict[order.CliOrdID] = orderList;
				}

				if (order.Text.Contains("Timestamp"))
				{
					if (timestampDict.ContainsKey(order.CliOrdID))
					{
						if (timestampDict[order.CliOrdID].Sayac < AyniEmirKacSeferGonderilsin)
						{
							timestampDict[order.CliOrdID].TetiklenmeZamani = DateTime.Now.AddSeconds(KacSaniyeSonraTekrarGonderilsin);
							timestampDict[order.CliOrdID].Sayac++;
							timestampDict[order.CliOrdID].AktifMI = true;

							Debug("Emir Timestamp hatasından dolayı iptal oldu tekrar gönderilecek");
						}else
						{
							timestampDict.Remove(order.CliOrdID);
							Debug("Aynı emir üst üste " + AyniEmirKacSeferGonderilsin + " defa gönderildi.");
						}
					}
				}
			}
			// #Gerekli - Timestamp				
		}
	}
}


 

(6,932 puan) tarafından
tarafından düzenlendi
0 0
Peki bakiyenin 3'te biri, ya da yüzde olarak %40'ı kadar alım yap diye komut verebiliyor muyuz?
0 0
Yukardaki örnek kod ile bakiye takibi mümkün olmayacaktır. Çünkü emir gönderildiğinde bakiye değiştiriliyor. Emir gerçekleşmeyebilir.

Portfoy bilgilerimize neden ulaşamıyoruz? Araştırmama göre GetPortfolio() fonksiyonu mevcut. ancak çalışmıyor. Bu çalışır hale getirilse iyi olur.

Teşekkürler
0 0

Aşağıdaki kod yapısını kullanarak overall ve işlem limitine ulaşabilirsiniz. Daha sonra işlem limitini hangi oranda kullanmak isterseniz hesaplatıp Bakiye değişkenine atayabilirsiniz.

aşağıdaki linki de inceleyebilirsiniz.

https://destek.matriksdata.com/?qa=95/portf%C3%B6y-penceresinde-g%C3%B6r%C3%BClen-bilgileri-strateji-edit%C3%B6r%C3%BCne&show=95#q95

var overall = BistOverall;         //Hesaptaki toplam para(hesap Overall)

var islemLimiti = BistAvailableMargin;  //Margin trading hesabi varsa

		

Debug("overall: " + overall + " islemLimiti " + islemLimiti);

 

0 0
Merhaba,

Hem yukardaki cevabınızı hemde linkini verdiğiniz kodları denedim.

Aşağıda yaptığım testlere ait kodlar mevcut. Ancak GetPortfolio() dan değer gelmiyor. Neden olabilir? Yatırım firmasına göre değişkenlik gösterir mi?

 

Teşekkürler

 

 

 

 

 

Debug("OnInitComplated");

var overall = GetOverall();      //Islem limiti

var para1 = BistOverall;         //Hesaptaki toplam para(hesap Overall)

 

var para = BistAvailableMargin;  //Margin trading hesabi varsa

 

Debug($"overall:{overall}, para1:{para1}, para:{para}");

 

decimal stock=0;

IDictionary<string, decimal> portfolio = GetPortfolio();

var positionflag = portfolio.ContainsKey(Symbol) && portfolio[Symbol] != 0;

if (positionflag) stock = portfolio[Symbol];

Debug($"hisse:{Symbol}, stock:{stock}");

foreach(var str in portfolio.Keys)

{

Debug($"str:{str}, {portfolio[str]}");

}

 

var tradeUser = GetTradeUser();

var account = tradeUser.Accounts.FirstOrDefault();

var overall2 = account.Overall;

var PnL = account.ProfitLoss;

 

Debug($"acc:{account}, overall2:{overall2}, pnl:{PnL}");
0 0
selam belirttiğiniz kodu kopyalayıp yapıştırdığımda

CS0246 hatası alıyorum nerede yanlış yapıyorum bu örnek kodu tam olarak nereye yapıştırmam gerekli ?
0 0

Merhaba,

Lütfen strateji isminizin BakiyeyeGoreAlSat olduğundan emin olunuz.

Farklı bir isim ile kaydedip derlemeye çalıştırıyorsanız bu hata mesajı ile karşılaşabilirsiniz.

İyi çalışmalar.

stratejiye ekleme
0 0
sorunu hallettim teşekkür ederim.
0 beğenilme 0 beğenilmeme
Düzenleme yapıldı 11.01.2022

HisseSenediMI, MinSize gibi değişkenler kullanılan sembole göre otomatik çekildi.
(6,932 puan) tarafından
0 0
Merhaba, bu yapıda kaldıraç oranı belirleyemiyor muyuz?

İkinci sorum, açığa satış yapacak şekilde de kullanamıyor muyuz? (Çift yönlü çalışmasına gerek yok, sadece açığa satış yapıp pozisyonu kapaması yeterli.) FX_Alis ve FX_Satis'in public void satırlarını ve orderside'larını yer değiştirip sendordersequential'ı Side.Sell yapsak açığa satan yapıya dönüşür mü kripto tarafı için?

Üçüncü sorum da, Binance Futures için bunu sadeleştirsek (başlangıç bakiyesini kaldırsak, hisse ile ilgili olan şeyleri silsek falan) sistem performasını arttırıcı etkisi olur mu?

Teşekkürler şimdiden.
1 0

Merhabalar,

bu yapıda kaldıraç oranı belirleyemiyor muyuz?

Maalesef kaldıraç oranı belirleyemiyorsunuz.

İkinci sorum, açığa satış yapacak şekilde de kullanamıyor muyuz? (Çift yönlü çalışmasına gerek yok, sadece açığa satış yapıp pozisyonu kapaması yeterli.) FX_Alis ve FX_Satis'in public void satırlarını ve orderside'larını yer değiştirip sendordersequential'ı Side.Sell yapsak açığa satan yapıya dönüşür mü kripto tarafı için?

Açığa satış yapacak şekilde çift taraflı kullanamazsınız. Fakat bahsettiğiniz gibi satış ile başlayacak şekilde sistemi ayarlarsanız (SendOrderSequential(true,Side.Sell) açığa satış gibi çalışır.

Üçüncü sorum da, Binance Futures için bunu sadeleştirsek (başlangıç bakiyesini kaldırsak, hisse ile ilgili olan şeyleri silsek falan) sistem performasını arttırıcı etkisi olur mu?

Performansı çok etkileyen yapılar değildir, fakat dilerseniz test edebilirsiniz.

İyi çalışmalar.

4,849 soru
4,857 cevap
3,198 yorum
3,636 kullanıcı