Merhaba, kusura bakmayin sorunun cevaplanmasinda biraz geciktik ama yardimci olabilme ihtimali acisindan kodu ekledim, asagida bulabilirsiniz.
"2 . belirlediğim ENV yı da geçerse işlemde kalmasını" durumu icin ek bir kosul gerekmiyor, cunku durum pozisyonda bir degisiklik yaratmiyor acikladiginiz kadari ile.
Onemli bir nokta "public bool islemde = false;" deklerasyonunu OnDataUpdate icerisinde yapmayiniz, aksi taktirde OnDataUpdate her tetiklendiginde bu deger false'a cekilecektir.
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 mov_env : 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("GARAN")]
public string Symbol;
[Parameter(SymbolPeriod.Min5)]
public SymbolPeriod SymbolPeriod;
[Parameter(100)]
public decimal OrderQuantity;
ENV env1;
ENV env2;
MOV mov;
public bool islemde = false;
/// <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>
public override void OnInit()
{
mov = MOVIndicator(Symbol, SymbolPeriod, OHLCType.Close, 5, MovMethod.Simple);
env1 = EnvelopeIndicator(Symbol, SymbolPeriod, OHLCType.Close, 20, 0.5m, MovMethod.Exponential);
env2 = EnvelopeIndicator(Symbol, SymbolPeriod, OHLCType.Close, 20, 0.5m, MovMethod.Exponential);
AddSymbol(Symbol, SymbolPeriod);
//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)
{
/*mov un İlk belirlediğim ENV yı kestiği zaman alım yapmasını,
eğer 2.belirlediğim ENV yı da geçerse işlemde kalmasını,
Daha sonra 2.belirlediğim noktayı aşağı kırdığında da sat yapmasını nasıl sağlayabilirim.
Aşağıdaki şekilde yazdığım kod düşündüğüme göre doğrumudur.*/
if (CrossAbove(mov, env1.Down) && !islemde)
{
SendMarketOrder(Symbol, OrderQuantity, (OrderSide.Buy));
islemde = true;
}
if (CrossBelow(mov, env2.Down) && islemde)
{
SendMarketOrder(Symbol, OrderQuantity, (OrderSide.Sell));
islemde = false;
}
}
/// <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)
{
if (order.OrdStatus.Obj == OrdStatus.Filled)
{
}
}
}
}