using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using Matriks.Data.Identifiers;
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;
namespace Matriks.Lean.Algotrader
{
//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("PRMIv2", IndicatorDrawingArea.OnDataSeries)]
//Indikatörün çizgilerinin isimleri
[IndicatorLineInformationAttribute(new []
{
"ST (0,1)", "K (0,1)"
})]
public class PRMIv2 : MatriksIndicator
{
[DefaultValue(5)]
public int MomentumPeriod
{
get; set;
}
[DefaultValue(20)]
public double Nominator
{
get; set;
}
[DefaultValue(10)]
public int AtrPeriod
{
get; set;
}
[DefaultValue(10)]
public int MovPeriod
{
get; set;
}
[DefaultValue(3)]
public int Coeff
{
get; set;
}
[DefaultValue(MovMethod.E)]
public MovMethod MovMethod
{
get; set;
}
MOM mom;
WILDERS wilders;
MOV mov;
RSI rsiofmomentum;
public sealed override void OnInit()
{
mom = MOMIndicator(Symbol, SymbolPeriod, OHLCType.Close, MomentumPeriod);
wilders = new WILDERS(AtrPeriod);
mov = new MOV(MovPeriod, MovMethod);
rsiofmomentum = RSIIndicator(mom, AtrPeriod);
}
Dictionary<int, decimal> fubDict = new Dictionary<int, decimal>();
Dictionary<int, decimal> flbDict = new Dictionary<int, decimal>();
public override void OnDataUpdate(int currentBar, decimal inputValue, DateTime barDateTime)
{
SetLine(currentBar, 0);
SetLine(1, currentBar, 0);
if (currentBar < AtrPeriod)
{
fubDict[currentBar] = 0;
flbDict[currentBar] = 0;
return ;
}
if (currentBar - 1 < 0 || !Instrument.SymbolBarData.Close.ContainsKey(currentBar - 1)) return ;
var high = Instrument.SymbolBarData.High[currentBar];
var low = Instrument.SymbolBarData.Low[currentBar];
var close = Instrument.SymbolBarData.Close[currentBar];
var diff = high - low;
var range2 = Math.Abs(high - Instrument.SymbolBarData.Close[currentBar - 1]);
var range3 = Math.Abs(low - Instrument.SymbolBarData.Close[currentBar - 1]);
var value = Math.Max(diff, Math.Max(range2, range3));
wilders.Update(value, currentBar, barDateTime);
mov.Update((high + low) / 2, currentBar, barDateTime);
mom.Update(close, currentBar, barDateTime);
double enumrsi = Convert.ToDouble(rsiofmomentum.CurrentValue.ToString());
decimal coefficient = Convert.ToDecimal(Math.Exp(Nominator / enumrsi).ToString());
var k = mov.CurrentValue;
var offset = coefficient * wilders.CurrentValue;
var str = k + offset;
var sts = k - offset;
var prev = Value[0][currentBar -1];
var fub = str<prev || Ref(mov, -1) >prev? str:prev;
var flb = sts>prev || Ref(mov, -1) <prev? sts:prev;
fubDict[currentBar] = fub;
flbDict[currentBar] = flb;
var st = prev == fubDict[currentBar -1] && k<fub? fub : (prev == fubDict[currentBar -1] && k>fub? flb:(prev == flbDict[currentBar -1] && k>flb? flb
:(prev == flbDict[currentBar -1] && k<flb? fub:fub)));
SetLine(currentBar, st);
SetLine(1, currentBar, k);
}
}
}
Merhaba,
Yukarıda PMAX indikatörüne kendi düzenlemelerimi ekledim, PRMI olarak kayıtlı duruyor. Coefficient çarpanı artık sabit değil RSİ(Mom(5),ATRperiod)/80'in logaritmik üssünden alıyor. Amacım bu kodu strateji haline getirebilmek. Bu kodla ilgili bir kaç sorum var:
1) Yeni eklenen PMAX stratejisinde gördüğüm kadarıyla PMAX(Değişken1,Değişken2,Değişken3...) şeklinde çağırılabiliyor. Bu şekilde kullanıcı indikatörlerini de çağırabiliyor muyum? PMAX stratejisini düzenlerken kullanıcı indikatörü aşağıdaki şekilde eklendi. Virgülden sonrakileri strateji içerisindeki parametre adlarıyla değiştirdim. Bu şekilde çalışır mı?
PRMI = new PRMI();
PRMI.SetIndicatorParameters("MomentumPeriod", MomentumPeriod);
PRMI.SetIndicatorParameters("Nominator", Nominator);
PRMI.SetIndicatorParameters("AtrPeriod", ATRPeriod);
PRMI.SetIndicatorParameters("MovPeriod", MovPeriod);
PRMI.SetIndicatorParameters("Coeff", Coefficient);
PRMI.SetIndicatorParameters("MovMethod", MovMethod);
RegisterUserIndicator(PRMI, Symbol, SymbolPeriod, OHLCType.Close, 5);
2) Yine PMAX stratejisinde gördüğüm kadarıyla pmax.STline gibi indikatörün hesapladığı line'i direkt olarak çağırabiliyorum. Bunu kullanıcı indikatöründe nasıl tanımlayıp, stratejide çağırabilirim?
3) Stratejide sabit quantitylerden ziyade işleme girmeden önce şunun gibi bir mantık çalıştırmak istiyorum. Fakat bu ATR'ın çok düşük olduğu menkul kıymetlerde overall'dan daha fazla para koymana sebep olabiliyor. Sizce math.min ile sabitlemek mi daha sağlıklı olur yoksa başka bir yöntem öneriniz var mıdır?
qty = Overall*MaksimumAnaparaKaybetmeYüzdesi / (AlışSatışSinyalindekiATR*coefficient(PRMIdakideğer))