Merhaba,
Aşağıda vermiş olduğum stratejide backtest sırasında bir problem yaşamıyorum. Fakat canlı çalıştırdıgımda şöyle bir durumla karşılaştım. Normalde 1 alıp 2 satıyorken, bir sinyalde 3-4 kere sat emri gönderdi ve hiçbir emir çalışmadı. Daha sonra tekrar yukarı kestiğinde 4 kere al gönderdi hiçbiri yine çalışmadı. En son tekrar sat gönderdiginde 2 satacagına 1 sattı ve tamamen pozisyonlarım kapandı. Burdaki sıkıntı ne olabilir.
Emir örnekleri (sırayla):
-Al: 1 adet (1 adet long )
-Sat:2 adet (1 adet long kapandı 1 adet short açıldı)
-Al: 2 adet (1 adet short kapandı 1 adet long açıldı)
-4 kere gelen ve çalışmayan sat emri (hala 1 adet long açık)
-4 kere gelen ve çalışmayan al emri ( hala 1 adet long açık)
-Sat: 1 adet ( tüm pozisyonlar kapandı, burda 2 adet satması gerekirdi.)
Strateji:
using MOTT = Matriks.Lean.Algotrader.EmbeddedCustom93361378115283151371657180103745885921294081419.MOTT;
using Matriks.AlgoTrader;
using Matriks.Data.Identifiers;
using System.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using Matriks;
using Matriks.Data.Symbol;
using Matriks.Data.Tick;
using Matriks.Engines;
using Matriks.Indicators;
using Matriks.Symbols;
using Matriks.Trader.Core;
using Matriks.Trader.Core.Fields;
using Matriks.Lean.Algotrader.AlgoBase;
using Matriks.Lean.Algotrader.Models;
using Matriks.Lean.Algotrader.Trading;
using Matriks.AI;
using Matriks.AI.AiParameters;
using Matriks.AI.Data;
using Matriks.Trader.Core.TraderModels;
using Matriks.Enumeration;
using Matriks.IntermediaryInstitutionAnalysis.Enums;
/*
▂ ▃ ▅ ▆ █ KRİPEX █ ▆ ▅ ▃ ▂
Gönderilen emir iptal olursa belirlenen sayı kadar tekrar gönderilmesi sağlanır.
Bu şablon AcigaSatisYapilsin seçeneği aktif olduğunda Viop ve Binance Future piyasaları için uygun olur.
AcigaSatisYapilsin seçeneği pasif olduğunda istenilen piyasada işlem yapacaktır.
Stratejinin çift yönlü ilerlemesi istendiğinde AcigaSatisYapilsin seçeneğinin aktif edilmesi gerekir ( varsayılan aktif )
Akşam seansında da oluşan sinyallere emir gönderilmesi için AksamSeansiniDahilEt seçeneğinin aktif edilmesi gerekir ( varsayılan pasif )
Kripto piyasası 7/24 açık olduğu için bu seçeneğin aktif ya da pasif seçilmesi birşey değiştirmez.
HangiIslemleBaslasin değişkeni ile stratejinin ilk Long ya da Short pozisyon ile başlaması sağlanabilir.
*** Stratejiye eklenen sentetik emirler tetiklendiğinde pozisyon sıfırlanıp ilk gelecek sinyale göre işleme girecektir.
*/
namespace Matriks.Lean.Algotrader
{
public class MOTTOrtakanal_V2: MatriksAlgo
{
/*
MOTT_4B Kurgu
AL
Cross(MOV(C,opt1,VAR),OTT(HHV(H,opt2),2,opt3)) OR
Cross(MOV(C,opt1,VAR),(OTT(HHV(H,opt2),2,opt3)+(OTT(HHV(H,opt2),2,opt3)+OTT(LLV(L,opt2),2,opt3))/2)/2) OR
Cross(MOV(C,opt1,VAR),(OTT(HHV(H,opt2),2,opt3)+OTT(LLV(L,opt2),2,opt3))/2) OR
Cross(MOV(C,opt1,VAR),(OTT(LLV(L,opt2),2,opt3)+(OTT(HHV(H,opt2),2,opt3)+OTT(LLV(L,opt2),2,opt3))/2)/2)
SAT
Cross(OTT(HHV(H,opt2),2,opt3),MOV(C,opt1,VAR)) OR
Cross((OTT(HHV(H,opt2),2,opt3)+(OTT(HHV(H,opt2),2,opt3)+OTT(LLV(L,opt2),2,opt3))/2)/2,MOV(C,opt1,VAR)) OR
Cross((OTT(HHV(H,opt2),2,opt3)+OTT(LLV(L,opt2),2,opt3))/2,MOV(C,opt1,VAR)) OR
Cross((OTT(LLV(L,opt2),2,opt3)+(OTT(HHV(H,opt2),2,opt3)+OTT(LLV(L,opt2),2,opt3))/2)/2,MOV(C,opt1,VAR))
*/
// ⒶⓀⒾⓃ ℍü
[SymbolParameter("GARAN")]
public string Symbol1;
[Parameter(SymbolPeriod.Day)]
public SymbolPeriod SymbolPeriod1;
[Parameter(4)]
public int MovPeriod;
[Parameter(MovMethod.VAR)]
public MovMethod MovMovMethod;
[Parameter(80)]
public int MottX1;
[Parameter(1.4)]
public decimal MottX2;
[Parameter(0)]
public int MottOteleme;
//_____________BURAYI KOPYALA________________//
[Parameter(5)]
public decimal BuyOrderQuantity;
[Parameter(5)]
public decimal SellOrderQuantity;
[Parameter(CryptoLeverageType.Cross)]
public CryptoLeverageType kaldirac_tipi_binance_future;
[Parameter(2)]
public decimal kaldirac_orani_binance_future;
//_____________BURAYI KOPYALA________________//
MOV mov;
MatriksIndicator MOTT;
public override void OnInit()
{
AddSymbol(Symbol1, SymbolPeriod1);
mov = MOVIndicator(Symbol1, SymbolPeriod1, OHLCType.Close, MovPeriod, MovMovMethod);
MOTT = new MOTT();
MOTT.SetIndicatorParameters("X1", MottX1);
MOTT.SetIndicatorParameters("X2", MottX2);
MOTT.SetIndicatorParameters("Oteleme", MottOteleme); RegisterUserIndicator(MOTT, Symbol1, SymbolPeriod1, OHLCType.Close, 5);
//_____________BURAYI KOPYALA________________//
// ------------ Timestamp OnInit ------------
SetTimerInterval(1);
// ------------ Timestamp OnInit ------------
SetLeverageType(Symbol1, kaldirac_tipi_binance_future); //sadece binance futureda aktif olur.
SetLeverage(Symbol1, kaldirac_orani_binance_future); ////sadece binance futureda aktif olur.
// Gerekli başla - Açığa satış
WorkWithPermanentSignal(true);
SendOrderSequential(true, HangiIslemleBaslasin);
SendOrderSequentialForShort(true, Side.All);
// #Gerekli bitti - Açığa satış
//_____________BURAYI KOPYALA________________//
}
public override void OnTimer()
{
//_____________BURAYI KOPYALA________________//
// ------------ Timestamp OnTimer ------------
var sorgu = RejectedOrderList.Where(x => x.Value.BitmexPostOnly == true && DateTime.Now >= x.Value.ExpireDate && x.Value.MinPosition>0);
var oncekiYon = LastOrderSide.Obj;
foreach (var deger in sorgu)
{
var order = deger.Value;
LastOrderSide.Obj = Side.All;
var orderID = SendOrder(order.Symbol, order.OrderQty, order.Price, order.Side, order.OrdType, order.TimeInForce, order.TransactionType, order.ChartIcon);
order.MinPosition--;
order.BitmexPostOnly = false;
order.ExpireDate = DateTime.Now.AddSeconds(KacSaniyeSonraTekrarGonderilsin);
order.CliOrdID = orderID;
Debug("İptal olan emir tekrar gönderildi. Detay -> CliOrdID: " + order.CliOrdID + " Yon: " + order.Side.Obj.ToString() + " kalan: " + order.MinPosition);
}
LastOrderSide.Obj = oncekiYon;
// ------------ Timestamp OnTimer ------------
//_____________BURAYI KOPYALA________________//
}
public override void OnDataUpdate(BarDataEventArgs barData)
{
if (CrossAbove(mov, MOTT, 0, 1)
|| CrossAbove(mov, MOTT, 0, 2)
|| CrossAbove(mov, MOTT, 0, 3))
{
FX_Alis(Symbol1, BuyOrderQuantity);
}
if (CrossBelow(mov, MOTT, 0, 1)
|| CrossBelow(mov, MOTT, 0, 2)
|| CrossBelow(mov, MOTT, 0, 3))
{
FX_Satis(Symbol1, SellOrderQuantity);
}
}
//_____________BURAYI KOPYALA________________//
// Gerekli başla - Açığa satış
[Parameter(true)]
public bool AcigaSatisYapilsin;
[Parameter(false)]
public bool AksamSeansiniDahilEt;
[Parameter(Side.All)]
public Side HangiIslemleBaslasin;
public bool FX_Alis(string sembol, decimal quantity)
{
bool sonuc = false;
if (LastOrderSide.Obj != Side.Buy)
{
var _quantity = (LastOrderSide.Obj == Side.All || !AcigaSatisYapilsin) ? quantity:(LastOrderSideForShort.Obj == Side.All) ? quantity:quantity * 2;
SendMarketOrder(sembol, _quantity, OrderSide.Buy, includeAfterSession:AksamSeansiniDahilEt);
Debug("Alış emri gönderildi.[ " + _quantity + " adet ]");
LastOrderSideForShort = LastOrderSide;
sentetikEmirdenMI = false;
sonuc = true;
}
return sonuc;
}
public bool FX_Satis(string sembol, decimal quantity)
{
bool sonuc = false;
if (LastOrderSide.Obj != Side.Sell)
{
var _quantity = (LastOrderSide.Obj == Side.All || !AcigaSatisYapilsin) ? quantity:(LastOrderSideForShort.Obj == Side.All) ? quantity:quantity * 2;
SendMarketOrder(sembol, _quantity, OrderSide.Sell, includeAfterSession:AksamSeansiniDahilEt);
Debug("Satış emri gönderildi.[ " + _quantity + " adet ]");
LastOrderSideForShort = LastOrderSide;
sentetikEmirdenMI = false;
sonuc = true;
}
return sonuc;
}
bool sentetikEmirdenMI = false;
public override void OnSyntheticOrderTriggered(SyntheticAlgoOrder sOrder)
{
if (sOrder.EnableOrderSending)
{
if (AcigaSatisYapilsin)
{
LastOrderSide.Obj = Side.All;
sentetikEmirdenMI = true;
}
Debug("Sentetik emir tetiklendi");
}
}
// #Gerekli bitti - Açığa satış
// ------------ Timestamp Tanımlar ------------
int KacSaniyeSonraTekrarGonderilsin = 10;
int AyniEmirKacSeferGonderilsin = 3;
Dictionary<string, IOrder> RejectedOrderList = new Dictionary<string, IOrder>();
// ------------ Timestamp Tanımlar ------------
//_____________BURAYI KOPYALA________________//
/// <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)
{
//_____________BURAYI KOPYALA________________//
if (order.OrdStatus.Obj == OrdStatus.Filled)
{
// ------------ Timestamp OnOrderUpdate Filled ------------
var sorgu = RejectedOrderList.FirstOrDefault(x => x.Value.CliOrdID == order.CliOrdID);
if (sorgu.Key != null)
{
Debug("İptal olan emir gerçekleşti. Detay-> CliOrdID: " + order.CliOrdID + " Text: " + sorgu.Value.Text);
}
// ------------ Timestamp OnOrderUpdate Filled ------------
}
if (order.OrdStatus.Obj == OrdStatus.Rejected)
{
// ------------ Timestamp OnOrderUpdate Rejected ------------
var sorgu = RejectedOrderList.FirstOrDefault(x => x.Value.CliOrdID == order.CliOrdID);
if (sorgu.Key == null)
{
order.BitmexPostOnly = true;
order.MinPosition = AyniEmirKacSeferGonderilsin;
order.ExpireDate = DateTime.Now.AddSeconds(KacSaniyeSonraTekrarGonderilsin);
RejectedOrderList[order.CliOrdID] = order;
Debug("Emir iptal oldu. Detay-> CliOrdID: " + order.CliOrdID + " Text: " + order.Text);
}else
{
sorgu.Value.BitmexPostOnly = true;
}
// ------------ Timestamp OnOrderUpdate Rejected ------------
}
//_____________BURAYI KOPYALA________________//
}
}
public class EmbeddedCustom93361378115283151371657180103745885921294081419
{
//Ilk parametre indikatörün adı, sınıfın adıyla aynı olmalıdır.
//Ikinci parametre indikatörün Dataserisinin üzerine mi yeni pencereye mi ekleneceğini belirtir. Yeni pencere için ->IndicatorDrawingArea.NewWindow , Data Serisi için IndicatorDrawingArea.OnDataSeries
[IndicatorInformationAttribute("MOTT", IndicatorDrawingArea.OnDataSeries)]
//Indikatörün çizgilerinin isimleri
[IndicatorLineInformationAttribute(new []
{
"Line1(0,1)", "Line2", "Line3", "Line4", "Line5"
},
new []
{
"#FF87CEFA", "#FF87CEFA", "#FFFFF0F5",
"#FFFF00FF", "#FFFF00FF"
},
new []
{
false, false, false,
false, false
},
new []
{
0, 2, 2,
2, 0
}, new []
{
1, 1, 1,
1, 1
})]
public class MOTT : MatriksIndicator
{
[DefaultValue(80)]
public int X1
{
get; set;
}
[DefaultValue(1.4)]
public decimal X2
{
get; set;
}
[DefaultValue(3)]
public int Oteleme
{
get; set;
}
MOV mov, mov2, mov3;
OTT ott, ott2;
HighestHigh HHV;
LowestLow LLV;
public sealed override void OnInit()
{
ott = new OTT(2, X2, MovMethod.VAR, false);
ott2 = new OTT(2, X2, MovMethod.VAR, false);
HHV = new HighestHigh(X1);
LLV = new LowestLow(X1);
mov = new MOV(1, MovMethod.Simple);
mov2 = new MOV(1, MovMethod.Simple);
mov3 = new MOV(1, MovMethod.Simple);
}
public override void OnDataUpdate(int currentBar, decimal inputValue, DateTime barDateTime)
{
if (currentBar < Period)
{
SetLine(0, currentBar, 0);
SetLine(1, currentBar, 0);
SetLine(2, currentBar, 0);
SetLine(3, currentBar, 0);
SetLine(4, currentBar, 0);
return;
}
var L = Instrument.SymbolBarData.Low[currentBar];
var H = Instrument.SymbolBarData.High[currentBar];
HHV.Update(H, currentBar, barDateTime);
ott.Update(HHV.CurrentValue, currentBar, barDateTime);
LLV.Update(L, currentBar, barDateTime);
ott2.Update(LLV.CurrentValue, currentBar, barDateTime);
var line1 = (((ott.Value[0][ott.CurrentIndex]) + ((ott.Value[0][ott.CurrentIndex] + ott2.Value[0][ott2.CurrentIndex]) / 2m)) / 2m);
mov.Update(line1, currentBar, barDateTime);
var line2 = (ott.CurrentValue + ott2.CurrentValue) / 2m;
mov2.Update(line2, curren