Стратегии и роботы > StepByStep (q start) старт по заданной цене
- ip851874
- Сообщения: 41
- Зарегистрирован: 21 ноя 2020, 22:56
- Откуда: Москва
- Благодарил (а): 14 раз
- Контактная информация:
StepByStep (q start) старт по заданной цене
Помогите реализовать задачу по старту от нужного уровня цены-отложенный запуск робота.
- evge
- Администратор
- Сообщения: 1813
- Зарегистрирован: 04 фев 2016, 09:46
- Откуда: Млечный путь, планета Земля
- Благодарил (а): 83 раза
- Поблагодарили: 369 раз
- Контактная информация:
Re: StepByStep (q start) старт по заданной цене
Недавно была тема здесь: Отложенный старт стратегии по достижении цены
Добавлен параметр OnPrice
Если цена закрытия бара пересечет указанную в OnPrice цену, то робот (стратегия) стартует.
Добавлен параметр OnPrice
Если цена закрытия бара пересечет указанную в OnPrice цену, то робот (стратегия) стартует.
Код: Выделить всё
function Initialize()
{
StrategyName = "StepByStep_WithStartPrice";
AddInput("Input1", Inputs.Candle, 5, true, "GAZP=МБ ЦК");
AddParameter("OnPrice", 300, "Стартовая цена (начать торговлю при пересечении цены)", 0);
AddParameter("StartQ", 100, "Стартовое кол-во", 0);
AddParameter("Q", 10, "Кол-во докупки", 0);
AddParameter("DeltaPercent", 1, "% изменения цены для докупки и продажи", 0);
AddGlobalVariable("Started", Types.Boolean, false);
AddGlobalVariable("inited", Types.Boolean, false);
AddGlobalVariable("lastSignalId", Types.Int, 0);
AddGlobalVariable("lastSignalProcessed", Types.Int, 0);
AddGlobalVariable("xPosition", Types.Double, 0.0);
AddGlobalVariable("LastPrice", Types.DoubleDictionary);
AddGlobalVariable("LastPriceCount", Types.Int, 0);
AddGlobalVariable("LongLimitStart", Types.Double, 0);
AddGlobalVariable("StartPrice", Types.Double, 0);
AddGlobalVariable("Last", Types.Double, 0);
AddGlobalVariable("MinPrice", Types.Double, 0);
AddGlobalVariable("Type", Types.Double, 1);
AddChartIndicator("MY.str_Invest_Grid", new Dictionary <string, string>{{"Price", "MinPrice"},{"PL", "DeltaPercent"},{"Delta", "DeltaPercent"}, {"Type", "Type"}});
}
function OnUpdate()
{
// evge 20.02.2022 https://alfadirect4.ru
var I = Input1;
if (!Started)
if ( (I.Close[0] < OnPrice && I.Close[1] >= OnPrice) || (I.Close[0] > OnPrice && I.Close[1] <= OnPrice) ) Started = true;
if (!Started) return;
if(StartPrice == 0)
StartPrice = Input1.Close[0];
double pos = CurrentPosition();
var signal = GetSignalInfo(lastSignalId);
var activeOrder = GetActiveOrders().FirstOrDefault(ao => ao.SignalId == lastSignalId);
// StartQ - позиция робота при старте
// Правило 1. если первый запуск и робот не проинициализирован, покупаем StartQ
if (pos < StartQ && !inited)
{
if ( (Q%LotSize() != 0) || (StartQ%LotSize() != 0) )
{
ShowMessage("StartQ или Q не кратно лоту.Робот остановлен!");
Stop();
}
if(LongLimitStart == 0)
{
LongLimitStart = LongLimit;
SetLongLimit(StartQ);
}
// Покупка StartQ
if (StartQ > 0)
{
EnterLongLimit(Input1.Close[0]*(1.0 + 0.01 * OrderSlippage));
var lastSignal = GetLastSignalInfo();
if(lastSignal != null)
{
lastSignalId = lastSignal.SignalID;
lastSignalProcessed = 0;
}
return;
}
}
var lastPriceSorted = new SortedList<double, double>(LastPrice);
if(pos >= StartQ && !inited)
{
inited = true;
if(LongLimitStart != 0)
SetLongLimit(LongLimitStart);
var signals = GetSignalInfo(SignalType.Open, (int)pos);
var initSum = signals.Where(s => s.ActionSuperType == AvailableActions.Initialization).Sum(s => s.OperationExecuted * Input.Close[0]);
var boughtSum = signals.Where(s => s.ActionSuperType != AvailableActions.Initialization).Sum(s => s.OperationExecuted * s.PriceOfTrade);
var avpStart = (initSum + boughtSum) / (pos);
var avp = avpStart;
double b = xPosition;
while (pos - b > 0)
{
lastPriceSorted.Add(avp, Math.Min(Q, pos - b));
avp += avpStart * 0.01* DeltaPercent;
b = b + Q;
}
xPosition = pos;
}
if(!inited)
{
CancelActiveOrders(true);
return;
}
if(activeOrder != null && activeOrder.IsStatusFilled && pos == xPosition)
{
return;//ждём сделки
}
//корректировка уровней
if(pos > xPosition)//позиция увеличилась
{
if(!lastPriceSorted.ContainsKey(signal.PriceOfTrade))
lastPriceSorted.Add(signal.PriceOfTrade, signal.OperationExecuted - lastSignalProcessed);
else
lastPriceSorted[signal.PriceOfTrade] += (signal.OperationExecuted - lastSignalProcessed);
lastSignalProcessed = signal.OperationExecuted;
}
else if(pos < xPosition && lastPriceSorted.Count >= 1)
{
var b = xPosition;
while(b > pos)
{
if(lastPriceSorted.Count == 0) break;
var firstKey = lastPriceSorted.First().Key;
if(b - pos<lastPriceSorted[firstKey])
{
lastPriceSorted[firstKey] -= (b - pos);//Исполнили часть уровня
b -= (b - pos);
}
else
{
b -= lastPriceSorted[firstKey];//Исполнили весь уровень
lastPriceSorted.Remove(firstKey);
}
}
}
xPosition = pos;//позиция учтена выше
var lastSignalFilled = GetLastSignalInfo();
if(lastPriceSorted.Count <= 0)
{
MinPrice = lastSignalFilled != null ? lastSignalFilled.PriceOfTrade : StartPrice;
}
else
{
MinPrice = lastPriceSorted.First().Key;
}
//Правило 2. Если цена упала и кол-во меньше допустимого,
// то покупаем и добавляем цену покупки в начало списка
if (Input1.Close[0] <= MinPrice* (1.0 - 0.01 * DeltaPercent) && pos + Q <= LongLimit )
{
if(activeOrder != null && !activeOrder.IsStatusTerminal)
{
if(activeOrder.OrderDirection != OrderDirection.Buy)
CancelActiveOrders(true);
return;//ждём исполнения уже выставленной заявки
}
EnterLongLimit(MinPrice* (1.0 - 0.01 * (DeltaPercent - OrderSlippage)), Q);
var lastSignal = GetLastSignalInfo();
if(lastSignal != null)
{
lastSignalId = lastSignal.SignalID;
lastSignalProcessed = 0;
}
}
//Правило 3. Если цена выше цены из начала списка, то продаем и удаляем 0-й элемент списка
if (Input1.Close[0] >= MinPrice* (1.0 + 0.01 * DeltaPercent) && pos > 0 )
{
if(activeOrder != null && !activeOrder.IsStatusTerminal)
{
if(activeOrder.OrderDirection != OrderDirection.Sell)
CancelActiveOrders(true);
return;//ждём исполнения уже выставленной заявки
}
var vSell = (int)lastPriceSorted.First().Value;
CloseLongLimit(MinPrice* (1.0 + 0.01 * (DeltaPercent - OrderSlippage)), vSell);
var lastSignal = GetLastSignalInfo();
if(lastSignal != null)
{
lastSignalId = lastSignal.SignalID;
lastSignalProcessed = 0;
}
}
LastPrice = new Dictionary<double, double>(lastPriceSorted);
LastPriceCount = LastPrice.Count;
}
никогда такого не было и вот опять
-
- Сообщения: 4
- Зарегистрирован: 20 дек 2022, 15:16
- Поблагодарили: 1 раз
Re: StepByStep (q start) старт по заданной цене
Добрый день! подскажи, пожалуйста, был ли где-нибудь код на Step By Step для шорта? если нет, то можно его организовать?) заранее спасибо.
Re: StepByStep (q start) старт по заданной цене
Код для переворота в шорт из лонга был тут, правда это не совсем Степ бай Степ, но принцип тот же был.
А в принципе шортовый Степ бай Степ и самому сделать не проблема.
А в принципе шортовый Степ бай Степ и самому сделать не проблема.
Re: StepByStep (q start) старт по заданной цене
Здравствуйте, Вы очень хорошо разбираетесь в программировании. Вот скажите, можно ли создать сеточного робота с простым алгоритмом. Покупаем по заданной цене StartQ лимитной заявкой, потом выставляем лимитные ордера на продажу с заданной дельтой в количестве StartQ/Q и лимитные ордера на покупку с той-же дельтой и в том-же количестве. и так дальше по сетке. Зачем ждать закрытия бара? Будет уже четко ясно по какой цене совершается покупка, по какой продажа. Если выдет из диапазона цен остановиться и будет ждать когда цена придет в диапазон. пользователь будет периодически следить за ним. ну и чтоб была возможность увеличивать Q и расширять диапазон путем добавления денег.
Re: StepByStep (q start) старт по заданной цене
Я не силен в программировании, но давно тут почитывал. Поэтому рискну ответить.
Тут скорее дело не в программировании, а в ограничениях платформы, которая не дает возможности роботу! выставить больше одного торгового ордера (не считая Стоплосс и Тейкпофит). Что конечно же сильно ограничивает возможности стратегии, именно по этой причине в данном коде "конское" проскальзывание, нет возможности на быстром рынке докупиться на следующей ступеньке если предыдущий ордер исполнился не полностью (ожидается полное исполнение), есть проверка на неисполненный предыдущий ордер противоположного направления, который необходимо удалить, чтобы иметь возможность совершить сделку на следующей ступеньке, и т.д.
Если бы не эти ограничения, то даже я с самым начальным уровнем, запрограммировал ваш вариант )
Тут скорее дело не в программировании, а в ограничениях платформы, которая не дает возможности роботу! выставить больше одного торгового ордера (не считая Стоплосс и Тейкпофит). Что конечно же сильно ограничивает возможности стратегии, именно по этой причине в данном коде "конское" проскальзывание, нет возможности на быстром рынке докупиться на следующей ступеньке если предыдущий ордер исполнился не полностью (ожидается полное исполнение), есть проверка на неисполненный предыдущий ордер противоположного направления, который необходимо удалить, чтобы иметь возможность совершить сделку на следующей ступеньке, и т.д.
Если бы не эти ограничения, то даже я с самым начальным уровнем, запрограммировал ваш вариант )
Вернуться в «Стратегии и роботы»
Кто сейчас на конференции
Сейчас этот форум просматривают: Google [Bot] и 11 гостей