Обучение языку MQL4 под MetaTrader 4📌

От xbms, 13 апреля, 2013 в Уголок Программиста

#951

До 3-го только подошел урока.

#952

Вот держи,если разобрался с функцией CountBuy() ,CountSell() то эта функция не сложнее

Спойлер

[//--------------------------------------------------------------------------------------------++
void CloseOrders(int otype)
{
for(int i=OrdersTotal(); i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber()==Magic && OrderSymbol()==Symbol() )
{
if(OrderType() == otype)
{
if(OrderType() == OP_BUY) OrderClose(OrderTicket(),OrderLots(),BID,Slippage,clrAqua);
if(OrderType() == OP_SELL) OrderClose(OrderTicket(),OrderLots(),ASK,Slippage,clrAqua);
}
}
}
}
}

#953

Товарищи знающие, помогите иначе у меня мозг скоро испарится из головы. В общем проблема такая: не могу никак придумать следующую функцию: Необходимо рассчитать процент прибыли/убытка при достижении ТП или СЛ, соответственно. Допустим у нас на счету 100 баксов, получили мы 50 баксов прибыли (или убытка) = 50%(-50%). Можно не в процентах.

P.S. Я не программист, поэтому Ваше просто может оказаться для меня сложно. Так что не надо камней в мой адрес. С уважением, SpyRF.

Изменено 19 мая, 2014 пользователем SpyRF

#954

Есть у кого рабочая ссылка для скачки курса? ... Подписка уже не работает и ссылки не рабочие на сайте.

#955


Товарищи знающие, помогите иначе у меня мозг скоро испарится из головы. В общем проблема такая: не могу никак придумать следующую функцию: Необходимо рассчитать процент прибыли/убытка при достижении ТП или СЛ, соответственно. Допустим у нас на счету 100 баксов, получили мы 50 баксов прибыли (или убытка) = 50%(-50%). Можно не в процентах.

Когда сделка открылась сохрани значение Баланса, а когда закрылась сравни сохранённое значение с текущим. Хоть в процентах, хоть в долях...
Текущий баланс в % = 100*ТекущийБаланс/СтарыйБаланс;
#956

В уроке №3 есть такие строки в коде совы:

Цитата

if(Bid >= PriceHigh && CountSell() == 0)
{
SL = NormalizeDouble(Bid + StopLoss * Point, Digits);
TP = NormalizeDouble(Bid - TakeProfit * Point, Digits);

ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, comment, Magic, 0, Red);
if (ticket > 0)
{
if(OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
OrderModify(ticket, OrderOpenPrice(),SL, TP, 0);
}
}



При компиляции показывается предупреждение: return value of 'OrderModify' should be checked test3.mq4

Нашел в сети ответ почему так? В новом билде 600+ нужно явно указать возврат в переменную. И приводился пример кода. В случае совы выглядит так:

Цитата

if(Bid >= PriceHigh && CountSell() == 0)
{
SL = NormalizeDouble(Bid + StopLoss * Point, Digits);
TP = NormalizeDouble(Bid - TakeProfit * Point, Digits);

ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, comment, Magic, 0, Red);
if (ticket > 0)
{
if(OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
bool modify1 = OrderModify(ticket, OrderOpenPrice(),SL, TP, 0);
}
}



Цитата

if (Ask 0)
{
for(int i=OrdersTotal()-1; i >=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS,MODE_TRADES) == true)
{
if (OrderMagicNumber() == Magic && OrderType() == OP_SELL)
bool close1 = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Black);
}
}

}

Вопрос: достаточно ли такого указания переменной? Для Ask варианта также modify1 определять или уже нужно modify2?
Тоже касается и переменных OrderSelect, OrderDelete, OrderClose, OrderSend ...
#957


Вопрос: достаточно ли такого указания переменной? Для Ask варианта также modify1 определять или уже нужно modify2?Тоже касается и переменных OrderSelect, OrderDelete, OrderClose, OrderSend ...

Молодец, сам разобрался! Достаточно одной переменной на все функции, возвращающие true/false.
#958

В новом билде MetaEditor шаблон не такой как в уроках.

int OnInit()
void OnDeinit(0)

Это новые теперь вводные? вместо

int init()
int deinit(0)

#959

Вот ссылка все уроки одним архивом
http://yadi.sk/d/-fvTqTOIQm2tX

#960



Товарищи знающие, помогите иначе у меня мозг скоро испарится из головы. В общем проблема такая: не могу никак придумать следующую функцию: Необходимо рассчитать процент прибыли/убытка при достижении ТП или СЛ, соответственно. Допустим у нас на счету 100 баксов, получили мы 50 баксов прибыли (или убытка) = 50%(-50%). Можно не в процентах.

Когда сделка открылась сохрани значение Баланса, а когда закрылась сравни сохранённое значение с текущим. Хоть в процентах, хоть в долях...
Текущий баланс в % = 100*ТекущийБаланс/СтарыйБаланс;

Я бы дополнил
пример: 100*1300 (текущий баланс)/1000 (СтарыйБаланс) =130 процентов
Если вам нужно получить именно тот процент который вы потеряли в сделки, тогда после вычесть 100 процентов. (100*ТекущийБаланс/СтарыйБаланс) - 100 процентов
тогда
100*1300 (текущий баланс)/1000 (СтарыйБаланс) =130 процентов - 100 = 30 процентов прибыли
или
100*800 (текущий баланс)/1000 (СтарыйБаланс) =80 процентов - 100 = -20 процентов прибыли


Добавлено: 20-05-2014 09:26:07


В новом билде MetaEditor шаблон не такой как в уроках.

int OnInit()
void OnDeinit(0)

Это новые теперь вводные? вместо

int init()
int deinit(0)


Да, а OnTick за место start

Добавлено: 20-05-2014 09:36:34


При компиляции показывается предупреждение: return value of 'OrderModify' should be checked


Для OrderModify, OrderSelect, OrderDelete, OrderClose, для bool функций можно так же использовать
if (OrderModify(ticket, OrderOpenPrice(),SL, TP, 0)){}
Тоесть проверять true оно или false. В уроке номер 1,5 на 29 минуте говорится об этом

Изменено 20 мая, 2014 пользователем denkudo

#961

Как научить советника находить ближайшее(в окружности 1000 пипсов) круглое значение цены, для установки отложек. Например если текущая цена 1.62563, то отложки ставить на 1.62000 и 1.63000, то есть кратно 1000 для пятизнака.

#962

Например если текущая цена 1.62563, то отложки ставить на 1.62000 и 1.63000, то есть кратно 1000 для пятизнака.

Умножай на 100, отбрасывай дробную часть (получишь 162), + 1 (=163), затем дели на 100.
#963

тут даже был мартин, который торговал исключительно круглые значения...))

#964

В уроке №3 сова при тесте открывает только один тип ордеров: либо buy, либо sell и с ним уже работает. Выходит, какой тип открылся первый, тот и работает. Второй тип игнорит.

Если включить сову только в long или short, то работают buy и sell. По отдельности. Вместе не хотят.

И почему при компиляции показывает declaration of 'priсe' hides global declaration at line 19 ?


Добавлено: 20-05-2014 17:12:24

Еще вопрос.

При тесте в журнале пишет такой меседж: 2014.05.20 19:58:30.183 2013.02.05 15:45 teste4 EURUSD,H1: OrderSend error 131.
Исходя из кода ошибки - это значит Нарушена парность квадратных скобок

В коде нету квадратных скобок. Откуда такое сообщение?

Добавлено: 20-05-2014 17:15:45

И еще вопрос. В том же журнале еще один меседж: 2014.05.20 19:58:30.183 2013.02.05 15:02 teste4 EURUSD,H1: OrderSend error 134
Это значит Сложно для компиляции (слишком большое ветвление, внутренний стек уровней переполнен)

С этим что делать?

P.S. Это все по уроку №3.

Изменено 20 мая, 2014 пользователем geugene

#965


тут даже был мартин, который торговал исключительно круглые значения...))


Как все просто оказывается, а то я уже начал создавать цикли, использовать логарифмы, функции разные... Спасибо!!!
#966

Господа программисты,разъясните пожалуйста такую вещь ? Сделал все по урокам господина XBMS структуру и класс. компилируется все без ошибок.но ордера открывает явно не по условию.Ставлю советник на график , как он мне тут же начинает открывать ордера,хотя значение индикатора показывает совершенно другое чем записано в условии.Поясните плиз,вот кусок кода:

Спойлер

[
extern bool shopping_cart_USD = true; //Корзина USD:true=Вкл, false=Выкд.
//extern bool shopping_cart_GBP = true; //Корзина GBP:true=Вкл, false=Выкд.
//extern bool shopping_cart_JPY = true; //Корзина JPY:true=Вкл, false=Выкд.
extern double Lots = 0.01;
extern bool lots = true;
extern double MaximumRisk = 0.03; //прогресия лота на каждые 500 баланса +0.1 лот. например депозит стал 1000 лот =0.2, 1500 лот =0.3 итд
extern double DecreaseFactor = 3.0;
extern double balans = 500; //шаг баланса
extern int Slippage = 5; //проскальзывание


int total = OrdersTotal(),ticket;
double lotsx;
//--------------------------------------------------------------------------------------++
struct Orders
{
int Magic_USD;
int Magic_GBP;
int Magic_JPY;

string cm_usd,cm_gbp,cm_jpy;
};
Orders aOrders;
//---------------------------------------------------------------------------------------++
class Signal
{
protected:

private:
double usdsig,
gbpsig,
jpysig;

//--------------------------++
public:
Signal(void);
~Signal(void);

void Init();
double SignalOpen_Gbp_Plus_70();
double SignalOpen_Gbp_Minus_70();

double SignalClose();
};
//+------------------------------------------------------------------+
Signal::Signal()//конструктор класса
{}
//+------------------------------------------------------------------+
Signal::~Signal()//диструктор класса
{}
//+------------------------------------------------------------------+
void Signal::Init()
{
gbpsig=iCustom(Symbol(),PERIOD_D1,"Kuklovod_GBP",7,0);
}
//+------------------------------------------------------------------+
double Signal::SignalOpen_Gbp_Plus_70()
{
Init();
if(gbpsig >= 70 && gbpsig if(gbpsig >= 70 && gbpsig return(-1);
}
//+------------------------------------------------------------------+
double Signal::SignalOpen_Gbp_Minus_70()
{
Init();
if(gbpsig = -95) return(OP_BUY);
if(gbpsig = -95) return(OP_SELL);
return(-1);
}
//--------------------------------------------------------------------++
double Signal::SignalClose()
{
Init();
if(gbpsig = -20.0) return(OP_BUY);
if(gbpsig = -20.0) return(OP_SELL);
if(gbpsig > 0.0 && gbpsig if(gbpsig > 0.0 && gbpsig

return(-1);
}
//------------------------------------------------------------------++
Signal *ES;
//------------------------------------------------------------------++

//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(Digits == 3 || Digits == 5)
{
Slippage *= 10;
}
if(lots==true)
lotsx=Lots;
else
lotsx=LotsOptimized();

aOrders. Magic_USD = 11111;
aOrders. Magic_GBP = 22222;
aOrders. Magic_JPY = 33333;
aOrders.cm_usd = "Корзина USD";
aOrders.cm_gbp = "Корзина GBP";
aOrders.cm_jpy = "Корзина JPY";

ES = new Signal;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
delete ES;
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(total > 0 && CountBuy_GBP() > 0 && ES.SignalClose())
{
CloseOrders(OP_BUY);
if(total > 0 && CountSell_GBP() > 0 && ES.SignalClose())
{
CloseOrders(OP_SELL);
}
}
//----------------------------------------------------------------------------------------++
if(shopping_cart_USD == true)
{
if(CountBuy_GBP() == 0 && ES.SignalOpen_Gbp_Plus_70())
{
// Здесь вызываем функцию открытия ордеров. ОРДЕРА ОТКРЫВАЮТСЯ НОРМАЛЬНО,КАК ПОЛОЖЕНО.
}
if(CountBuy_GBP() == 0 && ES.SignalOpen_Gbp_Minus_70())
{
// Здесь вызываем функцию открытия ордеров. ОРДЕРА ОТКРЫВАЮТСЯ НОРМАЛЬНО,КАК ПОЛОЖЕНО.
}
}
//---
}
//--------------------------------------------------------------++
int CountSell_GBP()
{
int count=0;

for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber()== aOrders.Magic_USD && OrderComment() == aOrders.cm_usd)
{
if(OrderType()== OP_SELL)
count++;
}
}
}
return(count);
}
//--------------------------------------------------------------++
int CountBuy_GBP()
{
int count=0;

for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber()== aOrders.Magic_GBP && OrderComment() == aOrders.cm_gbp)
{
if(OrderType()== OP_BUY)
count++;
}
}
}
return(count);
}
//-------------------------------------------------------++
void CloseOrders(int otype)
{
for(int i=total-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber() == aOrders.Magic_GBP && OrderComment() == aOrders.cm_gbp)
{
if(OrderType() == otype)
{
if(OrderType() == OP_BUY) if(OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,clrAqua))Print("Ордер №",+ ticket,"Закрылся успешно !"); else Alert("Ошибка ",+GetLastError()," закрытия ордера ! № ",+ticket);
if(OrderType() == OP_SELL) if(OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,clrAqua))Print("Ордер №",+ ticket,"Закрылся успешно !");else Alert("Ошибка ",+GetLastError()," закрытия ордера ! № ",+ticket);
}
}
}
}
}
//-------------------------------------------------------------------------++

















]

Изменено 23 мая, 2014 пользователем denis77515

#967


но ордера открывает явно не по условию.Ставлю советник на график , как он мне тут же начинает открывать ордера,хотя значение индикатора показывает совершенно другое чем записано в условии

Имхо у Вас в классе логическая ошибка:
double Signal::SignalOpen_Usd_Plus_70()
{
Init();
if(gbpsig >= 70 && gbpsig if(gbpsig >= 70 && gbpsig return(-1);
}

Оба условия if() одинаковы, а результат разный - поэтому срабатывает первый (Бай) и такая же песня в остальных функциях. Я так понимаю, что когда индикатор 70:95 то Бай, а -70:-95 то Селл - разберитесь.
#968

То и оно что индикатор показывает какое то определенное значение,допустим usdsig >= 70 && usdsig = 70 не помогает.

#969


То и оно что индикатор показывает какое то определенное значение,допустим usdsig >= 70 && usdsig = 70 не помогает.

Честно говоря я ничего не понял...
При одном значении индикатора должны открываться ордера в обе стороны? - а у Вас в одну - первую. А при другом значении индюка должны закрываться в обе стороны? - а у Вас в одну - опять в первую (по ходу написания)... Зачем Вам 2 if() - он никогда не работает?!
В-общем меняйте логику проги - она не рабочая, или объясните толково - может подскажем.
#970

if (Bid >= TMAMedium && CountBuy() > 0)
{
for (int i = OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)
{
if (OrderMagicNumber() == Magic && OrderType() == OP_BUY)
{
OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), TP, 0);
OrderClose(OrderTicket(), 0.5*Lots(), Bid, Slippage, Black);
}
}
}
}

как модифицировать этот участок кода, чтобы он срабатывал единожды для открытого лота. Дело в том, что при тестировании он выполняет описанное условие: закрывает часть позиции, но когда цена опускается ниже TMAMedium и потом снова возвращается (на одной свече или следующей или, например, через 3 свечи), то советник, на основании этого условия закрывает полностью позицию, в связи с этом теряются достаточно прибыльные движения. Спасибо.


Добавлено: 23-05-2014 17:14:51




Товарищи знающие, помогите иначе у меня мозг скоро испарится из головы. В общем проблема такая: не могу никак придумать следующую функцию: Необходимо рассчитать процент прибыли/убытка при достижении ТП или СЛ, соответственно. Допустим у нас на счету 100 баксов, получили мы 50 баксов прибыли (или убытка) = 50%(-50%). Можно не в процентах.

Когда сделка открылась сохрани значение Баланса, а когда закрылась сравни сохранённое значение с текущим. Хоть в процентах, хоть в долях...
Текущий баланс в % = 100*ТекущийБаланс/СтарыйБаланс;

Я бы дополнил
пример: 100*1300 (текущий баланс)/1000 (СтарыйБаланс) =130 процентов
Если вам нужно получить именно тот процент который вы потеряли в сделки, тогда после вычесть 100 процентов. (100*ТекущийБаланс/СтарыйБаланс) - 100 процентов
тогда
100*1300 (текущий баланс)/1000 (СтарыйБаланс) =130 процентов - 100 = 30 процентов прибыли
или
100*800 (текущий баланс)/1000 (СтарыйБаланс) =80 процентов - 100 = -20 процентов прибыли

Вся проблема в том, чтобы зафиксировать баланс до открытия позиции и после закрытия, я пока не занимался разработкой, взял код обычного мартина, пока я работаю над другими вопросами, к нему вернусь позже, но если кто поможет - буду благодарен =)

Изменено 23 мая, 2014 пользователем SpyRF

#971


if (OrderMagicNumber() == Magic && OrderType() == OP_BUY)
{
OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), TP, 0);
if (OrderLots() >= Lots())
OrderClose(OrderTicket(), 0.5*Lots(), Bid, Slippage, Black);

1. Доработать можно например так (не зная полного алгоритма сложно советовать)
#972



if (OrderMagicNumber() == Magic && OrderType() == OP_BUY)
{
OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), TP, 0);
if (OrderLots() >= Lots())
OrderClose(OrderTicket(), 0.5*Lots(), Bid, Slippage, Black);

1. Доработать можно например так (не зная полного алгоритма сложно советовать)


Спасибо. Попробую твое предложение. Что касается кода, то оставшаяся часть кода - код из урока №3 =)
#973

Всем привет написал для советника трал, все вроде работает, но иногда он притормаживает. Может что то надо убрать? или добавить?
:)
void TrailingStop(int trailing)
{
double StLo,OSL,OOP;
int tip;
bool error=true;
color col;
for (int i=0; i {
if (OrderSelect(i, SELECT_BY_POS))
{
tip = OrderType();
if (tip {
OSL = NormalizeDouble(OrderStopLoss(),Digits);
OOP = NormalizeDouble(OrderOpenPrice(),Digits);
if (tip==0)
{
StLo = NormalizeDouble(Bid - trailing*Point,Digits);
if (StLo if (StLo > OSL)
error=OrderModify(OrderTicket(),OrderOpenPrice(),StLo,OrderTakeProfit(),0,White);

}
if (tip==1)
{
StLo = NormalizeDouble(Ask + trailing*Point,Digits);
if (StLo > OOP) continue;
if (StLo error=OrderModify(OrderTicket(),OrderOpenPrice(),StLo,OrderTakeProfit(),0,White);
}
if (!error) Alert("Error TrailingStop ",GetLastError()," ",Symbol()," SL ",StLo);
}
}
}
}

#974

Оll вот смотрите индикатор показывает значение допустим 70 нам нужно открыть 7 сделок как на пакупку так и на продажу..
условие такое как я понимаю
if(usdsig >=70 && usdsig if(usdsig >=70 && usdsig
я вчера попробовал изменить не много параметры показаний индикатора if(usdsig >=69 && usdsig if(usdsig >=70 && usdsig оно все реально заработало, но при значении 69 допустим откроется часть ордеров,а до 70 может вообще не дойти.тогда второй части ордеров не будет.мне нужно что бы индикатор показал 70, открылись ордеора 3 пакупку,4 на продажу при чем по разным парам. как то так.Напасал вчера второй советник используя просто переменные,все работает.Разобраться с классом хочу почему так.если нельзя сделать как я хочу,то получается этот класс совсем не нужен в этой сове.Либо добавлять еще одну функцию для проверки условия.Только это выходит лишняя писанина.От сюда вопрос,когда ,вернее в каком случаи лучше использовать класс.или господин xbms не все рассказал о нем.Будем ждать следующих уроков.

#975


if(usdsig >=70 && usdsig if(usdsig >=70 && usdsig


У Вас класс выдаёт направление сделки Бай/Селл, а нужно просто решение - Входим/Выходим (всего один блок if). Разницу улавливаете?
Тогда, в вызывающем коде, после прихода решения, открываете/закрываете ордера в двух направлениях сразу. Вот и всё...
ПС: всё таки глаз режет - "я так поняимаю дает разрешение на паокупку" :)

Для публикации сообщений создайте учётную запись или авторизуйтесь

Перейти к списку тем
Форум · 2.0.20260627.0025