Merhaba. Bu forumda paylaşmış olduğunuz pmax stratejini aynı zamanda tradingwievden de takip ediyorum. Matrikse de, tradingvieve de aynı değerler vermeme rağmen, matriks tradihg vieve göre çok daha geç alıp çok daha geç satıyor. Bunun nedeni ne olabilir ?
Ayrıca trading vievde mov metodu Ema olarak tanımlıyorum. Matrikste ise Exponential olarak tanımlıyorum. Tardingwievdeki ema, matrikste neye karşılık geliyor ?
Ayrıca bu kodları indikatör olarak, matrikse ekledim. Kıvanç beyin youtubedeki vidosundan aldığım şekli ile ekledim. Ancak grafik üzerinde indikatör tradingviewde birebir aynı iken, strateji kısmında alım satım noktaları aynı değerler olmasına rağmen çok farklı. Özellikle en az 2 bar sonra alım ve satım yapıyor. Yardımcı olursanız sevinirim.
Kodlarım şu şekilde ;
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) //
//Ilk satis sinyali gelirse "Satış emri gönderildi" Debug ekraninda ciksa bile log ekranina baktiginizda Emir sinyali //
//geldi fakat emirlerin sıralı gitmesi seçeneği aktif olduğundan emir gönderilmedi ifadesini goreceksiniz. //
//EMIR GONDERIMI SIRALI OLDUGU ICIN SIRASIZ GELEN EMIR BORSAYA ILETILMEMISTIR. //
namespace Matriks.Lean.Algotrader
{
public class SARP : 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(false);
}
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_.Open.ContainsKey(currentBar - 1) || currentBar <= bufferlength) 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_.Open[currentBar - 1 - i]);
var _range3_ = Math.Abs(_low_ - _barData_.Open[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.Open.ContainsKey(currentBar - 1)) return ;
var high = barData.High[currentBar];
var low = barData.Low[currentBar];
var diff = high - low;
var range2 = Math.Abs(high - barData.Open[currentBar - 1]);
var range3 = Math.Abs(low - barData.Open[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)
{
}
}
}
}