Derinlik datasi kullanarak ZAMAN AYARLI (belirlenen kadar saniyede bir) çalışır. SADECE ilk seviye ya da 2. seviye kutusunun seçilmesi gerekmektedir. İkisi birden ya da hiçbiri seçildiğinde hata verecektir. Seçilen seviye sayısına göre alış ve satışta bekleyen emirlerin lot sayılarını karşılaştırır. Örneğin ilk 2 seviye seçer ve ÇARPANA 5 değeri atarsak bu 2 seviyedeki alışları ve satışları toplar, alışların toplamı satışların toplamının 5 katından büyükse alım emri gönderir, satış emri de ayni mantıkla yapılır. Bilgiler debug penceresine basılmaktadır.

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;
using Matriks.Data.Tick;
using Matriks.Enumeration;
using Matriks.IntermediaryInstitutionAnalysis.Enums;
using Newtonsoft.Json;

//=============================================ACIKLAMA=====================================================//
// Derinlik datasi kullanarak ZAMAN AYARLI (belirlenen kadar saniyede bir) calisir. 						//
// SADECE ilk seviye ya da 2. seviye kutusunun secilmesi gerekmektedir. 									//
// Ikisi birden ya da hicbiri secildiginde hata verecektir. Secilen seviye sayisina gore alis ve satista	//
// bekleyen emirlerin lot sayilarini karsilastirir. Ornegin ilk 2 seviye secer ve ÇARPANA 5 degeri atarsak	//
// bu 2 seviyedeki alislari ve satislari toplar, alislarin toplami satislarin toplaminin 5 katindan buyukse	// 
// alim emri gonderir, satis emri de ayni mantikla yapilir. Bilgiler debug penceresine basilmaktadir.		//

namespace Matriks.Lean.Algotrader
{
	public class MarketDepth3Timer : 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.Min)]
		public SymbolPeriod SymbolPeriod;

		[Parameter(1)]
		public int saniye;

		[Parameter(1)]
		public decimal SellOrderQuantity;

		[Parameter(1)]
		public decimal BuyOrderQuantity;

		[Parameter(true)]
		public bool ilk_Seviye;

		[Parameter(false)]
		public bool ilk_2_Seviye;

		[Parameter(8)]
		public float çarpan;

		[Output]
		public float SatisUstKademe_Fiyat;
		[Output]
		public float SatisUstKademe1_Miktar;
		[Output]
		public float SatisUstKademe2_Miktar;
		[Output]
		public float AlisUstKademe_Fiyat;
		[Output]
		public float AlisUstKademe1_Miktar;
		[Output]
		public float AlisUstKademe2_Miktar;

		List<SessionTimeInfo> sessiontime;
		 
		public override void OnInit()
		{
			AddSymbol(Symbol, SymbolPeriod);
			AddSymbolMarketDepth(Symbol);

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

			//Alttaki fonksiyon açıldıktan sonra parametre olarak verilen saniyede bir OnTimer fonksiyonu tetiklenir.
			SetTimerInterval(saniye);
		}

		public override void OnTimer()
		{
			var barDataModel = GetBarData();
			var depths = GetMarketDepth(Symbol);
			//var sessiontime = new SessionTimeInfo GetSessionTimes(Symbol);
			//var sessiontime = GetSessionTimes(Symbol);
			var sessiontime = GetSessionTimes(Symbol);
			//var timespan = TimeSpan.FromMinutes.TotalDays;
			var endhour = sessiontime[0].End.Hours;
			var endminute = sessiontime[0].End.Minutes;
			var endsecond = sessiontime[0].End.Seconds;

			var asktime = depths.AskRows[1].DateTime;
			var bardatatime = barDataModel.Time;

			 if (depths?.AskRows == null || depths.AskRows.Count < 1 || 
           depths?.BidRows == null || depths.BidRows.Count < 1)
       {
            Debug("Derinlik verisi bekleniyor.");
            return;
       }

			float BO_size = (float) depths.AskRows[0].Size;
			float BO1_size = (float) depths.AskRows[1].Size;
			float BO = (float) depths.AskRows[0].Price;
			float BO1 = (float) depths.AskRows[1].Price;

			float BB_size = (float) depths.BidRows[0].Size;
			float BB1_size = (float) depths.BidRows[1].Size;
			float BB = (float) depths.BidRows[0].Price;
			float BB1 = (float) depths.BidRows[1].Price;

			Debug("best offer " + BO + " size = " + BO_size + ", " + BO1_size);
			Debug("best bid " + BB + " size = " + BB_size + ", " + BB1_size);
			Debug(endhour);

			SatisUstKademe_Fiyat = BO;
			SatisUstKademe1_Miktar = BO_size;
			SatisUstKademe2_Miktar = BO1_size;

			AlisUstKademe_Fiyat = BB;
			AlisUstKademe1_Miktar = BB_size;
			AlisUstKademe2_Miktar = BB1_size;

			if (DateTime.Now.TimeOfDay.Hours < endhour || (DateTime.Now.TimeOfDay.Hours == endhour && DateTime.Now.TimeOfDay.Minutes < endminute)
				|| (DateTime.Now.TimeOfDay.Hours == endhour && DateTime.Now.TimeOfDay.Minutes == endminute
				&& DateTime.Now.TimeOfDay.Seconds < endsecond))
			{
				if (ilk_Seviye == true && ilk_2_Seviye == false)
				{
					Debug("Current Ratio(BB_1/BO_1 size) = " + Math.Round(BB_size / BO_size, 2));
					Debug("*******************************************************");
					if (BO_size > çarpan * BB_size)
					{
						SendMarketOrder(Symbol, SellOrderQuantity, OrderSide.Sell);
						Debug("Satış Emri Gönderildi");
					}

					if (BB_size > çarpan * BO_size)
					{
						SendMarketOrder(Symbol, BuyOrderQuantity, OrderSide.Buy);
						Debug("Alış Emri Gönderildi");
					}
				}

				if (ilk_Seviye == false && ilk_2_Seviye == true)
				{
					Debug("Current Ratio(BB_2/BO_2 size) = " + Math.Round((BB_size + BB1_size) / (BO_size + BO1_size), 2));
					Debug("*******************************************************");
					if ((BO_size + BO1_size) > çarpan * (BB_size + BB1_size))
					{
						SendMarketOrder(Symbol, SellOrderQuantity, OrderSide.Sell);
						Debug("Satış Emri Gönderildi");
					}

					if ((BB_size + BB1_size) > çarpan * (BO_size + BO1_size))
					{
						SendMarketOrder(Symbol, BuyOrderQuantity, OrderSide.Buy);
						Debug("Alış Emri Gönderildi");
					}
				}
				if ((ilk_Seviye == false && ilk_2_Seviye == false) || (ilk_Seviye == true && ilk_2_Seviye == true))
				{
					Debug("ERROR: 1 YA DA 2 SEVIYE KULLANILMALIDIR");
				}
			}
			else
			{
				Debug("Sürekli işlem seansı kapanmıştır. Stratejide alım/satım emir iletimi durduruldu");
			}
		}


		/// <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(BarDataEventArgs barData)
		{

		}

		/// <summary>
		/// Strateji durdurulduğunda bu fonksiyon tetiklenir.
		/// </summary>
		public override void OnStopped()
		{
		}
	}
}