BTC_USDT_BIN paritesinde bakiyeye göre emir gönderiyorum. Ondalık emirleri trailing stop loss sıfır olarak alıyor. Ondalık emirler için trailing stop loss'u nasıl yazacağız?
Kodum--------------------------------
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 BakiyeKomistonCrossMov : 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.Day)]
public SymbolPeriod SymbolPeriod;
[Parameter(10)]
public int MovPeriod;
[Parameter(20)]
public int MovFark;
[Parameter(3.5)]
public decimal trlngstplss;
[Parameter(false)]
public bool izsurenstop;
// Başlangıç adet
[Parameter(0)]
public decimal StartQuantity;
// Tutar
public decimal Amount;
// Al sat adedi
public decimal Quantity;
public int OrderQuantity;
public decimal Bakiye = 100;
public int firstrun = 0;
// Bakiye kontrolü
public bool BalanceControl = true;
// strateji hisse senedi ile mi coin ile mi kullanılacak
[Parameter(false)]
public bool HisseSenedi;
ISyntheticOrderPrices TSL;
int SystemPosition = 0;
decimal 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>
///
MOV mov;
MOV mov2;
public override void OnInit()
{
AddSymbol(Symbol, SymbolPeriod);
mov = MOVIndicator(Symbol, SymbolPeriod, OHLCType.Close, MovPeriod, MovMethod.Exponential);
mov2 = MOVIndicator(Symbol, SymbolPeriod, OHLCType.Close, MovPeriod + MovFark, MovMethod.Exponential);
//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);
}
/// <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)
{
var barDataModel = GetBarData();
var Index = barDataCurrentValues.LastUpdate.BarDataIndex;
var Close = barDataCurrentValues.LastUpdate.Close;
// Güncel bakiye ile alış yapıp yapamayacağınız kontrolü ediliyor. true ise alış yapabilir
if (HisseSenedi)
{
BalanceControl = (Math.Floor(Bakiye / Close) >0) ? true: false;
}
if (CrossAbove(mov, mov2) && BalanceControl == true && Bakiye > 0.00000001m && SystemPosition == 0)
{
// Alabileceği adet
if (HisseSenedi)
{
Quantity = Math.Floor(Bakiye * 999 / 1000 / Close);
}else
{
Quantity = Bakiye * 999 / 1000 / Close;
}
// Tutar
Amount = Quantity * Close;
Debug("Komisyon Öncesi Amount: " + Amount);
Debug("Komisyon Öncesi Bakiye: " + Bakiye);
// Güncel bakiye
Bakiye -= Amount;
Debug("Komisyon ve Alış Sonrası Bakiye: " + Bakiye);
SendMarketOrder(Symbol, Quantity, (OrderSide.Buy));
if (izsurenstop) TSL = TrailingStopLoss(Symbol, SyntheticOrderPriceType.Percent, trlngstplss);
SystemPosition = 1;
Quantity += StartQuantity;
StartQuantity = 0;
Debug("Alış Sinayli Oluştu. Fiyat: " + Close + " - Adet: " + Quantity + " - Tutar: " + Amount + " - Kalan Bakiye: " + Bakiye);
}else if (CrossAbove(mov, mov2) && (BalanceControl == false || Bakiye == 0))
{
Debug("Alış sinyali oluştu. Bakiyeniz yetersiz. Kalan Bakiye: " + Bakiye);
}
if (CrossBelow(mov, mov2) && (Quantity != 0 || StartQuantity != 0) && SystemPosition == 1)
{
Quantity += StartQuantity;
// Tutar
Amount = Quantity * Close;
// Güncel bakiye
Bakiye += Amount * 999 / 1000;
SendMarketOrder(Symbol, Quantity, OrderSide.Sell);
Debug("Satış sinyali oluştu. Fiyat: " + Close + " - Adet: " + Quantity + " - Tutar: " + Amount + " - Kalan Bakiye: " + Bakiye);
SystemPosition = 0;
Quantity = 0;
StartQuantity = 0;
}else if (CrossBelow(mov, mov2) && Quantity == 0)
{
Debug("Satış sinyali oluştu. Satılacak enstrüman yok. Kalan Bakiye: " + Bakiye);
}
}
/// <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)
{
//Gercek zamanli pozisyon takibi
if (order.OrdStatus.Obj == OrdStatus.Filled && order.Side.Obj == Side.Buy)
{
var positionChange = order.OrderQty;
realposition += (decimal) positionChange;
Debug("[ONORDERUPDATE]: Pozisyon = " + realposition);
if (realposition == 0)
{
SystemPosition = 0;
Debug("Kar AL / Zarar Durdur tetiklendi");
}
}
if (order.OrdStatus.Obj == OrdStatus.Filled && order.Side.Obj == Side.Sell)
{
var positionChange = order.OrderQty;
realposition -= (decimal) positionChange;
Debug("[ONORDERUPDATE]: Pozisyon = " + realposition);
if (realposition == 0 && SystemPosition == 1)
{
SystemPosition = 0;
Debug("Kar AL / Zarar Durdur tetiklendi");
Quantity += StartQuantity;
// Tutar
Amount = Quantity * order.Price;
Debug("Komisyon Öncesi Amount: " + Amount);
Debug("Komisyon Öncesi Bakiye: " + Bakiye);
// Güncel bakiye
Bakiye += Amount * 999 / 1000;
Debug("Komisyon Sonrası Bakiye: " + Bakiye);
Quantity = 0;
StartQuantity = 0;
}
}
}
}
}