Блог им. neophyte

Я наверное самый тупой на смартлабе?

P.S. (В начале, чтобы не читать до конца). Господа. Всем спасибо за обсуждение. Оно было конструктивным и полезным. Из множества мнений я выцепил возможный источник проблем и убрал его. Все работает, как часы.
Графики с результатами в конце публикации.

===================Дальше опубликованный ранее текст поста.
 Всем доброе утро...
Утро, потому что задолбала простейшая задачка — всю ночь ломал голову и экспериментировал с разными вариантами, но так и ушел в начале дня на хрен спать, не добившись результата. А сейчас проснулся... 

Тока не надо смеяться, но я наверное самый тупой программист на смартлабе, потому что сутки не могу разобраться в чем ошибка в трех строчках кода.

Я наверное самый тупой на смартлабе?

Что нужно? Хочу научить робота распознавать цепочки плюсовых и минусовых трейдов и менять при этом торговую тактику и загрузку капитала. Интересно, что из этого получится.

Выделяется три режима.
1. Старт.
2. Трейд завершился с прибылью.
3. Трейд завершился с убытком.

Вначале был более сложный режим, с мелкими деталями и кучей нюансов, но по причине неработоспсобности кода задачу упрощал, чтобы детали не мешали разобраться в принципе, и упростил до безобразия.
Теперь это выглядит так, но все равно нре работает.

if(MathRound(AccountBalance()) == InitialBalanse )
{ ABL=AccountBalance();
KMM=K0; }

if(AccountBalance() > ABL)
{ ABL=AccountBalance();
KMM=K1; }

if(AccountBalance() < ABL)
{ ABL=AccountBalance();
KMM=K2; }

//--- ABL — переменная. Последнее зафиксированное значение баланса.


Задумано следующее.
Есть три выделяемых события.

1. Старт, при котором закрытых сделок еще не было. 

Первый оператор if работает на старте. Сравнивается текущий баланс счета со стартовым.
Если текущий баланс равен стартовому, переменной ABL присваивается значение текущего баланса счета, а переменной KMM — значение K0 — признак стартового состояния.
Если сделок нет и баланс не изменился, все так и повторяется при каждом проходе кода, в второй и третий операторы if не работаю, поскольку условия в скобках не выполняются, а значит никакие действия этими операторами не производятся.

2. Если закрылась позиция и баланс вырос, то первый оператор уже не сработает, включается второй оператор if и выполняет следующие функции:
— переменной ABL присваивается новое значение — теущее значение выросшего баланса счета,
— переменной KMM — значение K1 — признак завершения прибыльной сделки.

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

3. Если закрылась позиция и баланс уменьшился, то включается третий оператор if и выполняет следующие функции:
— переменной ABL присваивается значение баланса счета,
— переменной KMM — значение K2 — признак завершения убыточной сделки.

Все просто, как грабли, но не работает.
Первый оператор if срабатывает нормально, инициализируя дальнейшие вычисления. После первой сделки, как бы она ни завершилась, с ростом или с убытком, управление передается на второй оператор и дальше молотит с коэффициентом К2.
Сутки мучаю.
Со сложного кода с кучей условий довел до шести строчек, а ни хрена не работает.
Убиться аб стену....
Где тут может быть ошибка? Вроде все по логике чайника нормально...


P.P.S.
//////////////
Как я уже сказал выше, проблема решена. Цель — резать оьбъем на серии убытков и восстанавливать, когда начинается серия прибылей.
Цель достигнута.
Грубый тест после достижения работоспособности программы:
Исходный вариант:
Я наверное самый тупой на смартлабе?

Вариант с дополнительным модулем:

Я наверное самый тупой на смартлабе? 

Игры разума с ММ дают выигрыш в прибыли примерно в два раза на фиксированном размере лота.
А если объем увеличивать с ростом баланса,

И еще один вариант, тоже грубый, с АвтоММ:
Я наверное самый тупой на смартлабе? 

★2
93 комментария
Жалко, что робот перешёл дорогу. То ждал от Вас прогнозных комментариев по инструментам, а теперь эти рассуждения самим с собой.
Александр НеПушкин, Блог (англ. blog, от web log — интернет-журнал событий, интернет-дневник, онлайн-дневник)

В своем дневнике я пишу о том, чем занимаюсь, и какие вопросы меня волнуют в настоящее время…
avatar
Александр НеПушкин, ну вот. Кто-то вчера жаловался что роботы задушили мою аналитику. Так не нужна никому аналитика, судя по сегодняшней публикации. :)
avatar
Николай Скриган, дык я уже и не жду, коли робот косит шаравэшки, на кой Вам теперь аналитика?
Александр НеПушкин, робот ограничен по своей железячной природе. Может накосячить так, что потом хрен поправишь. Поэтому ситуацию нужно анализировать, чтобы знать, когда включить робота, когда выключить, когда риски уменьшить, когда направлением ограничить.
avatar
Николай Скриган, у ты! я то думал, запустил и лежи на печи!
Александр НеПушкин, до печи еще конь не валялся. Рутину я с себя снял, это да. Но не контроль ситуации и риска.
То что пройден тест на одном промежутке истории ничего не решает и ничего не доказывает. На других промежутках может начаться слив и крах. Это может наступить и через 10 лет и через 10 минут. Поверьте старому механизатору торговых стратегий, который занимается этим больше 10 лет точно…
avatar
Ты — умный. Я вообще не понял — что ты написал.
Вестников, спсибо.
Комплимент приму, если смогу разобраться, где дурь в написанном.
В крайнем случае, если помогут, потому что постановка задачи важна не менее, чем ее решение :)
avatar
Николай Скриган, угу. Чтобы не вышло: тупой и ещё тупее. :-)
Вестников, )))) значит ты претендуешь на это пост?
avatar
баланс с чем сравнивает? точка от счета.
avatar
Sep38Rus, с предыдущим.
avatar
Я так понимаю, между приведенными операторами сравнения есть еще какие-то операторы?
Через Print попробуйте вывести значения в журнал и посмотрите, чему они равны.
avatar
Translator, со мной нужно проще...
Через принт это так?

Между приведенными операторами ничего нет. До них и после них конечно есть. А здесмь идет только эта цепочка, на выходе которой должно получаться значение КММ из набора трех вариантов К0, К1 или К2.

if(AccountBalance() < ABL)
{ ABL=AccountBalance();
KMM=K2;
Print(«КMM: », KMM); }
avatar
Николай Скриган, Да, что-то вроде этого. Принты можно нумеровать, чтобы знать, когда что выводится.
avatar
так зайдите на форум www.mql5.com/ru/forum и задайте вопрос, там хоть адекватный ответ будет
avatar
Costa, прошлый опыт общения показал, что там все начинают изгаляться, показывая свою крутизну и ничего не говоря по делу. Пару раз я пробовал там возникать с вопросами, толку ноль.
avatar
Николай Скриган, всё зависит от того, как спросите. Если и там начнете умничать про тупых и умных — конечно получите по полной программе и на любом из языков… непрограммирования )
Можете зайти на форум ТСЛаба, если на «мыколе» вас обижают )
avatar
VladMih, написал…
avatar
VladMih, написал, но вопрос просто удалили. :)
avatar
Николай Скриган, видимо написали на «мыколе», а язык-то не мыкуэлевский.
Я же советовал на ТСЛабе спросить.
avatar
VladMih, чисто MQL из метатрындера
avatar
Николай Скриган, дааа??? Я его не узнал! )))
А чего ж удалили?
Видимо нарушили правила форума, не туда запостили.
avatar
Николай Скриган, несколько раз обращался за помощью на форум, отвечали нормально
avatar
Сравнивает то с ABL
почему?
Профессор Преображенский, проверяет, изменился ли баланс по сравнению с прошлым значением.
avatar
Николай Скриган, я понимаю, я имею ввиду ABL в данном случае равна предыдущему значению)
Профессор Преображенский, все работает, нужно было вынести переменный в разряд глобальных и объявить их начальные значения вне цикла.
avatar
Что-то у тебя функция AccountBalance() слишком часто вызывается. Вызови ее один раз в переменную CurrentBalance.

CurrentBalance = AccountBalance();
if(MathRound(CurrentBalance) == InitialBalanse )
{ ABL= CurrentBalance;
KMM=K0; }

if(CurrentBalance > ABL)
{ ABL=CurrentBalance;
KMM=K1; }

if(CurrentBalance < ABL)
{ ABL=CurrentBalance;
KMM=K2; }

Если не работает, то ошибка либо в назначении переменных (глобальные, локальные), либо после компиляции ты смотришь результат не в той папке (запускаешь все время один и тот же сбойный вариант, поэтому не работает).
avatar
Reconnaissance, насчет папки все в порядке, проверено комбинированием значений переменных и проверки результатов сделок в тесте. Там они видны практически в явном виде, проявляются в изменении объема.

Насчет переменной счас попробую, хотя непонятно, как это может поломать логику работы операторов.

P.S. Как и ожидалось, введение промежуточной переменной CurrentBalance ничего не изменило.
avatar
Николай Скриган, можно вообще ABL=AccountBalance() вынести за IF
avatar
Mr. Bean, действительно.

if(MathRound(AccountBalance()) == InitialBalanse )
KMM=K0;
if(AccountBalance() > ABL)
KMM=K1;
if(AccountBalance() < ABL)
KMM=К2;
ABL=AccountBalance();

P.S. Но перестал работать даже первый этап.
avatar
Николай Скриган, вроде должно работать. попробуйте AccountBalance() в переменную до проверки выводить:

ab=AccountBalance()
if(MathRound(ab) == InitialBalanse )
KMM=K0;
if(ab > ABL)
KMM=K1;
if(ab < ABL)
KMM=К2;
ABL=AccountBalance();
avatar
Mr. Bean, этот вариант при любом исходе трейда дает КММ=К1;
avatar
Николай Скриган, ну в логике тут ошибок нет. ищите в другом месте. возможно AccountBalance() неверно возвращает значение. надо дебажить, без всего кода мало что понятно
avatar
Mr. Bean, 99% в этом ошибка
Профессор Преображенский, вы правы
avatar
Mr. Bean, в логике ошибок действительно нет. Я уже было сам логику начал утрачивать. :)
Проблема была в объявлении переменных и задании их начальных значений.
Мне с этим помог специалист из Киева.
avatar
Mr. Bean, вы правы
avatar
Николай Скриган, в конце тоже:
ABL=ab;
avatar
Reconnaissance, это вопросы оптимизации, проблма у него не в этом.
По хорошему все последующие if операторы надо сменить на elseif чтоб лишний раз поток не гонять.
avatar
dagh, это ничего не меняет в результате. В логике немного меняет.
Мне на этом этапе важнее смысл, а оптимизацию кода я потом буду делать, если нужно будет.
avatar
Николай Скриган, а я и не говорил что надо оптимизацию делать. Это работа крайняя.
Нашлась ошибка-то?
avatar
dagh, нет, не нашлась
avatar
dagh, нашлась. В объявлении переменных Работает мой исходный текст.
avatar
язык то какой… имхо не ассемблер точно
avatar
ves2010, не ругайтесь…
avatar
Николай Скриган, ну, он же не матом! )
avatar
ves2010, так «ИМХО» или «точно»? ))
Насколько я НЕ разбираюсь — это что-то Си-шное.
avatar
в чем ошибка то?
avatar
Mr. Bean, конфликт возникал непонятный.
Я вынес переменный в разряд глобальных и объявил их начальные значения. Все работает.
avatar
Нужна начальная инициализация всех переменных. Включая ABL

После того, как прошел блок обработки сделки и изменились данные хорошо бы через окно отладчика проверить их (переменных) содержимое.
avatar
dagh, вы были правы на 100%. Правда обошелся без отладчика, у меня это по сделкам сразу видною
avatar
Николай Скриган, отлично! Работал программистом на С++ в аутсорсе, правда это было лет 15 назад. Опыт не пропьешь. :)
avatar
(3*if) -> case
и при отладке ошибка станет ясной
avatar
bocha, не совcем понятно, что вы имеет в виду. Если использование полной формы оператора if, то это ничего не меняет.
Различные варианты каскадной реализации тоже.
Вопрос в том, что записанная цепочка должна работать, а не работает. И почему не работает непонятно. Логика процесса нигде не нарушена. А результата нет.
avatar
Николай Скриган, MathRound пробовали убрать?
При инициализации InitialBalanse=AccountBalance()
или в первом операторе написать так: ABL=MathRound(AccountBalance())
avatar
bocha, начальный баланс — целое число, если не округлять, могут быть ошибки.

Ваш вариант вместо начального балансу будет записывать текущий.
avatar
Николай Скриган,

(1)if(MathRound(AccountBalance()) == InitialBalanse )
{ ABL=AccountBalance(); KMM=K0; }

(2)if(AccountBalance() > ABL)
{ ABL=AccountBalance(); KMM=K1; }

(3)if(AccountBalance() < ABL)
{ ABL=AccountBalance(); KMM=K2; }

У Вас из-за округления срабатывает сначала (1) и сразу(3). В дальнейшем, если сделок нет, все время срабатывает (1)+(3)
Перепишите (1) в виде:

if(MathRound(AccountBalance()) == InitialBalanse )
{ ABL=MathRound(AccountBalance()); KMM=K0; }

Тогда при отсутствии сделок все время будет (1), что явный прогресс )))
avatar
bocha, три сработать не может. Там условие меньше, а не меньше или равно.
avatar
bocha, при отсутствии сделок у меня даже без кода все хорошо :)
avatar
ДА
Чем больше разбираюсь, тем меньше понимаю.
что-то я совсем запутался в этих трех соснах.
Отложу этот вопрос на неопределенное время.
avatar
Я ничего не понимаю в программировании, но кажется у Вас синтаксис нарушен в первой строчке InitialBalanSe, а должно быть InitialBalanCe...
Сильно палками не бейте, если херню спорол или она не влияет на работоспособность:)
avatar
Владимир Пермь, это моя константа. Никаких ограничений в имени нет. И ни на что оно не влияет. Могу назвать как угодно, главное чтобы имя при объявлении и при использовании совпадало.
Но исправил. Нужно быть точным и в мелочах.
Спасибо.
avatar
а что если проблема инициализации данных, те проблема инкапсуляции?
avatar
Ви Олег, вероятнее всего вы правы.
Я подозреваю, что проблема в этом, поскольку все остальное ничего не дает. Но как корректно устранить эту проблему я пока что не представляю. Двухнедельного опыта близкого знакомства с языком для этого пока что недостаточно…
avatar
> if(MathRound(AccountBalance()) == InitialBalanse )

уже неправильно. прелести плавающей арифметики.
у программистов 1/3 + 4/3 совсем не равны 5/3. не верите? скомпилируйте проверьте.MathRound не поможет

правильно
if(Abs(AccountBalance() — InitialBalanse) < 0.0001 ) // к примеру

дальше. на > < проверили, а если == ?

ну это сходу

avatar
Vitty, как раз таки это условие работает нормально и начальное значение задается без ошибок.
На старте баланс вообще точно равен начальному. Округление я ввел только из-за различного формата данных — начальный баланс — формат int, а плавающий — double .
Ошибки возникают потом, в процессе изменения баланса от начального значения.
Инициализация проходит нормально.
Далее баланс уменьшился, объемы должны (в тестовом примере) вдвое упасть, а они вдвое увеличились и такими и остаются...
avatar
Николай Скриган, ну тогда целиком код давайте, а не кусочек
avatar
Vitty, не даст)
Николай Скриган, так надо было приведение типов тогда делать а не округлять. к тому же в финансовых расчетах старайтесь по минимуму использовать числа с плавающей точкой.
avatar
Mr. Bean, проблема решена. дело совсем не в типах, это вопрос несущественный.
avatar
Vitty, ну если == то просто ничего не делается.
avatar
отбрось свои сомнения
avatar
при облегчении кода получилось нечто вроде
avatar
Ви Олег, не ну у вас разные числа в каждом ифе
avatar
double a, InitialBalanse;

int start()
{
a = NormalizeDouble( AccountBalance(), 0 );

if( a == InitialBalanse )
{
KMM=K0; }

if(a > ABL)
{
KMM=K1; }

if(AccountBalance() < ABL)
{
KMM=K2; }

ABL=a;

}

у меня без NormalizeDouble нормально сравнивать не хотело
avatar
Не знаю, что это за язык, поэтому напишу псевдокодом, как бы сделал я: убрал бы вообще вариант K0, если он используется только один раз. K1 значит увеличение лота, K2 — уменьшение.

// где-то в начале программы

// задаем начальную ситуацию
balancePrevious = 1000.0;

// где-то после сделки

// берем текущий баланс
balanceCurrent = AccountBalance();

// определяем ситуацию
KMM = (balanceCurrent > balancePrevious)? K1: K2;

// переписываем баланс
balancePrevious = balanceCurrent;
avatar
Wisard, угу. Это выглядит так (я действительно чайник, поэтому сразу не дошло):


//---Инициализация
double ABL=0;
double KMM=1;

//----Исполняемй код
void OnTick(void)
{
avatar
В MQL5 Со «стаканом» и лентой работать можно? Они там пристутствуют?
Оленевод Бельдыев, я работаю с MQL4, да и его возможностей толком не знаю. Опыт сознательного использования 3 недели.
Посмотрите документацию. www.mql5.com/ru/docs
Специалисты говорят, что там хорошо написано. Для того, кто уже знает процентов 60 написанного.
avatar
ну что? можно уже лопату-то приобрести? :)
avatar
dagh, увы. Не встречал я счастливых обладателей лопат для загребания денег среди роботостроителей (раньше они назывались алгоритмическими трейдерами)… Выигрыш получен только на участках рынка, где и так шла прибыль. и на за счет урезания убыточных позиций, а за счет увеличения прибыльных. Хотя может и это неплохо...
Но цикл публицаций «ММ: Игры разума» пожалуй напишу…
avatar
не знаю, написали это уже выше или нет, но вот так
>AccountBalance()) == InitialBalanse
делать не надо, надо
Math.Abs(AccountBalance()) — InitialBalanse) < SOME_CONST

это и решарпер подсказывает.
avatar
Михаил Иванов, ну почему же не надо. Эта операция нужна при запуске теста, когда ни одна сделка не проводилась, баланс равен начальному и нужно просто привести в соответствие типы переменных и убрать погрешность округления в типе double.
Дальнейшие совпадения меня не волнуют, хотя они будут портить чистоту эксперимента. Ваше предложение приведет к тому, что таких «порч» будет больше, так как у меня требуется абсолютное совпадение двух целых чисел, а в вашем варианте — совпадение с точностью до некоторой константы.
впрочем в окончательном варианте эта операция исключена, идет сравнение в нулём.
avatar
Николай Скриган, я посоветовал как сделать эту операцию менее глючной. убирать — не советовал :)
операцию == следует применять по сути ко всему, кроме double и float из-за вечных косяков в округлении вроде 0.1249999999999 или 0.125000000001

ставьте константу <= 0 и все
avatar
Михаил Иванов, вы просто функцию MathRound не заметили. Которая убирает этот косяк напрочь

if(MathRound(CurrentBalance) == InitialBalanse )
avatar
Николай Скриган, ну, если InitialBalanse тоже округлен, то все в порядке :)
avatar
Михаил Иванов, от жеж блин.
InitialBalanse по определению целое число :)
Упреждая вопрос — я его так определил.
avatar
Николай Скриган, ура :)
avatar

теги блога neophyte

....все тэги



UPDONW
Новый дизайн