Спасибо . А подскажите как найти цену открытия первого ордера из нескольких открытых . Именно первого ордера!!!
Обучение языку MQL4 под MetaTrader 4📌
От xbms, 13 апреля, 2013 в Уголок Программиста
Нужно в цикле найти 1 ордер по времени открытия или тикету и взять его цену.как найти цену открытия первого ордера из нескольких открытых
Если упрощённо, то OrderSelect( 0, SELECT_BY_POS, MODE_TRADES) - даст Вам 1 ордер
подсмотрел во всякие чужие совы и модули, написал открытие ордеров с отработкой ошибок, так как в тестере нет возможности получить ошибку, решил спросить у специалистов и знатоков:
вот такой вариант имеет право на жизнь?
что сделано вкратце:
1. Ошибки аля нет цены и так далее - повтор попытки открыть ордер через паузу
2. ошибки типа сервер занят и так далее - повтор попытки через паузу
3. модификация ордера (установка тейка и стопа) - проверка, если не удалось - повтор через паузу
4. критические ошибки не обрабатываются. не нашел в справке как вообще тормознуть сову (особо правда и не искал)
Заранее спасибо за критику.
void OpenOrder(int ord_type)
{
modify=false;
int NumberOfTry=100;
if(usemm==true) // если используем манименеджмент
{
lotmm=((AccountBalance()-balstart)/shagmm);
Lots=Lots+lotnax*lotmm;
}
// конец блока использования манименеджмента
for(int i=1; i {
if(ord_type==OP_SELL)
{
order_color=Red;
orderprice=Bid;
ordertype=OP_SELL;
if(TakeProfit else TP=orderprice-TakeProfit*Point;
if(StopLoss!=0)SL=orderprice+StopLoss*Point;
}
if(ord_type==OP_BUY)
{
order_color=Blue;
orderprice=Ask;
ordertype=OP_BUY;
if(TakeProfit else TP=orderprice+TakeProfit*Point;
if(StopLoss!=0)SL=orderprice-StopLoss*Point;
}
if(MarketInfo(NULL,MODE_SPREAD) else
{
Sleep(1000*2);
continue;
}
if(ticket>-1)
{
while(modify==false)
{
modify=OrderModify(ticket,orderprice,SL,TP,0,order_color);
if(modify==false) Sleep(1000*5);
}
break;
}
else
{
int err=GetLastError();
if(err==4 || err==137 || err==141 || err==8 || err==146) // сервер занят и т.д.
{
Sleep(1000*5);
continue;
}
if(err==129 || err==135 || err==136 || err==138) // Неправильная цена, Цена изменилась, Нет цен, Новые цены
{
Sleep(1000*2);
continue;
}
}
}
SL=0;
TP=0;
Lots=Lotsst;
ordertype=-1;
ticket=-1;
}
Подскажите а так правильно найти первый открытый ордер :
double FindPrice_1(int otype)
{
int ticket_1;
double openprice_1 = 0;
ticket = 0;
for(int cnt = OrdersTotal() -1; cnt >= 0; cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == otype)
{
ticket_1 =OrderTicket();
if(ticket_1 {
ticket = ticket_1;
openprice_1 = OrderOpenPrice();
}
}
}
}
return(openprice_1);
Изменено 5 апреля, 2018 пользователем 0ll
double FindPrice_1(int otype)
{
int ticket_1 = -1;
double openprice_1 = 0;
for(int cnt = OrdersTotal() -1; cnt >= 0; cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == otype)
{
if ( ticket_1 {
ticket_1 = OrderTicket() ;
openprice_1 = OrderOpenPrice();
}
}
}
}
return(openprice_1);
djnet есть некоторые замечания:
- в блок открытия ордера и обработки ошибок, я бы не вставлял расчёт лота - ММ может измениться.
- расчёт уровней СЛ и ТП нужно сделать после успешного открытия ордера - цена может уйти, проскальзывание. чистый STOPLEVEL тоже использовать нельзя по этой-же причине. Лучше назначить минимально возможную дистанцию - например 5*спрэд.
- при отсутствии коннекта, кроме слипа, проверять коннект.
- при отсутствии цены, кроме слипа, проверять приход новой цены, прежде чем пробовать отсылать ордер.
Изменено 5 апреля, 2018 пользователем 0ll
Цитата
djnet есть некоторые замечания:
- в блок открытия ордера и обработки ошибок, я бы не вставлял расчёт лота - ММ может измениться.
- расчёт уровней СЛ и ТП нужно сделать после успешного открытия ордера - цена может уйти, проскальзывание. чистый STOPLEVEL тоже использовать нельзя по этой-же причине. Лучше назначить минимально возможную дистанцию - например 5*спрэд.
- при отсутствии коннекта, кроме слипа, проверять коннект.
- при отсутствии цены, кроме слипа, проверять приход новой цены, прежде чем пробовать отсылать ордер.
Спасибо, ща еще поколдую.
Добавлено: 05-04-2018 12:59:20
- при отсутствии коннекта, кроме слипа, проверять коннект.
с этим понял, тут через функцию IsConnected
при отсутствии цены, кроме слипа, проверять приход новой цены, прежде чем пробовать отсылать ордер.
а вот с этим у меня вопрос либо через MarketInfo() сравнивать время последней котировки, но тики могут и несколько раз в секунду приходить, либо там же сравнивать биды и аски с предыдущим значением, но опять же можно напороться что пролетело два тика (или больше) один вверх, другой вниз, и в итоге цена не изменилась, а тики прошли. либо через SymbolInfoTick..... вообщем ай нид хелп....
Изменено 5 апреля, 2018 пользователем djnet
А как быть со строкой : OrderSelect( 0, SELECT_BY_POS, MODE_TRADES) - даст Вам 1 ордер
Добавлено: 05-04-2018 13:32:20
oll , если не трудно , можете объяснить разницу между моим примером и вашим кодом .
Изменено 5 апреля, 2018 пользователем Roman 13
while(!RefreshRates()) Sleep(16); // Читайте о функции RefreshRatesа вот с этим у меня вопрос либо через MarketInfo()
Roman 13 Ваш код лучше для реальной торговли, когда на счёте могут работать несколько экспертов или используются несколько валютных пар.
Данная строка "OrderSelect( 0, SELECT_BY_POS, MODE_TRADES)" корректно работает только в тестере
:)) Спасибо, ещё раз порадовал.просто берут пакет надежных сов
Почему сова даёт только 5%, ведь можно увеличить нагрузку на депо и будет 10% (например)? Ответ - нагружать депо опасно, значит "надёжная" сова даёт 5% при риске не менее 30%, 70% оставляют для запаса прочности.
Теперь представь: возникает ситуация на рынке и сова уходит в просадку на 50%, которой в тестере не видел - Ваши действия? - 1. закрыть убыток и начать заново, 2. продолжить торговлю до полного слива.
Что выберете? и это на одной паре! а если их больше?
Тут можно книгу писать, одно ясно - "просто" не получится...
))) ну в таком случае мне кажется диверсификация наше все! Типа на одном просадка, зато на другом все чики-пуки! А в этом тесте я выберу ответ № 2, несмотря на то, что уже сливал 2 депозита(((( в надежде, что великая удача придет ко мне ^:)^
Добавлено: 07-04-2018 01:07:35
Друзья, подскажите пожалуста в каком направлении искать-копать, если не срабатывает функция модификации ордера? Благодарю заранее!
ticket = OrderSend(Symbol(),OP_SELL,llot,Bid,Slippage,0,0,"",Magic,0,Red);
if (ticket>=0)
{
if(!OrderSelect(ticket,SELECT_BY_TICKET)) return;
sl=NormalizeDouble( OrderOpenPrice() + Stopl *Point,Digits);
tp=NormalizeDouble( OrderOpenPrice() - Profit*Point,Digits);
if(!OrderModify( ticket, OrderOpenPrice(), sl, tp, 0 ) )
Print("Ошибка модификации ордера на продажу");
}
else Print("Ошибка открытия ордера на продажу");
return;
Изменено 7 апреля, 2018 пользователем Serhoo
Serhoo не сработала функция модификации - в журнале ошибки есть?
2018.04.07 14:34:54.761 2017.04.03 04:15:25 Бот+Иши EURUSD.e,M5: Ошибка модификации ордера на продажу
2018.04.07 14:34:54.761 2017.04.03 04:15:25 Бот+Иши EURUSD.e,M5: OrderModify error 130
Ну вот - разбирайся, это чистая ошибка в коде. Там где у Вас принт об ошибке модификации сделайте дополнительно вывод данных: тип ордера, текущая цена, СЛ или/и ТП - в журнале будет больше инфы.OrderModify error 130
if(CountSell()==0 && Bid {
ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "Sloper", Magic, 0, Red);
if (ticket > 0)
{
SL = NormalizeDouble(Bid + StopLoss*Point, Digits);
TP = NormalizeDouble(Bid - TakeProfit*Point, Digits);
if (OrderSelect(ticket, SELECT_BY_TICKET))
if(!OrderModify(ticket, OrderOpenPrice(), SL, TP, 0))
Print("Ошибка на продажу");
LastTradeSignal = OP_SELL;
}
}
if(CountBuy()==0 && Ask > SD163 && BuySignal()==true && LastTradeSignal != OP_BUY && Close[1] > SD163 )
{
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "Sloper", Magic, 0, Blue);
if (ticket>0)
{
TP = NormalizeDouble(Ask + TakeProfit*Point, Digits);
SL = NormalizeDouble(Ask - StopLoss*Point, Digits);
if (OrderSelect(ticket, SELECT_BY_TICKET))
if(!OrderModify(ticket, OrderOpenPrice(), SL, TP, 0))
Print("Ошибка на покупку");
LastTradeSignal = OP_BUY;
}
}
//условия обратного сигнала
if(z==true)
{
if ( CountSell()>0 && Ask > SD163 && BuySignal()==true && Close[1] > SD163)
{
for(int i = OrdersTotal() -1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderMagicNumber() == Magic && OrderType() == OP_SELL )
if(!OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Black))
Print("Ошибка");
}
}
}
if ( CountBuy()>0 && Bid {
for(int i = OrdersTotal() -1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderMagicNumber() == Magic && OrderType() == OP_BUY)
if(!OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Black))
Print("Ошибка");
}
}
}
}
Добрый день, подскажите пожалуйста почему не действует обратный сигнал?Открывает и сел и бай?
Добавлено: 10-04-2018 06:23:20
Все решилось само собой)) после правки кода, обязательно перезагружайте платформу.....(а то мозг можно сломать))))
Изменено 10 апреля, 2018 пользователем d1w4m3
Коллеги, подскажите, как прописать равенство цены ключевым уровням (например, 1.2, 1.2500, 1.3 и т.д.) ?
Заранее спасибо откликнувшимся.
допустим Вас интересуют уровни с 3 нулями для 5 знаковой котировки. В любом месте графика будет 2 уровня - верхний и нижний
double lvlUp, lvlDown, mn;
mn = MathPow(10, (_Digits - count0)); // count0 - сколько нулей хотите получить
lvlDown = (int)(Bid * mn);
lvlUp = lvlDown + 1;
lvlDown /= mn;
lvlUp /= mn;
далее ждёте когда цена придёт на уровень: if ( Bid == lvlUp ) - пришла на верхний
mFox а что именно не понятно? как вычислить "круглый" уровень?
допустим Вас интересуют уровни с 3 нулями для 5 знаковой котировки. В любом месте графика будет 2 уровня - верхний и нижний
double lvlUp, lvlDown, mn;
Уровни считает верно, но сделки при достижении уровня не открывает. Я так понимаю, причина в том, что при достижении Bid ранее посчитанных круглых уровней, они моментально пересчитываются до следующих круглых значений.
Ребята подскажите пожалуйста, почему индикатор не удаляет созданные им текстовые объекты. Что я делаю не так?
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
double downArrow[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexStyle(0,DRAW_ARROW, EMPTY);
SetIndexArrow(0,234);
SetIndexBuffer(0, downArrow);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
int deinit()
{
ObjectsDeleteAll(0,OBJ_TEXT);
ObjectsDeleteAll();
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int shift, shift1,shift2, shift3;
double Range, AvgRange;
int counter ;
int setPattern = 0;
int alert = 0;
int countedBars=IndicatorCounted(), limit;
if(countedBars>0)countedBars--;
limit = Bars-countedBars;
for (shift = 0; shift shift1 = shift + 1;
shift2 = shift + 2;
shift3 = shift + 3;
Range=0;
AvgRange=0;
for (counter=shift ;counter AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
}
Range=AvgRange/10;
if(((High[shift2]-Low[shift2])>3*(Open[shift2]-Close[shift2]))&&((High[shift2]-Close[shift2])/(0.001+High[shift2]-Low[shift2])>0.6)
&&((High[shift2]-Open[shift2])/(0.001+High[shift2]-Low[shift2])>0.6))
//выводим
{
ObjectCreate( "Shooting Star"+IntegerToString(shift),OBJ_TEXT, 0, Time[shift2], Low[shift2] - 0.5 *Range);
ObjectSetText("Shooting Star"+IntegerToString(shift),"Падающая звезда№1", 9, "Times New Roman", Red);
downArrow[shift2] = Low[shift2] - 0.1*Range;
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
Изменено 19 апреля, 2018 пользователем 0ll
Не знаю... у меня этот скрипт удалил всё:Что я делаю не так?
void OnStart() { ObjectsDeleteAll(); }
В том то и оно, скрипт удаляет. А инидикатор нет. Что не так? По идее, при удалении инидикатора он должен удалить все:
Не знаю... у меня этот скрипт удалил всё:Что я делаю не так?
void OnStart() { ObjectsDeleteAll(); }
int deinit()
{
ObjectsDeleteAll(0,OBJ_TEXT);
ObjectsDeleteAll();
return(0);
А текстовые метки остаются, ну если отдельно запустить скрипт, он удаляет все. Что не очень удобно.
Попробуйте тек: ObjectsDeleteAll(0,"Shooting Star");
если не поможет, то по-старинке:
void Object_Delete_ByPrefix(string sPrefix)
{
int L = StringLen(sPrefix);
for (int i = ObjectsTotal() - 1; i >= 0; i--)
if(StringSubstr(ObjectName(i), 0, L) == sPrefix) ObjectDelete(ObjectName(i));
}
если и это не поможет, то сдаюсь...
Ошибки Array out of range нужно исправить, тогда будет удаляться.
Здравствуйте Господа! Выложите кто нибудь индикатор TMA тот, что в уроке №3.
if ( Ask if ( Bid >= PriceHigh && CountSell() == 0 ) 'CountSell' - function not defined
int CountBuy() 'CountBuy' - function can be declared only in the global scope
int CountSell() 'CountSell' - function can be declared only in the global scope
Объясните господа программисты в чём ошибка где "косяк?
Для публикации сообщений создайте учётную запись или авторизуйтесь
Перейти к списку тем