PMAX indikatörünün kullanıldığı bir stratejidir. Alım/satım sinyalleri Cross fonksiyonu kullanılarak elde edilir. Strateji long/short pozisyon alabilmektedir. Kalıcı sinyal ve sıralı emir ile çalışmaktadır. AçığaSatışYapılsın seçildiği durumda ilk emir parametrelerde belirtilen miktarda, daha sonraki emirler ise ilk emrin 2 katı olarak gönderilir. Böylece pozisyon 1/0 şeklinde değil, 1/-1 şeklinde alınabilmektedir (long/neutral yerine long/short). OnOrderUpdate fonksiyonu ile algo içerisinde gerçek zamanlı pozisyon takibi yapılmaktadır. AçığaSatışYapılsın kutusu işaretlenmediği takdirde açığa satış yapılmayacaktır ve emirler alış ile başlamak şartı ile sıralı gönderilecektir. Bu durumda Loglar sekmesine: “Emir sinyali geldi fakat emirlerin sıralı gitmesi seçeneği aktif olduğundan emir gönderilmedi” bildirimi yansıtılabilir. Bu, sıralı gönderim bildirimi olup, hata değildir. AçığaSatışYapılsın işaretlendiği durumda ise emirler yine sıralı gönderilecektir, fakat strateji ilk emir olarak satış emri gönderebilecektir.
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; using System; using Matriks.Data.Tick; using Matriks.Enumeration; using Matriks.IntermediaryInstitutionAnalysis.Enums; using Newtonsoft.Json; namespace Matriks.Lean.Algotrader { public class PMAX_Strategy : 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_BUSD_FBIN")] public string Symbol; [Parameter(SymbolPeriod.Min60)] public SymbolPeriod SymbolPeriod; [Parameter(0.01)] public decimal BuyOrderQuantity; [Parameter(0.01)] 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, 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(true, 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(BarDataEventArgs barData) { var pmaxKline = Math.Round(pmax.KLine.CurrentValue, 2); var pmaxSTline = Math.Round(pmax.StLine.CurrentValue, 2); Debug("***********************************************"); Debug("pmaxSTline = " + pmaxSTline); Debug("pmaxKline = " + pmaxKline); if (CrossAbove(pmax.KLine, pmax.StLine)) { if (firstRun == 0 || !AcigaSatisYapilsin) { 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)) { if (firstRun == 0 || !AcigaSatisYapilsin) { 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); } } /// <summary> /// Strateji durdurulduğunda bu fonksiyon tetiklenir. /// </summary> public override void OnStopped() { } } }