Merhaba,
Stratejide kullanmak istediğiniz enstrüman adedini ve bakiyeyi belirterek strateji çalıştırıp alış satışlara göre güncel bakiyenizi hesaplatıp al sat yaptırmak için aşağıdaki stratejiyi deneyebilirsiniz.
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;
//========================================== by KRIPEX ==========================================//
// Başlangıçta belirlenen bakiyeye ve elinizdeki estrüman adetine göre strateji çalışmaya başlar.//
// Alış sinyali oluştuysa bakiye varsa bakiye kadar alış yapar. //
// Satış sinyali oluştuysa pozisyonunuz varsa hepsini satar. //
// ***** Bu strtaeji Bist ve Binance Spot piyasası için uygundur. //
namespace Matriks.Lean.Algotrader
{
public class SablonBakiyeyeGoreAlSatV1 : MatriksAlgo
{
[SymbolParameter("GARAN")]
public string Symbol;
[Parameter(SymbolPeriod.Min5)]
public SymbolPeriod SymbolPeriod;
[Parameter(3)]
public int Period;
[Parameter(2)]
public decimal Percentage;
MOST most;
public override void OnDataUpdate(BarDataEventArgs barData)
{
if (CrossAbove(most, most, 1, 0))
{
FX_Alis(Symbol);
}
if (CrossBelow(most, most, 1, 0))
{
FX_Satis(Symbol);
}
}
public override void OnInit()
{
AddSymbol(Symbol, SymbolPeriod);
most = MOSTIndicator(Symbol, SymbolPeriod, OHLCType.Close, Period, Percentage, MovMethod.Exponential);
WorkWithPermanentSignal(true);
SendOrderSequential(true, Side.All);
// Gerekli - Timestamp
SetTimerInterval(1);
// #Gerekli - Timestamp
}
// Gerekli - Bakiyeye Göre
[Output][Parameter(50)]
public decimal Bakiye;
[Parameter(0)]
public decimal BaslangıctakiEnstrumanAdedi;
[Parameter(false)]
public bool KomisyonuDahilEt;
[Parameter(0.001)]
public decimal KomisyonOranı;
public decimal Adet;
decimal priceStep;
double tradeFraction;
double decimalCount;
int exchangeID;
public override void OnInitComplated()
{
var symbolDetail = GetSymbolDetail(Symbol);
if (symbolDetail != null)
{
tradeFraction = symbolDetail.TradeFraction;
decimalCount = symbolDetail.DecimalCount;
exchangeID = symbolDetail.ExchangeDetail.ExchangeID;
}
}
public bool FX_BalanceKontrolu(string sembol)
{
bool _sonuc = false;
if ((int) ExchangeType.Ise == exchangeID)
{
_sonuc = (Math.Floor(Bakiye / FX_Sonfiyat(sembol)) >0) ? true: false;
}else if ((int) ExchangeType.Crypto == exchangeID)
{
_sonuc = Bakiye >= 10.5m? true:false;
}
return _sonuc;
}
public void FX_Alis(string sembol)
{
decimal _close = FX_Sonfiyat(sembol);
decimal _adet = 0;
if (FX_BalanceKontrolu(sembol) && LastOrderSide.Obj != Side.Buy)
{
if ((int) ExchangeType.Ise == exchangeID)
{
_adet = Math.Floor(Bakiye / _close);
}else if ((int) ExchangeType.Crypto == exchangeID)
{
_adet = FX_LotAyarla(Bakiye / _close);
}
if (_adet != 0)
{
SendMarketOrder(sembol, _adet, (OrderSide.Buy));
Debug("Alış sinyali oluştu. Sinyal fiyatı: " + _close + " - Adet: " + _adet);
}
}else
{
Debug("XXXXX - Alış sinyali oluştu ama emir gönderilmedi. Bakiye: " + Bakiye);
Debug(" 1 - Bakiyenin işlem açmak için yeterli olup olmadığınız kontrol ediniz.");
Debug(" 2 - Enstrümanın Bist ya da Binance Spot piyasasından olup olmadığını kontrol ediniz.");
}
}
public void FX_Satis(string sembol)
{
if (((Adet != 0 || BaslangıctakiEnstrumanAdedi != 0)) && LastOrderSide.Obj != Side.Sell)
{
Adet += BaslangıctakiEnstrumanAdedi;
SendMarketOrder(sembol, Adet, (OrderSide.Sell));
Debug("Satış sinyali oluştu. Sinyal fiyatı: " + FX_Sonfiyat(sembol) + " - Adet: " + Adet);
}else
{
Debug("Satış sinyali oluştu. Satılacak enstrüman yok. Bakiye: " + Bakiye);
}
}
public decimal FX_LotAyarla(decimal quantity)
{
double _kuvvet = Math.Pow(10, tradeFraction);
return (decimal)(Math.Truncate((double) quantity * _kuvvet) / _kuvvet);
}
public decimal FX_FiyatAyarla(decimal price)
{
double _kuvvet = Math.Pow(10, decimalCount);
return (decimal)(Math.Truncate((double) price * _kuvvet) / _kuvvet);
}
public decimal FX_Sonfiyat(string sembol)
{
return GetSelectedValueFromBarData(GetBarData(sembol, SymbolPeriod), OHLCType.Close);
}
// # Gerekli - Bakiyeye Göre
// Gerekli - Timestamp
public class OrderListTimestamp
{
public string ID;
public string Sembol;
public decimal Adet;
public decimal Fiyat;
public OrdType EmirTipi;
public OrderSide orderSide;
public string EmirYonu;
public DateTime TetiklenmeZamani;
public int Sayac;
public bool AktifMI;
}
Dictionary<string, OrderListTimestamp> timestampDict = new Dictionary<string, OrderListTimestamp>();
[Parameter(3)]
public int AyniEmirKacSeferGonderilsin;
[Parameter(10)]
public int KacSaniyeSonraTekrarGonderilsin;
string orderIDTimestamp = string.Empty;
public override void OnTimer()
{
if ((int) ExchangeType.Crypto == exchangeID)
{
var tutt = timestampDict.Where(x => x.Value.AktifMI == true && DateTime.Now >= x.Value.TetiklenmeZamani);
if (tutt.Count() >0)
{
foreach (var deger in tutt)
{
LastOrderSide.Obj = deger.Value.orderSide == OrderSide.Buy? Side.Sell:Side.Buy;
if (deger.Value.EmirTipi.Obj == OrdType.Limit)
{
orderIDTimestamp = SendLimitOrder(deger.Value.Sembol, deger.Value.Adet, deger.Value.orderSide, deger.Value.Fiyat);
Debug(deger.Value.EmirYonu + " emri tekrar gönderildi.");
}else if (deger.Value.EmirTipi.Obj == OrdType.Market)
{
orderIDTimestamp = SendMarketOrder(deger.Value.Sembol, deger.Value.Adet, deger.Value.orderSide);
Debug(deger.Value.EmirYonu + " emri tekrar gönderildi.");
}
deger.Value.ID = orderIDTimestamp;
deger.Value.AktifMI = false;
timestampDict[orderIDTimestamp] = deger.Value;
timestampDict.Remove(deger.Key);
}
}
}
}
// #Gerekli - Timestamp
public override void OnOrderUpdate(IOrder order)
{
// Gerekli - Bakiyeye Göre
if (order.OrdStatus.Obj == OrdStatus.Filled && order.Side.Obj == Side.Buy)
{
var tutar = order.OrderQty * order.Price;
Bakiye -= tutar;
Adet += BaslangıctakiEnstrumanAdedi + order.OrderQty;
BaslangıctakiEnstrumanAdedi = 0;
if (KomisyonuDahilEt)
{
if ((int) ExchangeType.Ise == exchangeID)
{
Bakiye -= (Bakiye * KomisyonOranı);
}else if ((int) ExchangeType.Crypto == exchangeID)
{
Adet = FX_LotAyarla(Adet - (Adet * KomisyonOranı));
}
}
Debug("================ ALIŞ GERÇEKLEŞTİ ================");
Debug("Adet: " + order.OrderQty + " Fiyat: " + order.Price + " Tutar: " + tutar);
Debug("Bakiye: " + Bakiye + " Toplam Adet: " + Adet);
}
if (order.OrdStatus.Obj == OrdStatus.Filled && order.Side.Obj == Side.Sell)
{
var tutar = order.OrderQty * order.Price;
Bakiye += tutar;
Adet = 0;
BaslangıctakiEnstrumanAdedi = 0;
if (KomisyonuDahilEt)
{
Bakiye -= (Bakiye * KomisyonOranı);
}
Debug("================ SATIŞ GERÇEKLEŞTİ ================");
Debug("Adet: " + order.OrderQty + " Fiyat: " + order.Price);
Debug("Tutar: " + tutar + " - Kalan bakiye: " + Bakiye);
}
// # Gerekli - Bakiyeye Göre
// Gerekli - Timestamp
if (order.OrdStatus.Obj == OrdStatus.Filled)
{
if (timestampDict.ContainsKey(order.CliOrdID))
{
timestampDict.Remove(order.CliOrdID);
Debug("Timestamp hatasına takılan emriniz gerçekleşti.");
}
}
if (order.OrdStatus.Obj == OrdStatus.Rejected)
{
if (!timestampDict.ContainsKey(order.CliOrdID))
{
OrderListTimestamp orderList = new OrderListTimestamp();
orderList.ID = order.CliOrdID;
orderList.Sembol = order.Symbol;
orderList.Adet = order.OrderQty;
orderList.Fiyat = order.Price;
orderList.EmirTipi = order.OrdType;
orderList.TetiklenmeZamani = DateTime.Now;
orderList.Sayac = 0;
orderList.AktifMI = false;
if (order.Side.Obj == Side.Buy)
{
orderList.orderSide = OrderSide.Buy;
orderList.EmirYonu = "Alış";
}else
{
orderList.orderSide = OrderSide.Sell;
orderList.EmirYonu = "Satış";
}
timestampDict[order.CliOrdID] = orderList;
}
if (order.Text.Contains("Timestamp"))
{
if (timestampDict.ContainsKey(order.CliOrdID))
{
if (timestampDict[order.CliOrdID].Sayac < AyniEmirKacSeferGonderilsin)
{
timestampDict[order.CliOrdID].TetiklenmeZamani = DateTime.Now.AddSeconds(KacSaniyeSonraTekrarGonderilsin);
timestampDict[order.CliOrdID].Sayac++;
timestampDict[order.CliOrdID].AktifMI = true;
Debug("Emir Timestamp hatasından dolayı iptal oldu tekrar gönderilecek");
}else
{
timestampDict.Remove(order.CliOrdID);
Debug("Aynı emir üst üste " + AyniEmirKacSeferGonderilsin + " defa gönderildi.");
}
}
}
}
// #Gerekli - Timestamp
}
}
}