Merhabalar,
Çift yönlü işlem yaptığınız stratejilerde maalesef bakiye parametresi kullanılmamaktadır.
Bakiyeyi yalnızca spot işlemlerde kullanabilirsiniz.
Örneği aşağıda verilmiştir.
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 tottbakiye : MatriksAlgo
{
[SymbolParameter("GARAN")]
public string Symbol;
[Parameter(SymbolPeriod.Min5)]
public SymbolPeriod SymbolPeriod;
[Parameter(40)]
public int TOTTPeriod;
[Parameter(1)]
public decimal TOTTOpt;
[Parameter(0.001d)]
public decimal TwinOttCoef;
[Parameter(MovMethod.Variable)]
public MovMethod TottMovMethod;
TOTT tott;
public override void OnDataUpdate(BarDataEventArgs barData)
{
if (CrossAbove(tott.Mov, tott.OttUp))
{
FX_Alis();
}
if (CrossBelow(tott.Mov, tott.OttDown))
{
FX_Satis();
}
}
public override void OnInit()
{
AddSymbol(Symbol, SymbolPeriod);
tott = TOTTIndicator(Symbol, SymbolPeriod, OHLCType.Close, TOTTPeriod, TOTTOpt, TwinOttCoef, TottMovMethod);
WorkWithPermanentSignal(true);
SendOrderSequential(true, Side.All);
// Gerekli - Timestamp
SetTimerInterval(1);
// #Gerekli - Timestamp
}
[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;
[Output]
public string Sembol1 = "";
[Output]
public string Sembol2 = "";
double tradeFraction;
int exchangeID;
public override void OnInitComplated()
{
var SymbolDetail = GetSymbolDetail(Symbol);
tradeFraction = SymbolDetail.TradeFraction;
exchangeID = SymbolDetail.ExchangeDetail.ExchangeID;
if ((int) ExchangeType.Crypto == exchangeID)
{
Sembol1 = Symbol.Split('_')[0];
Sembol2 = Symbol.Split('_')[1];
}
}
public decimal FX_Sonfiyat()
{
var barDataModel = GetBarData();
return Ref(barDataModel, OHLCType.Close, 0);
}
public bool FX_BalanceKontrolu()
{
bool _sonuc = false;
if ((int) ExchangeType.Ise == exchangeID)
{
_sonuc = (Math.Floor(Bakiye / FX_Sonfiyat()) >0) ? true: false;
}else if ((int) ExchangeType.Crypto == exchangeID)
{
_sonuc = Bakiye >= 10.5m? true:false;
}
return _sonuc;
}
public decimal FX_MinSize(decimal quantity)
{
double _kuvvet = Math.Pow(10, tradeFraction);
return (decimal)(Math.Truncate((double) quantity * _kuvvet) / _kuvvet);
}
public void FX_Alis()
{
decimal _close = FX_Sonfiyat();
decimal _adet = 0;
if (FX_BalanceKontrolu() && LastOrderSide.Obj != Side.Buy)
{
if ((int) ExchangeType.Ise == exchangeID)
{
_adet = Math.Floor(Bakiye / _close);
}else if ((int) ExchangeType.Crypto == exchangeID)
{
_adet = FX_MinSize(Bakiye / _close);
}
if (_adet != 0)
{
SendMarketOrder(Symbol, _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()
{
if (((Adet != 0 || BaslangıctakiEnstrumanAdedi != 0)) && LastOrderSide.Obj != Side.Sell)
{
Adet += BaslangıctakiEnstrumanAdedi;
SendMarketOrder(Symbol, Adet, (OrderSide.Sell));
Debug("Satış sinyali oluştu. Sinyal fiyatı: " + FX_Sonfiyat() + " - Adet: " + Adet);
}else
{
Debug("Satış sinyali oluştu. Satılacak enstrüman yok. Bakiye: " + Bakiye);
}
}
// 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)
{
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.");
}
}
}
}
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_MinSize(Adet - Adet * KomisyonOranı);
}
}
Debug("Alış gerçekleşti. Gerçekleşen fiyat: " + order.Price + " - Adet: " + order.OrderQty + "- Tutar: " + tutar + " - 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("Satış gerçekleşti. Gerçekleşen fiyat: " + order.Price + " - Adet: " + order.OrderQty + " - Tutar: " + tutar + " - Kalan bakiye: " + Bakiye);
}
}
}
}
İyi çalışmalar.