#40452 - Tue Apr 17 2012 10:47 AM
Take Profit и Stop Loss на основе дневного ATR
|
stranger
Registered: Fri Mar 02 2012
Записи: 8
|
Здравствуйте. Пытаюсь реализовать технику выхода из позиции на основе тейк профита и стоп лоса построенных на основе дневного ATR, рабочий тайм фрейм час. Для этого набросал простенькую стратегию где вход в сделку осушествляется при пересечении скользяшей средней цены закрытия. Стратегия компилится без ошибок но работает очень странно. Если поставить дату начиная от 01.04.2012 0:00:00 то все работает рис 2. Если же поставить дату 01.03.2012 0:00:00 то вылетает исключение "в экземпляре объекта не задана ссылка на объект" рис 1. Вот код стратегии
public class ATRExit : IExternalScript
{
public OptimProperty SMAPeriodParam = new OptimProperty(27, 10, 30, 1);
public OptimProperty atrDailyPeriodParam = new OptimProperty(12, 1, 30, 1);
public OptimProperty atrStopPercentParam = new OptimProperty(50, 10, 100, 5);
public OptimProperty winLossParam = new OptimProperty(4, 2, 7, 1);
public void Execute(IContext ctx, ISecurity sec)
{
int SMAPeriod = this.SMAPeriodParam;
int atrDailyPeriod = this.atrDailyPeriodParam;
int atrStopPercent = this.atrStopPercentParam;
int winLoss = this.winLossParam;
IList<double> SMA = ctx.GetData("SMA", new[] { SMAPeriod.ToString() }, delegate { return Series.SMA(sec.ClosePrices, SMAPeriod); });
var dailySec = sec.CompressTo(1440); //Делаю компрессию до дня
IList<double> atrDaily = ctx.GetData("atrDaily", new[] { atrDailyPeriod.ToString() }, delegate { return Series.AverageTrueRange(dailySec.Bars, atrDailyPeriod); }); //вычисляю дневной ATR
IList<double> hourlyATR = dailySec.Decompress(atrDaily, DecompressMethodWithDef.Default);//Синхронизирую дневной ATR с часовым интервалом
double takeProfit = 0;
double stopLoss = 0;
for (int bar = 60; bar < sec.Bars.Count - 1; bar++)
{
if (sec.Positions.LastPositionActive != null)
{
if (sec.Positions.LastPositionActive.IsLong)
{
sec.Positions.LastPositionActive.CloseAtProfit(bar, takeProfit, "Long"); //Выставляю Take Profit
sec.Positions.LastPositionActive.CloseAtStop(bar, stopLoss, "Long"); //Выставляю Stop Loss
}
else
{
sec.Positions.LastPositionActive.CloseAtProfit(bar, takeProfit, "Short");
sec.Positions.LastPositionActive.CloseAtStop(bar, stopLoss, "Short");
}
}
else
{
if (CrossOver(bar, sec.ClosePrices, SMA)) //Вхожу в длинную позицию
{
sec.Positions.BuyAtMarket(bar + 1, 1, "Long");
takeProfit = sec.ClosePrices[bar] + atrStopPercent * winLoss * hourlyATR[bar] / 100; //Вычисляю Take Profit для Лонга
stopLoss = sec.ClosePrices[bar] - atrStopPercent * hourlyATR[bar] / 100; //Вычисляю Stop Loss для Лонга
}
else if (CrossUnder(bar, sec.ClosePrices, SMA))
{
sec.Positions.SellAtMarket(bar + 1, 1, "Short");
takeProfit = sec.ClosePrices[bar] - atrStopPercent * winLoss * hourlyATR[bar] / 100; //Вычисляю Take Profit для Шорта
stopLoss = sec.ClosePrices[bar] + atrStopPercent * hourlyATR[bar] / 100; //Вычисляю Stop Loss для Шорта
}
}
}
}
private bool CrossOver(int bar, IList<double> series1, IList<double> series2)
{
return ((series1[bar] >= series2[bar]) && (series1[bar - 1] < series2[bar - 1]));
}
private bool CrossUnder(int bar, IList<double> series1, IList<double> series2)
{
return ((series1[bar] < series2[bar]) && (series1[bar - 1] >= series2[bar - 1]));
}
}
P.S. А как вставить загруженные картинки в сам текст сообшения?
Attachments
2.PNG (291 downloads)1.PNG (259 downloads)
|
|
Наверх
|
|
|
|
#40459 - Tue Apr 17 2012 02:46 PM
Re: Take Profit и Stop Loss на основе дневного ATR
[Re: WD-40]
|
stranger
Registered: Fri Mar 02 2012
Записи: 8
|
Ну как не у кого нет идей с чем это связанно?
|
|
Наверх
|
|
|
|
#40487 - Tue Apr 17 2012 06:46 PM
Re: Take Profit и Stop Loss на основе дневного ATR
[Re: Nektodron]
|
stranger
Registered: Fri Mar 02 2012
Записи: 8
|
Спасибо за подсказку в пофиксил багу. Вот код
public void Execute(IContext ctx, ISecurity sec)
{
int SMAPeriod = this.SMAPeriodParam;
int atrDailyPeriod = this.atrDailyPeriodParam;
int atrStopPercent = this.atrStopPercentParam;
int winLoss = this.winLossParam;
IList<double> SMA = ctx.GetData("SMA", new[] { SMAPeriod.ToString() }, delegate { return Series.SMA(sec.ClosePrices, SMAPeriod); });
var dailySec = sec.CompressTo(1440); //Делаю компрессию до дня
IList<double> atrDaily = ctx.GetData("atrDaily", new[] { atrDailyPeriod.ToString() }, delegate { return Series.AverageTrueRange(dailySec.Bars, atrDailyPeriod); }); //вычисляю дневной ATR
IList<double> hourlyATR = dailySec.Decompress(atrDaily, DecompressMethodWithDef.Default);//Синхронизирую дневной ATR с часовым интервалом
for (int bar = 60; bar < sec.Bars.Count - 1; bar++)
{
IPosition lastActivePosition = sec.Positions.LastPositionActive;
if (lastActivePosition != null)
{
if (sec.Positions.LastPositionActive.IsLong)
{
double takeProfit = lastActivePosition.EntryPrice + atrStopPercent * winLoss * hourlyATR[lastActivePosition.EntryBarNum] / 100;
double stopLoss = lastActivePosition.EntryPrice - atrStopPercent * hourlyATR[lastActivePosition.EntryBarNum] / 100;
if (lastActivePosition.IsActive)
{
lastActivePosition.CloseAtProfit(bar + 1, takeProfit, "Long"); //Выставляю Take Profit
}
if (lastActivePosition.IsActive)
{
lastActivePosition.CloseAtStop(bar + 1, stopLoss, "Long"); //Выставляю Stop Loss
}
}
else
{
double takeProfit = lastActivePosition.EntryPrice - atrStopPercent * winLoss * hourlyATR[lastActivePosition.EntryBarNum] / 100;
double stopLoss = lastActivePosition.EntryPrice + atrStopPercent * hourlyATR[lastActivePosition.EntryBarNum] / 100;
if (lastActivePosition.IsActive)
{
lastActivePosition.CloseAtProfit(bar + 1, takeProfit, "Short");
}
if (lastActivePosition.IsActive)
{
lastActivePosition.CloseAtStop(bar + 1, stopLoss, "Short");
}
}
}
else
{
if (CrossOver(bar, sec.ClosePrices, SMA)) //Вхожу в длинную позицию
{
sec.Positions.BuyAtMarket(bar + 1, 1, "Long");
}
else if (CrossUnder(bar, sec.ClosePrices, SMA))
{
sec.Positions.SellAtMarket(bar + 1, 1, "Short");
}
}
}
}
Мне правда не нравится большое количество проверок, но пока не придумал как можно отрефакторить. У меня по этому коду ещё пара вопросов есть. 1.Правильно ли я понимаю, что при закрытие позиции через CloseAtProfit и CloseAtStop когда цена коснется цены указанной в заявке, то будет сгенерирован рыночный приказ. То есть, к примеру, я купил сбербанк за 100 рублей тэйк профит поставил на 110, а стоп лосс установил на 90. Когда на рынке совершится первая сделка с ценой к примеру 110.1р. то моя заявка будет исполнена по рынку? 2.Будут ли у меня проблемы при реальной торговле при теперешних модификациях кода. Я имею в виду то что я рассчитываю тейк и стоп каждый раз а не запоминаю значение.
double takeProfit = lastActivePosition.EntryPrice + atrStopPercent * winLoss * hourlyATR[lastActivePosition.EntryBarNum] / 100;
double stopLoss = lastActivePosition.EntryPrice - atrStopPercent * hourlyATR[lastActivePosition.EntryBarNum] / 100;
if (lastActivePosition.IsActive)
{
lastActivePosition.CloseAtProfit(bar + 1, takeProfit, "Long"); //Выставляю Take Profit
}
if (lastActivePosition.IsActive)
{
lastActivePosition.CloseAtStop(bar + 1, stopLoss, "Long"); //Выставляю Stop Loss
}
|
|
Наверх
|
|
|
|
|
|