Стратегии и роботы > StepByStep (q start) старт по заданной цене

Обсуждение, описание стратегий и роботов, идеи для стратегий
ip851874
Сообщения: 41
Зарегистрирован: 21 ноя 2020, 22:56
Благодарил (а): 12 раз

StepByStep (q start) старт по заданной цене

Непрочитанное сообщение ip851874 » 20 фев 2022, 02:08

Помогите реализовать задачу по старту от нужного уровня цены-отложенный запуск робота.

Аватара пользователя
evge
Администратор
Сообщения: 1807
Зарегистрирован: 04 фев 2016, 09:46
Откуда: Млечный путь, планета Земля
Благодарил (а): 83 раза
Поблагодарили: 363 раза
Контактная информация:

Re: StepByStep (q start) старт по заданной цене

Непрочитанное сообщение evge » 20 фев 2022, 02:47

Недавно была тема здесь: Отложенный старт стратегии по достижении цены

Добавлен параметр 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;
}

никогда такого не было и вот опять

ip851874
Сообщения: 41
Зарегистрирован: 21 ноя 2020, 22:56
Благодарил (а): 12 раз

Re: StepByStep (q start) старт по заданной цене

Непрочитанное сообщение ip851874 » 20 фев 2022, 14:15

Спасибо! Пропустил видимо этот момент.

Leonid_1234
Сообщения: 3
Зарегистрирован: 20 дек 2022, 15:16
Поблагодарили: 1 раз

Re: StepByStep (q start) старт по заданной цене

Непрочитанное сообщение Leonid_1234 » 02 мар 2023, 16:50

Добрый день! подскажи, пожалуйста, был ли где-нибудь код на Step By Step для шорта? если нет, то можно его организовать?) заранее спасибо.

_E_V_N_
Сообщения: 24
Зарегистрирован: 14 ноя 2022, 20:22
Поблагодарили: 3 раза

Re: StepByStep (q start) старт по заданной цене

Непрочитанное сообщение _E_V_N_ » 03 мар 2023, 18:41

Код для переворота в шорт из лонга был тут, правда это не совсем Степ бай Степ, но принцип тот же был.
А в принципе шортовый Степ бай Степ и самому сделать не проблема.


Вернуться в «Стратегии и роботы»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 12 гостей