Стратегии и роботы > Усреднение!
-
- Сообщения: 47
- Зарегистрирован: 13 мар 2019, 00:45
- Благодарил (а): 37 раз
- Поблагодарили: 1 раз
Re: Усреднение!
Евгений, все работает как надо.
Я хотел узнать именно по стратегии с закрытием в конце дня. Правильно я понимаю, что робот на основе этой стратегии при запуске например днем, пересчитывает позиции (виртуально) с утра , что бы принять решение, что делать?
Просто ситуация такая сегодня: Торгую минутки фьюча газа. Максимальный объем набираемый 10 лотов.
Утром запустил робота. Гэп вниз, робот берет лонг 1 порцию. Мы идем вверх, он продает и начинает набирать шорт. К 11 часам уже набрано 10 лотов и фьюч идет дальше. Я вижу, что настроение бычье и где то в 12 часов выключаю робота. Нажимаю Остановить и закрыть позиции.
Фьюч ушел значительно выше. Т.е. робот бы держал в шорте 10 фьючей и накапливал бы убыток. Но я закрыл позу и выключил его.
Перезапустил АД. В районе 16-00 я понимаю, что возможно рынок уйдет в боковик. Запускаю робота а он ничего не делает)
Т.е. по идее он ждет возврата к ценам что были утром???
Я хотел узнать именно по стратегии с закрытием в конце дня. Правильно я понимаю, что робот на основе этой стратегии при запуске например днем, пересчитывает позиции (виртуально) с утра , что бы принять решение, что делать?
Просто ситуация такая сегодня: Торгую минутки фьюча газа. Максимальный объем набираемый 10 лотов.
Утром запустил робота. Гэп вниз, робот берет лонг 1 порцию. Мы идем вверх, он продает и начинает набирать шорт. К 11 часам уже набрано 10 лотов и фьюч идет дальше. Я вижу, что настроение бычье и где то в 12 часов выключаю робота. Нажимаю Остановить и закрыть позиции.
Фьюч ушел значительно выше. Т.е. робот бы держал в шорте 10 фьючей и накапливал бы убыток. Но я закрыл позу и выключил его.
Перезапустил АД. В районе 16-00 я понимаю, что возможно рынок уйдет в боковик. Запускаю робота а он ничего не делает)
Т.е. по идее он ждет возврата к ценам что были утром???
- evge
- Администратор
- Сообщения: 1812
- Зарегистрирован: 04 фев 2016, 09:46
- Откуда: Млечный путь, планета Земля
- Благодарил (а): 83 раза
- Поблагодарили: 367 раз
- Контактная информация:
Re: Усреднение!
Orange2000 писал(а):Т.е. по идее он ждет возврата к ценам что были утром???
Остановка и запуск того же робота не перезапускает алгоритм.
Он помнит состояние на момент остановки в глоб. переменных.
никогда такого не было и вот опять
-
- Сообщения: 20
- Зарегистрирован: 11 окт 2017, 15:25
- Благодарил (а): 6 раз
Re: Усреднение!
evge писал(а):Тогда вот код ГрааляКод: Выделить всё
/**
**/
function Initialize()
{
StrategyName = "UpAndDown";
AddInput("Input1", Inputs.Candle, 5, true, "GAZP=МБ ЦК");
AddParameter("StartQ", 3000, "Стартовое кол-во", 0);
AddParameter("Q", 300, "Кол-во докупки", 0);
AddParameter("DeltaPercent", 0.4, "% изменения цены для докупки и продажи", 0);
AddGlobalVariable("xPrice", Types.Double, 10000000000.0);
AddGlobalVariable("xPosition", Types.Double, 0.0);
AddGlobalVariable("LastPrice", Types.DoubleList);
AddGlobalVariable("Last", Types.Double, 0);
AddGlobalVariable("MinPrice", Types.Double, 0);
AddGlobalVariable("MaxPrice", Types.Double, 99999999);
AddGlobalVariable("Type", Types.Double, 1);
AddGlobalVariable("N", Types.Int, 1); //направление "1" - Long, "-1" - Short
}
function OnUpdate()
{
// evge 13.04.2019 https://alfadirect4.ru
// модификация стратегии StepByStep от AlfaDirect
// Переворот стратегии Long/Short
if (xPosition !=0 && CurrentPosition() == 0)
{
N =- N;
xPrice = 10000000000.0;
LastPrice.Clear();
xPosition = 0;
MaxPrice = Double.MaxValue;
MinPrice = 0;
}
double pos = CurrentPosition();
// Правило 1. если первый запуск, покупаем StartQ
if ( xPrice == 10000000000.0 && N > 0)
{
if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
{
ShowMessage("StartQ или Q не кратно лоту. Робот остановлен !");
Stop();
}
// Покупка StartQ
if (StartQ > 0)
{
EnterLongLimit(Input1.Close[0]*(1.0 + 0.01*DeltaPercent), StartQ);
}
xPrice = Input1.Close[0];
}
// Правило 1.1 старт для Short, продаем StartQ
if ( xPrice == 10000000000.0 && N < 0)
{
if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
{
ShowMessage("StartQ или Q не кратно лоту. Робот остановлен !");
Stop();
}
// Продажа StartQ
if (StartQ > 0)
{
EnterShortLimit(Input1.Close[0]*(1.0 - 0.01*DeltaPercent), StartQ);
}
xPrice = Input1.Close[0];
}
// Модуль проверки изменение позиции UP
// если позиция выросла, добавляем уровень в список
if (N > 0)
{
if ( pos > xPosition )
{
double a = xPrice;
double b = xPosition;
while (pos - b > 0)
{
LastPrice.Add(a);
a = a*(1.0 + 0.01*DeltaPercent);
b = b + Q;
}
Last = xPrice;
xPosition = pos;
LastPrice.Sort();
}
// если позиция снизилась, убираем уровень из списка
else if ( pos < xPosition && LastPrice.Count >= 1 )
{
LastPrice.Sort();
LastPrice.RemoveAt(0);
Last = xPrice;
xPosition = pos;
}
if ( LastPrice.Count <= 0 )
MinPrice = Last;
else
MinPrice = LastPrice.Min();
}
// Модуль проверки изменение позиции DOWN
// если позиция снизилась, добавляем уровень в список
if (N < 0)
{
if ( pos < xPosition )
{
double a = xPrice;
double b = xPosition;
while (pos - b < 0)
{
LastPrice.Add(a);
a = a*(1.0 - 0.01*DeltaPercent);
b = b - Q;
}
Last = xPrice;
xPosition = pos;
LastPrice.Sort();
LastPrice.Reverse();
}
// если позиция выросла, убираем уровень из списка
else if ( pos > xPosition && LastPrice.Count >= 1 )
{
LastPrice.Sort();
LastPrice.Reverse();
LastPrice.RemoveAt(0);
Last = xPrice;
xPosition = pos;
}
if ( LastPrice.Count <= 0 )
MaxPrice = Last;
else
MaxPrice = LastPrice.Max();
}
//Правило 2. Если цена упала и кол-во меньше допустимого,
// то покупаем и добавляем цену покупки в начало списка
if ( N > 0 && Input1.Close[0] < MinPrice*(1.0 - 0.01*DeltaPercent) && pos + Q <= LongLimit )
{
EnterLongLimit(Input1.Close[0]*(1.0 + 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 2.1. Если цена выросла и кол-во больше допустимого,
// то продаем и добавляем цену продажи в начало списка
if ( N < 0 && Input1.Close[0] > MaxPrice*(1.0 + 0.01*DeltaPercent) && pos - Q >= ShortLimit )
{
EnterShortLimit(Input1.Close[0]*(1.0 - 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 3. Если цена выше цены из начала списка, то продаем и удаляем 0-й элемент списка
if ( N > 0 && Input1.Close[0] >= MinPrice*(1.0 + 0.01*DeltaPercent) && pos > 0 )
{
CloseLongLimit(Input1.Close[0]*(1.0 - 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 3.1. Если цена ниже цены из начала списка, то покупаем и удаляем 0-й элемент списка
if ( N < 0 && Input1.Close[0] <= MaxPrice*(1.0 - 0.01*DeltaPercent) && pos < 0 )
{
CloseShortLimit(Input1.Close[0]*(1.0 + 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
}
Код с параметрами по умолчанию как на графиках по GAZP выше, в тестировании не забывайте установить предельную позицию Long и Short больше стартовой (например, 5000 в обе стороны)
Этот код стартует всегда с Long.
Можно конечно доработать и сделать возможность старта в нужную сторону.
evge, можете сделать так, чтобы открытие первой сделки было не случайным, а по какому-нибудь трендовому индикатору, например, МА?
А в случае смены тренда, происходило закрытие всех позиций по этому трендовому индикатору.
- evge
- Администратор
- Сообщения: 1812
- Зарегистрирован: 04 фев 2016, 09:46
- Откуда: Млечный путь, планета Земля
- Благодарил (а): 83 раза
- Поблагодарили: 367 раз
- Контактная информация:
Re: Усреднение!
оно не случайное, а всегда long. Можно сделать всегда short, если задать N по умолчанию -1
здесь
если конечно надо стартовать можно конечно задать в 0 и вначале проверять на 0 и определять начальное направление.
Не понятно что значит: если МА сменило направление, то закрыть все позиции? т.е. в противоположную сторону вообще не открывать позиции пока не сменится опять в MA в нужную сторону?
здесь
Код: Выделить всё
AddGlobalVariable("N", Types.Int, -1); //направление "1" - Long, "-1" - Short
если конечно надо стартовать можно конечно задать в 0 и вначале проверять на 0 и определять начальное направление.
Не понятно что значит: если МА сменило направление, то закрыть все позиции? т.е. в противоположную сторону вообще не открывать позиции пока не сменится опять в MA в нужную сторону?
никогда такого не было и вот опять
-
- Сообщения: 20
- Зарегистрирован: 11 окт 2017, 15:25
- Благодарил (а): 6 раз
Re: Усреднение!
evge писал(а):оно не случайное, а всегда long. Можно сделать всегда short, если задать N по умолчанию -1
здесьКод: Выделить всё
AddGlobalVariable("N", Types.Int, -1); //направление "1" - Long, "-1" - Short
если конечно надо стартовать можно конечно задать в 0 и вначале проверять на 0 и определять начальное направление.
Не понятно что значит: если МА сменило направление, то закрыть все позиции? т.е. в противоположную сторону вообще не открывать позиции пока не сменится опять в MA в нужную сторону?
Да, верно, открывать противоположную позицию, только когда МА покажет тренд в нужную сторону. То есть можно будет выставить МА с большим периодом, а покупать/продавать на откатах, но при смене тренда, закрывать все позиции.
Торгуем в обе стороны, но по показаниям МА.
- evge
- Администратор
- Сообщения: 1812
- Зарегистрирован: 04 фев 2016, 09:46
- Откуда: Млечный путь, планета Земля
- Благодарил (а): 83 раза
- Поблагодарили: 367 раз
- Контактная информация:
Re: Усреднение!
Будет частая смена направления и переворот позиции, на котором будет больше всего потерь.
Судя по описанию, закрытие всех позиций при смене направления MA в тоже время это и открытие по количеству StartQ в противоположную сторону.
Чуть позже сделаю.
Судя по описанию, закрытие всех позиций при смене направления MA в тоже время это и открытие по количеству StartQ в противоположную сторону.
Чуть позже сделаю.
никогда такого не было и вот опять
- evge
- Администратор
- Сообщения: 1812
- Зарегистрирован: 04 фев 2016, 09:46
- Откуда: Млечный путь, планета Земля
- Благодарил (а): 83 раза
- Поблагодарили: 367 раз
- Контактная информация:
Re: Усреднение!
вот что-то подобное
Код: Выделить всё
function Initialize()
{
StrategyName = "UpAndDownMA";
AddInput("Input1", Inputs.Candle, 5, true, "GAZP=МБ ЦК");
AddParameter("StartQ", 1500, "Стартовое кол-во", 0);
AddParameter("Q", 300, "Кол-во докупки", 0);
AddParameter("DeltaPercent", 0.1, "% изменения цены для докупки и продажи", 0);
AddParameter("SMAper", 99, "MA Period", 0);
AddGlobalVariable("xPrice", Types.Double, 10000000000.0);
AddGlobalVariable("xPosition", Types.Double, 0.0);
AddGlobalVariable("LastPrice", Types.DoubleList);
AddGlobalVariable("Last", Types.Double, 0);
AddGlobalVariable("MinPrice", Types.Double, 0);
AddGlobalVariable("MaxPrice", Types.Double, 99999999);
AddGlobalVariable("Type", Types.Double, 1);
AddGlobalVariable("N", Types.Int, 1); //направление "1" - Long, "-1" - Short
AddChartIndicator("SMA", new Dictionary <string, string>{{"Period", "SMAper"}});
}
function OnUpdate()
{
// evge 13.04.2019 https://alfadirect4.ru
// модификация стратегии StepByStep от AlfaDirect
// evge 06.08.2020 https://alfadirect4.ru
// работа по MA
var CP = CurrentPosition();
var sMA = SMA(Input1, SMAper);
var NN = sMA[0] > sMA[1] ? 1 : sMA[0] < sMA[1] ? - 1 : N;
if (N == 0) N = NN;
// Переворот при смене направления
if (N != NN && CP > 0 && NN < 0) { ClosePosition(); xPosition = 1; N = NN; CP = 0; return; }
if (N != NN && CP < 0 && NN > 0) { ClosePosition(); xPosition = -1; N = NN; CP = 0; return; }
if (xPosition !=0 && CP == 0)
{
//N =- N;
xPrice = 10000000000.0;
LastPrice.Clear();
xPosition = 0;
MaxPrice = Double.MaxValue;
MinPrice = 0;
}
double pos = CurrentPosition();
// Правило 1. если первый запуск, покупаем StartQ
if ( xPrice == 10000000000.0 && N > 0)
{
if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
{
ShowMessage("StartQ или Q не кратно лоту. Робот остановлен !");
Stop();
}
// Покупка StartQ
if (StartQ > 0)
{
EnterLongLimit(Input1.Close[0]*(1.0 + 0.01*DeltaPercent), StartQ);
}
xPrice = Input1.Close[0];
}
// Правило 1.1 старт для Short, продаем StartQ
if ( xPrice == 10000000000.0 && N < 0)
{
if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
{
ShowMessage("StartQ или Q не кратно лоту. Робот остановлен !");
Stop();
}
// Продажа StartQ
if (StartQ > 0)
{
EnterShortLimit(Input1.Close[0]*(1.0 - 0.01*DeltaPercent), StartQ);
}
xPrice = Input1.Close[0];
}
// Модуль проверки изменение позиции UP
// если позиция выросла, добавляем уровень в список
if (N > 0)
{
if ( pos > xPosition )
{
double a = xPrice;
double b = xPosition;
while (pos - b > 0)
{
LastPrice.Add(a);
a = a*(1.0 + 0.01*DeltaPercent);
b = b + Q;
}
Last = xPrice;
xPosition = pos;
LastPrice.Sort();
}
// если позиция снизилась, убираем уровень из списка
else if ( pos < xPosition && LastPrice.Count >= 1 )
{
LastPrice.Sort();
LastPrice.RemoveAt(0);
Last = xPrice;
xPosition = pos;
}
if ( LastPrice.Count <= 0 )
MinPrice = Last;
else
MinPrice = LastPrice.Min();
}
// Модуль проверки изменение позиции DOWN
// если позиция снизилась, добавляем уровень в список
if (N < 0)
{
if ( pos < xPosition )
{
double a = xPrice;
double b = xPosition;
while (pos - b < 0)
{
LastPrice.Add(a);
a = a*(1.0 - 0.01*DeltaPercent);
b = b - Q;
}
Last = xPrice;
xPosition = pos;
LastPrice.Sort();
LastPrice.Reverse();
}
// если позиция выросла, убираем уровень из списка
else if ( pos > xPosition && LastPrice.Count >= 1 )
{
LastPrice.Sort();
LastPrice.Reverse();
LastPrice.RemoveAt(0);
Last = xPrice;
xPosition = pos;
}
if ( LastPrice.Count <= 0 )
MaxPrice = Last;
else
MaxPrice = LastPrice.Max();
}
//Правило 2. Если цена упала и кол-во меньше допустимого,
// то покупаем и добавляем цену покупки в начало списка
if ( N > 0 && Input1.Close[0] < MinPrice*(1.0 - 0.01*DeltaPercent) && pos + Q <= LongLimit )
{
EnterLongLimit(Input1.Close[0]*(1.0 + 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 2.1. Если цена выросла и кол-во больше допустимого,
// то продаем и добавляем цену продажи в начало списка
if ( N < 0 && Input1.Close[0] > MaxPrice*(1.0 + 0.01*DeltaPercent) && pos - Q >= ShortLimit )
{
EnterShortLimit(Input1.Close[0]*(1.0 - 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 3. Если цена выше цены из начала списка, то продаем и удаляем 0-й элемент списка
if ( N > 0 && Input1.Close[0] >= MinPrice*(1.0 + 0.01*DeltaPercent) && pos > 0 )
{
CloseLongLimit(Input1.Close[0]*(1.0 - 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 3.1. Если цена ниже цены из начала списка, то покупаем и удаляем 0-й элемент списка
if ( N < 0 && Input1.Close[0] <= MaxPrice*(1.0 - 0.01*DeltaPercent) && pos < 0 )
{
CloseShortLimit(Input1.Close[0]*(1.0 + 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
}
никогда такого не было и вот опять
-
- Сообщения: 20
- Зарегистрирован: 11 окт 2017, 15:25
- Благодарил (а): 6 раз
Re: Усреднение!
evge писал(а):вот что-то подобноеКод: Выделить всё
function Initialize()
{
StrategyName = "UpAndDownMA";
AddInput("Input1", Inputs.Candle, 5, true, "GAZP=МБ ЦК");
AddParameter("StartQ", 1500, "Стартовое кол-во", 0);
AddParameter("Q", 300, "Кол-во докупки", 0);
AddParameter("DeltaPercent", 0.1, "% изменения цены для докупки и продажи", 0);
AddParameter("SMAper", 99, "MA Period", 0);
AddGlobalVariable("xPrice", Types.Double, 10000000000.0);
AddGlobalVariable("xPosition", Types.Double, 0.0);
AddGlobalVariable("LastPrice", Types.DoubleList);
AddGlobalVariable("Last", Types.Double, 0);
AddGlobalVariable("MinPrice", Types.Double, 0);
AddGlobalVariable("MaxPrice", Types.Double, 99999999);
AddGlobalVariable("Type", Types.Double, 1);
AddGlobalVariable("N", Types.Int, 1); //направление "1" - Long, "-1" - Short
AddChartIndicator("SMA", new Dictionary <string, string>{{"Period", "SMAper"}});
}
function OnUpdate()
{
// evge 13.04.2019 https://alfadirect4.ru
// модификация стратегии StepByStep от AlfaDirect
// evge 06.08.2020 https://alfadirect4.ru
// работа по MA
var CP = CurrentPosition();
var sMA = SMA(Input1, SMAper);
var NN = sMA[0] > sMA[1] ? 1 : sMA[0] < sMA[1] ? - 1 : N;
if (N == 0) N = NN;
// Переворот при смене направления
if (N != NN && CP > 0 && NN < 0) { ClosePosition(); xPosition = 1; N = NN; CP = 0; return; }
if (N != NN && CP < 0 && NN > 0) { ClosePosition(); xPosition = -1; N = NN; CP = 0; return; }
if (xPosition !=0 && CP == 0)
{
//N =- N;
xPrice = 10000000000.0;
LastPrice.Clear();
xPosition = 0;
MaxPrice = Double.MaxValue;
MinPrice = 0;
}
double pos = CurrentPosition();
// Правило 1. если первый запуск, покупаем StartQ
if ( xPrice == 10000000000.0 && N > 0)
{
if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
{
ShowMessage("StartQ или Q не кратно лоту. Робот остановлен !");
Stop();
}
// Покупка StartQ
if (StartQ > 0)
{
EnterLongLimit(Input1.Close[0]*(1.0 + 0.01*DeltaPercent), StartQ);
}
xPrice = Input1.Close[0];
}
// Правило 1.1 старт для Short, продаем StartQ
if ( xPrice == 10000000000.0 && N < 0)
{
if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
{
ShowMessage("StartQ или Q не кратно лоту. Робот остановлен !");
Stop();
}
// Продажа StartQ
if (StartQ > 0)
{
EnterShortLimit(Input1.Close[0]*(1.0 - 0.01*DeltaPercent), StartQ);
}
xPrice = Input1.Close[0];
}
// Модуль проверки изменение позиции UP
// если позиция выросла, добавляем уровень в список
if (N > 0)
{
if ( pos > xPosition )
{
double a = xPrice;
double b = xPosition;
while (pos - b > 0)
{
LastPrice.Add(a);
a = a*(1.0 + 0.01*DeltaPercent);
b = b + Q;
}
Last = xPrice;
xPosition = pos;
LastPrice.Sort();
}
// если позиция снизилась, убираем уровень из списка
else if ( pos < xPosition && LastPrice.Count >= 1 )
{
LastPrice.Sort();
LastPrice.RemoveAt(0);
Last = xPrice;
xPosition = pos;
}
if ( LastPrice.Count <= 0 )
MinPrice = Last;
else
MinPrice = LastPrice.Min();
}
// Модуль проверки изменение позиции DOWN
// если позиция снизилась, добавляем уровень в список
if (N < 0)
{
if ( pos < xPosition )
{
double a = xPrice;
double b = xPosition;
while (pos - b < 0)
{
LastPrice.Add(a);
a = a*(1.0 - 0.01*DeltaPercent);
b = b - Q;
}
Last = xPrice;
xPosition = pos;
LastPrice.Sort();
LastPrice.Reverse();
}
// если позиция выросла, убираем уровень из списка
else if ( pos > xPosition && LastPrice.Count >= 1 )
{
LastPrice.Sort();
LastPrice.Reverse();
LastPrice.RemoveAt(0);
Last = xPrice;
xPosition = pos;
}
if ( LastPrice.Count <= 0 )
MaxPrice = Last;
else
MaxPrice = LastPrice.Max();
}
//Правило 2. Если цена упала и кол-во меньше допустимого,
// то покупаем и добавляем цену покупки в начало списка
if ( N > 0 && Input1.Close[0] < MinPrice*(1.0 - 0.01*DeltaPercent) && pos + Q <= LongLimit )
{
EnterLongLimit(Input1.Close[0]*(1.0 + 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 2.1. Если цена выросла и кол-во больше допустимого,
// то продаем и добавляем цену продажи в начало списка
if ( N < 0 && Input1.Close[0] > MaxPrice*(1.0 + 0.01*DeltaPercent) && pos - Q >= ShortLimit )
{
EnterShortLimit(Input1.Close[0]*(1.0 - 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 3. Если цена выше цены из начала списка, то продаем и удаляем 0-й элемент списка
if ( N > 0 && Input1.Close[0] >= MinPrice*(1.0 + 0.01*DeltaPercent) && pos > 0 )
{
CloseLongLimit(Input1.Close[0]*(1.0 - 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 3.1. Если цена ниже цены из начала списка, то покупаем и удаляем 0-й элемент списка
if ( N < 0 && Input1.Close[0] <= MaxPrice*(1.0 - 0.01*DeltaPercent) && pos < 0 )
{
CloseShortLimit(Input1.Close[0]*(1.0 + 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
}
Спасибо, всё работает отлично, но ещё лучше будет, если закрываться позиции будут при одновременном выполнении двух условий: показания МА о смене тренда и достижение уровня DeltaPercent. Это позволит избежать лишних открытий/закрытий во флэте.
- evge
- Администратор
- Сообщения: 1812
- Зарегистрирован: 04 фев 2016, 09:46
- Откуда: Млечный путь, планета Земля
- Благодарил (а): 83 раза
- Поблагодарили: 367 раз
- Контактная информация:
Re: Усреднение!
Хорошо, ориентируясь на MinPrice и MaxPrice и отклонение цены от них на DeltaPercent
тогда вот так:
тогда вот так:
Код: Выделить всё
function Initialize()
{
StrategyName = "UpAndDownMA";
AddInput("Input1", Inputs.Candle, 5, true, "GAZP=МБ ЦК");
AddParameter("StartQ", 500, "Стартовое кол-во", 0);
AddParameter("Q", 100, "Кол-во докупки", 0);
AddParameter("DeltaPercent", 0.4, "% изменения цены для докупки и продажи", 0);
AddParameter("SMAper", 99, "MA Period", 0);
AddGlobalVariable("xPrice", Types.Double, 10000000000.0);
AddGlobalVariable("xPosition", Types.Double, 0.0);
AddGlobalVariable("LastPrice", Types.DoubleList);
AddGlobalVariable("Last", Types.Double, 0);
AddGlobalVariable("MinPrice", Types.Double, 0);
AddGlobalVariable("MaxPrice", Types.Double, 99999999);
AddGlobalVariable("Type", Types.Double, 1);
AddGlobalVariable("N", Types.Int, 1); //направление "1" - Long, "-1" - Short
AddChartIndicator("SMA", new Dictionary <string, string>{{"Period", "SMAper"}});
}
function OnUpdate()
{
// evge 13.04.2019 https://alfadirect4.ru
// модификация стратегии StepByStep от AlfaDirect
// evge 06.08.2020 https://alfadirect4.ru
// работа по MA + DeltaPercent от MinPrice и MaxPrice
var CP = CurrentPosition();
var sMA = SMA(Input1, SMAper);
var NN = sMA[0] > sMA[1] && Input1.Close[0] > MaxPrice*(1.0 + 0.01*DeltaPercent) ? 1 : sMA[0] < sMA[1] && Input1.Close[0] < MinPrice*(1.0 + 0.01*DeltaPercent) ? - 1 : N;
if (N == 0) N = NN;
// Переворот при смене направления
if (N != NN && CP > 0 && NN < 0) { ClosePosition(); xPosition = 1; N = NN; CP = 0; return; }
if (N != NN && CP < 0 && NN > 0) { ClosePosition(); xPosition = -1; N = NN; CP = 0; return; }
if (xPosition !=0 && CP == 0)
{
//N =- N;
xPrice = 10000000000.0;
LastPrice.Clear();
xPosition = 0;
MaxPrice = Double.MaxValue;
MinPrice = 0;
}
double pos = CurrentPosition();
// Правило 1. если первый запуск, покупаем StartQ
if ( xPrice == 10000000000.0 && N > 0)
{
if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
{
ShowMessage("StartQ или Q не кратно лоту. Робот остановлен !");
Stop();
}
// Покупка StartQ
if (StartQ > 0)
{
EnterLongLimit(Input1.Close[0]*(1.0 + 0.01*DeltaPercent), StartQ);
}
xPrice = Input1.Close[0];
}
// Правило 1.1 старт для Short, продаем StartQ
if ( xPrice == 10000000000.0 && N < 0)
{
if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
{
ShowMessage("StartQ или Q не кратно лоту. Робот остановлен !");
Stop();
}
// Продажа StartQ
if (StartQ > 0)
{
EnterShortLimit(Input1.Close[0]*(1.0 - 0.01*DeltaPercent), StartQ);
}
xPrice = Input1.Close[0];
}
// Модуль проверки изменение позиции UP
// если позиция выросла, добавляем уровень в список
if (N > 0)
{
if ( pos > xPosition )
{
double a = xPrice;
double b = xPosition;
while (pos - b > 0)
{
LastPrice.Add(a);
a = a*(1.0 + 0.01*DeltaPercent);
b = b + Q;
}
Last = xPrice;
xPosition = pos;
LastPrice.Sort();
}
// если позиция снизилась, убираем уровень из списка
else if ( pos < xPosition && LastPrice.Count >= 1 )
{
LastPrice.Sort();
LastPrice.RemoveAt(0);
Last = xPrice;
xPosition = pos;
}
if ( LastPrice.Count <= 0 )
MinPrice = Last;
else
MinPrice = LastPrice.Min();
}
// Модуль проверки изменение позиции DOWN
// если позиция снизилась, добавляем уровень в список
if (N < 0)
{
if ( pos < xPosition )
{
double a = xPrice;
double b = xPosition;
while (pos - b < 0)
{
LastPrice.Add(a);
a = a*(1.0 - 0.01*DeltaPercent);
b = b - Q;
}
Last = xPrice;
xPosition = pos;
LastPrice.Sort();
LastPrice.Reverse();
}
// если позиция выросла, убираем уровень из списка
else if ( pos > xPosition && LastPrice.Count >= 1 )
{
LastPrice.Sort();
LastPrice.Reverse();
LastPrice.RemoveAt(0);
Last = xPrice;
xPosition = pos;
}
if ( LastPrice.Count <= 0 )
MaxPrice = Last;
else
MaxPrice = LastPrice.Max();
}
//Правило 2. Если цена упала и кол-во меньше допустимого,
// то покупаем и добавляем цену покупки в начало списка
if ( N > 0 && Input1.Close[0] < MinPrice*(1.0 - 0.01*DeltaPercent) && pos + Q <= LongLimit )
{
EnterLongLimit(Input1.Close[0]*(1.0 + 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 2.1. Если цена выросла и кол-во больше допустимого,
// то продаем и добавляем цену продажи в начало списка
if ( N < 0 && Input1.Close[0] > MaxPrice*(1.0 + 0.01*DeltaPercent) && pos - Q >= ShortLimit )
{
EnterShortLimit(Input1.Close[0]*(1.0 - 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 3. Если цена выше цены из начала списка, то продаем и удаляем 0-й элемент списка
if ( N > 0 && Input1.Close[0] >= MinPrice*(1.0 + 0.01*DeltaPercent) && pos > 0 )
{
CloseLongLimit(Input1.Close[0]*(1.0 - 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
//Правило 3.1. Если цена ниже цены из начала списка, то покупаем и удаляем 0-й элемент списка
if ( N < 0 && Input1.Close[0] <= MaxPrice*(1.0 - 0.01*DeltaPercent) && pos < 0 )
{
CloseShortLimit(Input1.Close[0]*(1.0 + 0.5*0.01*DeltaPercent), Q);
xPrice = Input1.Close[0];
}
}
никогда такого не было и вот опять
- evge
- Администратор
- Сообщения: 1812
- Зарегистрирован: 04 фев 2016, 09:46
- Откуда: Млечный путь, планета Земля
- Благодарил (а): 83 раза
- Поблагодарили: 367 раз
- Контактная информация:
Re: Усреднение!
но есть вероятность что не перевернется, если цена дальше уйдёт в том же направлении
при тестах это вижу
нужно наверное ориентир другой, не MinPrice и MaxPrice
пример, с января по август 2020, GAZP
с марта и далее уже цена не была выше 210 и переворота не случилось
при тестах это вижу
нужно наверное ориентир другой, не MinPrice и MaxPrice
пример, с января по август 2020, GAZP
с марта и далее уже цена не была выше 210 и переворота не случилось
никогда такого не было и вот опять
Вернуться в «Стратегии и роботы»
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 5 гостей