Open ve Close icin degerleriniz yanlisti. OnDataUpdate() her yeni bar ACILISINDA data geldigi anda tetiklenmektedir. Open ve close alirken
barDataCurrentValues.LastUpdate.Open;
seklinde alirsaniz yeni acilan barin acilis ve kapanis bilgilerini verir, bunlar da birbirine esit olur bar acildiginda, istediginiz sonuca ulasamazsiniz. Bar acildiginda update geldiginden bir onceki bara bakmaniz gerekir. Bunu da barData.Open[barDataCurrentValues.LastUpdate.BarDataIndex - 1]; seklinde yapabilirsiniz - duzeltildi.
Ayni sekilde canli strateji calistirdiginizda
var ClosePrev2 = Ref(barData, OHLCType.Close, 2);
yeni acilan bardan 3 onceki barin kapanisini vermektedir. Bundan bilginiz var mi emin olamadim, bu sekilde biraktim.
Son olarak backtest'de OnOrderUpdate ile gerceklesen emir fiyati saglikli gelmedigi icin (siz de anladigim kadariyla backtest yapiyorsunuz) alis ve satis emirlerinin kapanis fiyatindan gerceklestigi farz edilmistir.
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 SonBar : 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("XBT_USD_BMEX")]
public string Symbol;
[Parameter(SymbolPeriod.Min)]
public SymbolPeriod SymbolPeriod;
[Parameter(100)]
public decimal Quantity;
[Parameter(0.5)]
public decimal AlisSartiYuzde;
[Parameter(0.5)]
public decimal SatisSartiYuzde;
//Emir takibi degiskenleri
decimal LastBuyOrderPrice = 0;
decimal LastSellOrderPrice = 0;
int realposition = 0;
/// <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);
//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);
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)
{
// bardata verileri çağırılıyor.
var barData = GetBarData();
// Aktif barın open ve close değerleri alınıyor.
var Open = barData.Open[barDataCurrentValues.LastUpdate.BarDataIndex - 1];
var Close = barData.Close[barDataCurrentValues.LastUpdate.BarDataIndex - 1];
// ref fonksiyonu ile 2 önceki close değeri alınıyor.
var ClosePrev2 = Ref(barData, OHLCType.Close, 2);
var alisnoktasi = LastSellOrderPrice*(1+AlisSartiYuzde/100);
var satisnoktasi = LastBuyOrderPrice*(1-SatisSartiYuzde/100);
Debug("******************************************");
Debug($"Open = {Open}, Close = {Close}, PrevClose = {ClosePrev2}");
Debug($"alisnoktasi = {alisnoktasi}, satisnoktasi = {satisnoktasi}, Pozisyon = {realposition}");
// Alış şartı - son barda kapanış açılıştan büyük ve kapanış 2 bar önceki kapanıştan küçük ise
//"veya satış fiyatından %0.5 yükselmiş ise"
if (Close > Open && Close < ClosePrev2 && realposition == 0)
{
SendMarketOrder(Symbol, Quantity, OrderSide.Buy);
Debug("Alim kosulu olustu, alış emri gönderildi.");
//LastBuyOrderPrice = Close;
}
if(Close > alisnoktasi && realposition == 0 && alisnoktasi!=0)
{
Debug($"Close @ {Close} > {alisnoktasi} alisnoktasi ALIM kosulu olustu.");
SendMarketOrder(Symbol, Quantity, OrderSide.Buy);
Debug("Alış emri gönderildi.");
//LastBuyOrderPrice = Close;
}
// Satış şartı - son barda açılış kapanıştan büyük ve kapanış 2 bar önceki kapanıştan büyük ise
//"veya alış fiyatından %0.5 düşmüş ise"
if (Close < Open && Close > ClosePrev2 && realposition == 1)
{
SendMarketOrder(Symbol, Quantity, OrderSide.Sell);
Debug("Satış kosulu olustu, satış emri gönderildi.");
//LastSellOrderPrice = Close;
}
if(Close < satisnoktasi && realposition == 1 && satisnoktasi!=0)
{
Debug($"Close @ {Close} < {satisnoktasi} satisnoktasi SATIS kosulu olustu.");
SendMarketOrder(Symbol, Quantity, OrderSide.Sell);
Debug("Satış emri gönderildi.");
//LastSellOrderPrice = Close;
}
}
/// <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 && order.Side.Obj == Side.Buy)
{
LastBuyOrderPrice = order.Price;
Debug("Alis emri gerceklesti @ " + LastBuyOrderPrice);
realposition++;
Debug("OnorderUpdate: IN LONG POSITION. Position = " + realposition);
}
if (order.OrdStatus.Obj == OrdStatus.Filled && order.Side.Obj == Side.Sell)
{
LastSellOrderPrice = order.Price;
Debug("Satis emri gerceklesti @ " + LastSellOrderPrice);
realposition--;
Debug("OnorderUpdate: SOLD POSITION. Position = " + realposition);
}
}
}
}