Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 722
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Доброе время суток,
Вопрос:
Подскажите пожалуйста, почему я не могу поставить отложенник на бай:
request.price =SymbolInfoDouble(Symbol(),SYMBOL_ASK)+(offset)*point;
при offset=1 выпадает ошибка:
failed buy stop 0.10 AUDNZD.m at 1.03748 [Invalid price], т.е.маленький уровень цены (в моем случае)
Когда же при постановки сразу за ним же «ордера по исполнению»
request.price = SymbolInfoDouble(Symbol(), SYMBOL_ASK)
все нормально отрабатывает (т.е. ордер ставится):
order performed buy 0.10 at 1.03747 [#2 buy 0.10 AUDNZD.m at 1.03747]
Почему не принимается запрос по отложенному ордеру (1.03748), т.е. при 1.03747 – ставится, а при 1.03748 – маленькое значение? (ведь SYMBOL_ASK учитавает спред, а offset - отступ от текущей цены для установки ордера, в пунктах, увеличен на 1)
Но при offset=100: ордер отложенный BUY_STOP price = 1.03847 – уже работает
Спасибо.Доброе время суток,
Вопрос:
Подскажите пожалуйста, почему я не могу поставить отложенник на бай:
request.price =SymbolInfoDouble(Symbol(),SYMBOL_ASK)+(offset)*point;
при offset=1 выпадает ошибка:
failed buy stop 0.10 AUDNZD.m at 1.03748 [Invalid price], т.е.маленький уровень цены (в моем случае)
Когда же при постановки сразу за ним же «ордера по исполнению»
request.price = SymbolInfoDouble(Symbol(), SYMBOL_ASK)
все нормально отрабатывает (т.е. ордер ставится):
order performed buy 0.10 at 1.03747 [#2 buy 0.10 AUDNZD.m at 1.03747]
Почему не принимается запрос по отложенному ордеру (1.03748), т.е. при 1.03747 – ставится, а при 1.03748 – маленькое значение?
Но при offset=100: ордер отложенный BUY_STOP price = 1.03847 – уже работает
Спасибо.Вы же сами и ответили на свой вопрос.
Есть такой параметр stoplevel -- минимально необходимое расстояние от текущей цены до цены установки отложенного ордера -- для каждого инструмента своё значение и задаётся в торговых условиях
Вы же сами и ответили на свой вопрос.
Есть такой параметр stoplevel -- минимально необходимое расстояние от текущей цены до цены установки отложенного ордера -- для каждого инструмента своё значение и задаётся в торговых условиях
Тогда наверняка справедлива будет запись:
price =SymbolInfoDouble(Symbol(),SYMBOL_ASK)+SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL)*point
хотя, если вы написали "...от текущей цены", то причем тут спред? Который входит в SYMBOL_ASK (ведь SYMBOL_ASK = цена открытия+спред).
Я прикрепил пример, который поможет Вам...
Понятно, пример помог. Спасибо.
Теперь такой вопрос.
При увеличении лота в какой-то момент чуть не хватает свободных средств, а открыть нужно увеличенным лотом.
То есть, войти максимальным лотом, сколько позволяет FreeMargin.
Как записать такое условие: если для открытия позиции расчетным лотом недостаточно средств, то функция должна вернуть максимально возможный лот для открытия позиции.
{
double Lot=FirstLot;
if(DoublingCount<=0) return Lot;
double MaxLot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
double MainLot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
if(Lot<MainLot)Lot=MainLot;
if(Lot>MaxLot)Lot=MaxLot;
double lt1=Lot;
HistorySelect(0,TimeCurrent());
if(HistoryOrdersTotal()==0)return(Lot);
double cl=HistoryOrderGetDouble(HistoryOrderGetTicket(HistoryOrdersTotal()-1),ORDER_PRICE_OPEN);
double op=HistoryOrderGetDouble(HistoryOrderGetTicket(HistoryOrdersTotal()-2),ORDER_PRICE_OPEN);
long typeor=HistoryOrderGetInteger(HistoryOrderGetTicket(HistoryOrdersTotal()-2),ORDER_TYPE);
if(typeor==ORDER_TYPE_BUY)
{
if(op>cl)
{
if(ud<DoublingCount)
{
lt1=HistoryOrderGetDouble(HistoryOrderGetTicket(HistoryOrdersTotal()-2),ORDER_VOLUME_INITIAL)*_C_;
ud++;
}
else ud=0;
}
else ud=0;
}
if(typeor==ORDER_TYPE_SELL)
{
if(cl>op)
{
if(ud<DoublingCount)
{
lt1=HistoryOrderGetDouble(HistoryOrderGetTicket(HistoryOrdersTotal()-2),ORDER_VOLUME_INITIAL)*_C_;
ud++;
}
else ud=0;
}
else ud=0;
}
if(lt1>MaxLot)lt1=MaxLot;
lt1=LotCheck(lt1);
return(lt1);
}
//+------------------------------------------------------------------+}
Понятно, пример помог. Спасибо.
Теперь такой вопрос.
При увеличении лота в какой-то момент чуть не хватает свободных средств, а открыть нужно увеличенным лотом.
То есть, войти максимальным лотом, сколько позволяет FreeMargin.
Как записать такое условие: если для открытия позиции расчетным лотом недостаточно средств, то функция должна вернуть максимально возможный лот для открытия позиции.
double Mgn,Lot=0,BID,ASK;
BID=SymbolInfoDouble(_Symbol,SYMBOL_BID);
ASK=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
if(OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1,ASK,Mgn)==true)Lot=AccountInfoDouble(ACCOUNT_MARGIN_FREE)/Mgn;
if(OrderCalcMargin(ORDER_TYPE_SELL,_Symbol,1,BID,Mgn)==true)Lot=AccountInfoDouble(ACCOUNT_MARGIN_FREE)/Mgn;
Марина, может быть так?
Два варианта расчета применяете - один для открытия SELL, а другой - для открытия BUY
if(OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1,ASK,Mgn)==true)Lot=AccountInfoDouble(ACCOUNT_MARGIN_FREE)/Mgn;
if(OrderCalcMargin(ORDER_TYPE_SELL,_Symbol,1,BID,Mgn)==true)Lot=AccountInfoDouble(ACCOUNT_MARGIN_FREE)/Mgn;
Не, не так.
Нужно не просто вычислить максимально возможный лот, но и проверить всё это дело на минимально допустимый, потому как может произойти ситуация, что минимальный лот 0.01, а маржа позволяет открыть только 0.009, тогда замучаете сервер запросами, которые никогда не примут, а вот меры на вас могут и принять)
Не, не так.
Нужно не просто вычислить максимально возможный лот, но и проверить всё это дело на минимально допустимый, потому как может произойти ситуация, что минимальный лот 0.01, а маржа позволяет открыть только 0.009, тогда замучаете сервер запросами, которые никогда не примут, а вот меры на вас могут и принять)
Напишите полный код, как должно быть, ну и я посмотрю заодним....?
Я теперь всегда буду учиться у Вас и посматривать за Вами, чтобы ответы были в полном объеме.
Я когда то работал технадзором, не переживайте, всё будет ОК!
Вместе мы - команда!
Понятно, пример помог. Спасибо.
Теперь такой вопрос.
При увеличении лота в какой-то момент чуть не хватает свободных средств, а открыть нужно увеличенным лотом.
То есть, войти максимальным лотом, сколько позволяет FreeMargin.
Как записать такое условие: если для открытия позиции расчетным лотом недостаточно средств, то функция должна вернуть максимально возможный лот для открытия позиции.
Люди подскажите что не так делаю , Почему два индикатора iRSI,iCCI не вызывают проблем , а мувинг и ВВ выдает предупреждение (possible loss of data due to type conversion Indicator.mqh )
//| Indicator.mqh |
//| Copyright 2017, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
// интерфейс к индикаторам.
class CIndicators
{
public:
double iRSI(string symbol, ENUM_TIMEFRAMES tf, int period, ENUM_APPLIED_PRICE applied, int shift);
double iCCI(string symbol, ENUM_TIMEFRAMES tf, int period, ENUM_APPLIED_PRICE applied, int shift);
double iBands(string symbol,ENUM_TIMEFRAMES tf,int BBPeriod,int shift,double BBDeviation,ENUM_APPLIED_PRICE BBPrice );
double iMA(string symbol,ENUM_TIMEFRAMES tf, int nMAPeriod,int shift, ENUM_MA_METHOD eMAMethod ,ENUM_APPLIED_PRICE MAPrice);
};
// -Создадим экземпляр индикатора iRSI
double CIndicators::iRSI(string symbol, ENUM_TIMEFRAMES tf, int period, ENUM_APPLIED_PRICE applied, int shift)
{
//---
int hRSI = iRSI(symbol, tf, period, applied);
if(hRSI == INVALID_HANDLE)
return 0.0;
double rsi[];
CopyBuffer(hRSI, 0, shift, 1, rsi);
if(ArraySize(rsi))
return rsi[0];
return 0.0;
//--Создадим экземпляр индикатора iCCI
}
//----------------------------------
double CIndicators::iCCI(string symbol, ENUM_TIMEFRAMES tf, int period, ENUM_APPLIED_PRICE applied, int shift)
{
int hCCI = iCCI(Symbol(), PERIOD_CURRENT, 55, PRICE_CLOSE);
if(hCCI == INVALID_HANDLE)return 0.0;
double cci[];
ArrayResize(cci, 1);
CopyBuffer(hCCI, 0, 0, 1, cci);
return cci[0];
}
//--------------------------------------------------
// Создадим экземпляр индикатора ВВ
double CIndicators::iBands(string symbol,ENUM_TIMEFRAMES tf,int BBPeriod,int shift,double BBDeviation,ENUM_APPLIED_PRICE BBPrice)
{
int hBands = iBands(Symbol(),tf,BBPeriod,0,BBDeviation,PRICE_CLOSE);
if(hBands==INVALID_HANDLE)return 0.0;
// Создадим массив значений верхней границы ВВ
double fBBUpper[];
ArrayResize(fBBUpper,true);
CopyBuffer(hBands,UPPER_BAND,0,3,fBBUpper);
return fBBUpper[0];
// Создадим массив значений нижней границы ВВ
double fBBLower[];
ArraySetAsSeries(fBBLower,true);
CopyBuffer(hBands,LOWER_BAND,0,3,fBBLower);
return fBBLower[0];
}
// Создадим экземпляр индикатора МА
double CIndicators::iMA(string symbol,ENUM_TIMEFRAMES tf, int nMAPeriod,int shift, ENUM_MA_METHOD eMAMethod ,ENUM_APPLIED_PRICE MAPrice)
{
// получим его хэндл
int hMA=iMA(Symbol(), PERIOD_CURRENT, nMAPeriod,0,MODE_EMA,PRICE_CLOSE);
if(hMA == INVALID_HANDLE)return 0.0;
// Создадим массив значений МА,заполним тремя последними значениями мувинга.
double fMA[];
ArraySetAsSeries(fMA,true);
CopyBuffer(hMA,0,0,3,fMA);
return fMA[0];
}
И еще хотел спросить: Что нужно изменить в торговом запросе , появилась ошибка 10030 ,,, годом ранее код эксперта работал без проблем а теперь опять меня заставляет читать/искать новшество изменений MQL5
// функция открытия позиции с рынка
bool MarketOrder(const string sSymbol, const ENUM_POSITION_TYPE eType, const double fLot, const int nSL = 0, const int nTP = 0, const ulong nMagic = 0, const uint nSlippage = 1000)
{
bool bRetVal = false;
// запрос
MqlTradeRequest oRequest = {0};
MqlTradeResult oResult = {0};
double fPoint = SymbolInfoDouble(sSymbol, SYMBOL_POINT);
int nDigits = (int) SymbolInfoInteger(sSymbol, SYMBOL_DIGITS);
oRequest.action = TRADE_ACTION_DEAL;
oRequest.symbol = sSymbol;
oRequest.volume = fLot;
oRequest.stoplimit = 0;
oRequest.deviation = nSlippage;
if(eType == POSITION_TYPE_BUY)
{
oRequest.type = ORDER_TYPE_BUY;
oRequest.price = NormalizeDouble(SymbolInfoDouble(sSymbol, SYMBOL_ASK), nDigits);
oRequest.sl = NormalizeDouble(oRequest.price - nSL * fPoint, nDigits) * (nSL > 0);
oRequest.tp = NormalizeDouble(oRequest.price + nTP * fPoint, nDigits) * (nTP > 0);
}
if(eType == POSITION_TYPE_SELL)
{
oRequest.type = ORDER_TYPE_SELL;
oRequest.price = NormalizeDouble(SymbolInfoDouble(sSymbol, SYMBOL_BID), nDigits);
oRequest.sl = NormalizeDouble(oRequest.price + nSL * fPoint, nDigits) * (nSL > 0);
oRequest.tp = NormalizeDouble(oRequest.price - nTP * fPoint, nDigits) * (nTP > 0);
}
// определим допустимый тип заливки ордера (зависит от типа исполнения - Instant, Market, биржевое и т.д.)
switch((int) SymbolInfoInteger(sSymbol, SYMBOL_FILLING_MODE))
{
case SYMBOL_FILLING_FOK:
oRequest.type_filling = ORDER_FILLING_FOK;
break;
case SYMBOL_FILLING_IOC:
oRequest.type_filling = ORDER_FILLING_IOC;
break;
default:
oRequest.type_filling = ORDER_FILLING_RETURN;
}
oRequest.magic = nMagic;
// проверка перед отправкой
MqlTradeCheckResult oCheckResult= {0};
bool bCheck = OrderCheck(oRequest, oCheckResult);
Print("Проверка заявки MarketOrder:",
" OrderCheck = ", bCheck,
", retcode = ", oCheckResult.retcode,
", balance = ", NormalizeDouble(oCheckResult.balance, 2),
", equity = ", NormalizeDouble(oCheckResult.equity, 2),
", margin = ", NormalizeDouble(oCheckResult.margin, 2),
", margin_free = ", NormalizeDouble(oCheckResult.margin_free, 2),
", margin_level = ", NormalizeDouble(oCheckResult.margin_level, 2),
", comment = ", oCheckResult.comment);
// если проверка удачная - отправка заявки
if(bCheck == true && oCheckResult.retcode == 0)
{
bool bResult = false;
// 3 попытки выставления ордера
for(int k = 0; k < 3; k++)
{
bResult = OrderSend(oRequest, oResult);
if(bResult == true && oResult.retcode == TRADE_RETCODE_DONE)
break;
if(k == 2)
break;
Sleep(100);
}
Print("Отправка заявки:",
" OrderSend = ", bResult,
", retcode = ", oResult.retcode,
", deal = ", oResult.deal,
", order = ", oResult.order,
", volume = ", NormalizeDouble(oResult.volume, 2),
", price = ", NormalizeDouble(oResult.price, _Digits),
", bid = ", NormalizeDouble(oResult.bid, _Digits),
", ask = ", NormalizeDouble(oResult.ask, _Digits),
", comment = ", oResult.comment,
", request_id = ",oResult.request_id);
if(oResult.retcode == TRADE_RETCODE_DONE)
bRetVal = true;
}
else if(oResult.retcode == TRADE_RETCODE_NO_MONEY)
{
Print("Недостаточно денег для открытия позиции. Работа эксперта прекращена.");
ExpertRemove();
}
return(bRetVal);
}