voidOnTick(){
//--- объявление и инициализация запроса и результатаMqlTradeRequest request={0};
MqlTradeResult result={0};
//--- параметры запроса
request.action =TRADE_ACTION_DEAL; // тип торговой операции
request.symbol =Symbol(); // символ
request.volume =0.1; // объем в 0.1 лот
request.type =ORDER_TYPE_BUY; // тип ордера
request.price =SymbolInfoDouble(Symbol(),SYMBOL_ASK); // цена для открытия
request.deviation=5; // допустимое отклонение от цены
request.magic =EXPERT_MAGIC; // MagicNumber ордера//--- отправка запросаif(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // если отправить запрос не удалось, вывести код ошибкиAlert(GetLastError());
//--- информация об операцииPrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
和这个。
uint SendRandomPendingOrder(longconst magic_number)
{
//--- готовим запрос MqlTradeRequest request={0};
request.action=TRADE_ACTION_PENDING; // установка отложенного ордера
request.magic=magic_number; // ORDER_MAGIC
request.symbol=_Symbol; // инструмент
request.volume=0.1; // объем в 0.1 лот
request.sl=0; // Stop Loss не указан
request.tp=0; // Take Profit не указан //--- сформируем тип ордера
request.type=GetRandomType(); // тип ордера //---сформируем цену для отложенного ордера
request.price=GetRandomPrice(request.type); // цена для открытия //--- отправим торговый приказ MqlTradeResult result={0};
OrderSend(request,result);
//--- выведем в лог ответ сервера Print(__FUNCTION__,":",result.comment);
if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- вернем код ответа торгового сервера return result.retcode;
}
// Функция ищет бар, внутри которого находится указанный момент.
// Если такой бар найден - возвращается true и ссылка rIdx устанавливает нужное значение
// Если такой бар не найден - возвращается false и ссылка rIdx устанавливает значение на ближайший индекс,
// время которого меньше, требуемого.
// При недостаточности буффера функция возвращает false, ссылка устанавливается на отрицательное значение.
// NOTE !!! ненаступивший момент может лежать внутри нулевого бара, в этом случае вернется true,
// даже если фактически данный момент еще не наступил. false вернется только если данный момент лежит позже
// нулевого бара.
// Если искомый момент находится раньше самого раннего бара, возвращается false и rIdx = INT_MAX
bool CTSTime::FindIdxOf(datetime dtMomentToFind,int& rIdx)
{
ASSERT(dtMomentToFind > MIN_DATETIME && dtMomentToFind < NEVER_EXPIRES);
// Пока найденный индекс - невалиден.
rIdx = WRONG_VALUE;
// Если данных нет - возвращаем отрицательный результат поиска.if(GetTSSize() == 0)
return(false);
// Найдем продолжительность текущего бараint iSecondsInBar = PeriodSeconds(m_etTimeframe);
ASSERT(iSecondsInBar >= SECS_IN_MINUTE);
datetime dtMomentOfZeroBar = GetTime(0);
datetime dtMomentOfLastBar = GetTime(GetTSSize()-1);
// Искомый момент лежит внутри или позже, чем нулевой бар ? if(dtMomentToFind >= dtMomentOfZeroBar)
{
rIdx = 0;
// Искомый момент лежит на открытии минус первого бара или позже ? if(dtMomentToFind >= dtMomentOfZeroBar + iSecondsInBar)
return (false); // Искомый момент лежит после нулевого бара. // Искомый момент лежит внутри нулевого бара.return(true);
};
// Здесь ясно, что искомый момент был ранее нулевого бара. // Проверим, может быть искомый момент лежит раньше последнего бара ? if(dtMomentToFind < dtMomentOfLastBar)
{
// Увы, такого раннего момента в таймсерии нет. // Возвращаем самый большой индекс бара, какой можем возвратить// (Потому, что бара со временем меньше требуемого - в таймсерии нет).
rIdx = INT_MAX;
return(false);
};
// Здесь ясно, что искомый момент был позже начала самого раннего бара, но раньше начала самого нового бара.
ASSERT(GetTSSize() > 1); // Проверим, размер буффера должен быть минимум два бара. (Иначе условие не выполняется, что искомый момент был позже начала самого раннего бара, но раньше начала самого нового бара, не выполняется)// Ищем примерно, где был данный момент.
ASSERT(dtMomentOfZeroBar > dtMomentToFind);
ASSERT(dtMomentOfZeroBar > dtMomentOfLastBar);
ulong ulSecFromSearchToLatest = dtMomentOfZeroBar - dtMomentToFind;
ulong ulSecFromEarlestToLatest = dtMomentOfZeroBar - dtMomentOfLastBar;
ASSERT(ulSecFromEarlestToLatest > ulSecFromSearchToLatest);
double dResIdx = (double)ulSecFromSearchToLatest*(double)(GetTSSize()-1)/(double)ulSecFromEarlestToLatest;
ASSERT(dResIdx <INT_MAX && dResIdx >= 0);
int iResIdx = (int)MathRound(dResIdx);
ASSERT(iResIdx >= 0 && iResIdx<(int)GetTSSize()); // По идее, мы должны уложиться в этот диапазон.// Поскольку мы исследуем минимум два бара (текущий и следующий),// Текущий бар не должен быть нулевым.// Поскольку случай с буффером в один бар у нас был отсеян раньше, мы не должны получить ошибку.if(iResIdx == 0)
iResIdx = 1;
// Получен приблизительный индекс (uiResIdx).// Уточняем. Берем два бара, текущий и следующий.datetime dtResMoment;
datetime dtNextMoment;
dtResMoment = GetTime(iResIdx);
dtNextMoment = GetTime(iResIdx-1);
int iShift = 0;
bool bUp = false;
bool bDown = false;
do
{
if(dtResMoment > dtMomentToFind) // Если искомый момент раньше начала первого бара
{
iShift = 1; // Возьмем на один бар раньше.
bUp = true; // Запомним направление
}
else// Иначе - Искомый момент равен или позже начала первого бара.
{
if(dtNextMoment <= dtMomentToFind) // Если искомый момент больше или равен началу второго бара
{
iShift = -1; // Возьмем на один бар позже
bDown = true; // Запомним направление
}
else// Иначе - искомый момент равен или позже начала перого бара и раньше начала второго бара
{
iShift = 0; // То есть, можно выходить из цикла коррекции.
}
}
iResIdx += iShift; // Смещаемсяif(iResIdx > (int)GetTSSize() || iResIdx <= 0) // Проверим на допустимый диапазон
{
ASSERT(false); // В серии недостаточно данных (мал буффер)
rIdx = INT_MAX;
return(false);
};
dtResMoment = GetTime(iResIdx); // Запрашиваем новые данные
dtNextMoment = GetTime(iResIdx-1);
if(bUp == true && bDown == true) // Контроль направления коррекции
{
ASSERT(false); // Сменилось направление коррекции !!!
iShift = 0;
}
}
while(iShift != 0);
// В этой точке искомый момент равен или позже начала перого бара и раньше начала второго бара.// Проверим, может быть, искомый момент позже конца первого бара, но раньше начала второго бара // (между барами разрыв, и искомый момент находится именно там)// Ясно, что ссылка должна показывать на первый бар в любом случае
rIdx = iResIdx;
if(dtMomentToFind >= dtResMoment+iSecondsInBar)
// Действительно, искомый момент - внутри разрыва между барами.return(false);
return(true);
};
在学习C语言之前,程序员经历了机器命令、汇编、Fortran、PL/1、Pascal和许多其他东西,所有这些都没有教科书,没有适当的解释,正如Volchansky所说,文件是用歪歪扭扭的字母打印出来的,这样的日子早就过去了。
这是一个复杂的多功能应用系统的时代--带有嵌入式应用编程语言--这种语言的任务是使应用终端对应用用户开放,用户无需深挖编程,就能在短时间内快速学习和使用这种终端语言。
我同意!正确的说法是。交易终端 应促进交易。
你是根据谁来判断的?作为公司的形象代言人,你滑向拖泥带水是不好的。你已经写过,即使是那些有MT4经验的人也有困难。而且他们也不需要。
你看到的是扯皮吗?
我已经写过很多次,有很多机会可以简单轻松地为你的策略编写一个测试EA。
我甚至给了一个帮助的链接。但如果我们开始询问有关帮助的问题,我们会发现我们对这种知识感兴趣。但它一直在说一切是多么糟糕。
这就是为什么我说--也许我们现在这一代人--18岁,父母-媳妇要买车,21岁--买房。但要学习--不,为什么?
汇编程序有多复杂? 我需要它的功能
因为仅在10年前,初学者在这个论坛上问的问题就大不相同--更复杂、更有趣。
顺便说一下,今天MQL4中的问题比MQL5中的信息量大得多。原因很明显,这不是MQL-版本的时代。
不,我不知道。你是什么意思?
阿列克谢,真的,我现在不能给你一个例子。但你喜欢实验--运行它,看看它在不同的输入数据下会返回什么。
只是我现在很难记住并寻找它。
好吧,fxsaber给出了一个例子(我为自己修改了一下),比较一下代码。
这里你可以看到在什么条件下Bars()会返回一个犯规。
初学者写的第一件事是交易脚本。第二个是一个简单的指标。第三种 - 一个简单的专家顾问。
即使是MQL4的第一阶段也比MQL5快。
一个交易脚本?为什么不是专家顾问,甚至是标准库 的替代品?
在我看来,编写交易脚本是一项明确的中级任务,绝不适合初学者。
初学者应首先限于最简单的线上输出。然后--一个简单的指标。然后才是--转到请求指标和交易功能。
汇编程序有多复杂? 我需要它的功能。
什么功能?
汇编程序过于具体,不能说 "我需要它的功能"。
关于SB在论坛上向新手推销什么的问题,以及为什么即使是远离懒惰的人也真的很难受的问题,这是一个新鲜的例子。今天我得到了一个关于MQL5的非常有建设性的问题,没有任何抱怨。
这是一个关于交易、自动交易系统和交易策略测试的论坛。
虫子,虫子,问题
damirqa, 2018.01.09 12:14
你好!我从https://www.mql5.com/ru/articles/100 开始学习MQL5。我启动了代码,收到了错误4756。我想我应该从简单的东西开始(警报/打印......)。其中一个最重要的功能是OrderSend。我开始在论坛/文档中搜索如何使用OrderSend。我发现这篇文章https://www.mql5.com/ru/docs/constants/tradingconstants/enum_trade_request_actions,并 找到了开设买入头寸的代码。我得到了错误4756和检索码10030。我理解10030--它是OrderSend属性,但我没有理解这个属性应该如何使用(我看了别人的代码),它主要用于什么。然后我打开https://www.mql5.com/ru/docs/trading/ordersend, 复制了代码,启动了它,一切都很好,它工作了。
但我仍然不明白为什么会出现错误4756,以及如何摆脱它,还有10030。
看了一下之间的代码
和这个。
在我看来它们几乎是一样的,我没有看到这些错误出现的地方(4756和10030)。请指证和解释
主持人回答
关于交易、自动交易系统和策略测试器的论坛
错误, 漏洞, 问题
Vladimir Karputov, 2018.01.09 12:20
使用 CTrade 交易类 - 这样可以保证你尽可能少犯错误。
发送交易指令打开买入的例子。
可能有助于解决这个问题。但事实上,这个新秀有一个非常严重的问题。
关于交易、自动交易系统和策略测试的论坛
错误、漏洞、问题
fxsaber, 2018.01.09 13:22
https://www.mql5.com/ru/search#!keyword=Unsupported%20filling%20mode
也就是说,你必须去阅读指定主题的链接。在SB,这一点通过一个奇妙的地方得到了解决。也就是说,在编写最简单的交易脚本(任何初学者的第一个程序)时,几乎是轻而易举的。
交易脚本 ??为什么不是专家顾问,甚至是标准库 的替代品?
在我看来,写交易脚本是一项明确的中级任务,绝不适合初学者。
初学者应首先限于最简单的线上输出。然后--一个简单的指标。然后才是--转到请求指标和交易功能。
我马上就开始使用多货币MTF专家顾问。而且我在新手支部感觉很好。而且我没有问太多的问题--我在某处有帮助,有脑子......。
哦,顺便说一下,关于iBarsShift。
这是我的对应函数(CTSTime是一个时间序列类),我觉得对新手来说有点复杂,即使有注释。所以它真的缺乏SB。