Merhaba, size ozelden mesaj attim, log'larinizi gonderirseniz daha saglikli bir strateji yazabiliriz, stratejinizi gonderirseniz de sizin stratejiniz uzerine yazarbilirim.
Asagiya emir gitmedigi takdirde emri tekrar gonderen bir strateji yaziyorum. Strateji bunu pozisyon kontrolu yaparak basarmaktadir. Riski sudur, emir baska herhangi bir neden ile Bitmex'e ulasmaz ise, ya da API (orn. baglanti kesilmesi) ulasmadigini sanar ise, emri tekrar gonderecektir. Bu arada emir exchange tarafindan zaten gerceklestirilmis olabilir, bu durumda emir gercekte 2 hatta daha fazla kere gerceklesmis olabilir.
Bu Strateji WorkWithPermanentSignal(true); (kalici sinyal) ile calisacak sekilde yazilmistir. Yani periyot olarak belirlediginiz surede bir fiyata update geldiginde calismaktadir. Orn. 1dk'lik periyot belirlersek dk'da bir calisacaktir.
Trading stratejisi kismi basit yazilmistir (siz buraya kendi stratejinizi yapistirabilin diye) belirlenen SMA'nin uzerinde kapanista alim, altinda ise satim yapmaktadir. Her 15 saniyede bir kontrol etmek isterseniz (ki bu baska problemlere de yol acabilir) OnTimer'da calisacak ayri bir strateji yazarak bunu da size gonderecegim birazdan. Su haliyle pozisyon kontrolunu dakikada bir kere yapmaktadir, cogu strateji icin yeterlidir.
***STRATEJIYI BITMEX TESTNET'DE TEST ETMEDEN VE SIZIN ISTEDIGINIZ SEKILDE CALISTIGINA EMIN OLMADAN GERCEK ORTAMDA HIC BIR ZAMAN CALISTIRMAYIN***
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;
//===============================================ACIKLAMA===================================================//
// SMA indikatöründe, fiyat çubuklarınının SMA bandının üstüne kırdığı anda al, //
// altına kırdığı anda sat sinyali üretilir. Cross değil relational operator (<, >) kullanır //
// Emirler piyasa fiyatından gönderilir ve Emir gönderimi ile birlikte strateji raporunda //
// Debug sekmesine "Alış emri gönderildi ve "Satış emri gönderildi." ifadesi yazdırılmaktadır. //
// Normal SMA stratejisine ek olarak Kar al ve Zarar durdur fonksiyonlarinin kullanımı örneklendirilmiştir. //
namespace Matriks.Lean.Algotrader
{
public class bitmex_overloaded : 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 BuyOrderQuantity;
[Parameter(100)]
public decimal SellOrderQuantity;
[Parameter(60)]
public int Period;
SMA sma;
int SystemPosition = 0, realposition = 0, OnOrderUpdate_Executed = 0;
decimal Close = 0, Sma = 0;
public override void OnInit()
{
sma = SMAIndicator(Symbol, SymbolPeriod, OHLCType.Close, Period);
//sma200 = SMAIndicator(Symbol, SymbolPeriod.Day, OHLCType.Close, 200);
AddSymbol(Symbol, SymbolPeriod);
SetTimerInterval(5);
// 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(false);
}
/// <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)
{
Close = barData.BarData.Close;
Sma = Math.Round(sma.CurrentValue, 2);
Debug("==============================");
Debug("Close:" + Close);
Debug("Sma:" + Sma);
//var barDataModel = GetBarData();
if (Close > Sma)
{
if (realposition == 0 && SystemPosition == 0)
{
Debug($"Gercek Pozisyon = {realposition}. Alış emri gönderiliyor.");
SendMarketOrder(Symbol, BuyOrderQuantity, (OrderSide.Buy));
SystemPosition = 1;
}
else if (realposition == 0 || realposition == -1 * SellOrderQuantity && SystemPosition == 1)
{
Debug($"Gercek Pozisyon = {realposition}. Alış emri gönderildi FAKAT ULAŞMADI, tekrar gönderiliyor.");
SendMarketOrder(Symbol, BuyOrderQuantity, (OrderSide.Buy));
}
else if (realposition == -1 * SellOrderQuantity && SystemPosition == -1)
{
SendMarketOrder(Symbol, BuyOrderQuantity * 2, (OrderSide.Buy));
Debug("Alış emri verildi.");
SystemPosition = 1;
}
}
if (Close < Sma)
{
if (realposition == 0 && SystemPosition == 0)
{
SendMarketOrder(Symbol, SellOrderQuantity, (OrderSide.Sell));
Debug("Satış emri verildi.");
SystemPosition = -1;
}
else if (realposition == 0 || realposition == 1 * BuyOrderQuantity && SystemPosition == -1)
{
Debug($"Gercek Pozisyon = {realposition}. Satış emri gönderildi FAKAT ULAŞMADI, tekrar gönderiliyor.");
SendMarketOrder(Symbol, BuyOrderQuantity, (OrderSide.Buy));
}
else if (realposition == 1 * BuyOrderQuantity && SystemPosition == 1)
{
SendMarketOrder(Symbol, SellOrderQuantity * 2, (OrderSide.Sell));
Debug("Satış emri verildi.");
SystemPosition = -1;
}
}
}
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);
}
}
}
}