Выделяется три режима.
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.
//////////////
Как я уже сказал выше, проблема решена. Цель — резать оьбъем на серии убытков и восстанавливать, когда начинается серия прибылей.
Цель достигнута.
Грубый тест после достижения работоспособности программы:
Исходный вариант:
Вариант с дополнительным модулем:
Игры разума с ММ дают выигрыш в прибыли примерно в два раза на фиксированном размере лота.
А если объем увеличивать с ростом баланса,
И еще один вариант, тоже грубый, с АвтоММ:
В своем дневнике я пишу о том, чем занимаюсь, и какие вопросы меня волнуют в настоящее время…
То что пройден тест на одном промежутке истории ничего не решает и ничего не доказывает. На других промежутках может начаться слив и крах. Это может наступить и через 10 лет и через 10 минут. Поверьте старому механизатору торговых стратегий, который занимается этим больше 10 лет точно…
Комплимент приму, если смогу разобраться, где дурь в написанном.
В крайнем случае, если помогут, потому что постановка задачи важна не менее, чем ее решение :)
Через Print попробуйте вывести значения в журнал и посмотрите, чему они равны.
Через принт это так?
Между приведенными операторами ничего нет. До них и после них конечно есть. А здесмь идет только эта цепочка, на выходе которой должно получаться значение КММ из набора трех вариантов К0, К1 или К2.
if(AccountBalance() < ABL)
{ ABL=AccountBalance();
KMM=K2;
Print(«КMM: », KMM); }
Можете зайти на форум ТСЛаба, если на «мыколе» вас обижают )
Я же советовал на ТСЛабе спросить.
А чего ж удалили?
Видимо нарушили правила форума, не туда запостили.
почему?
CurrentBalance = AccountBalance();
if(MathRound(CurrentBalance) == InitialBalanse )
{ ABL= CurrentBalance;
KMM=K0; }
if(CurrentBalance > ABL)
{ ABL=CurrentBalance;
KMM=K1; }
if(CurrentBalance < ABL)
{ ABL=CurrentBalance;
KMM=K2; }
Если не работает, то ошибка либо в назначении переменных (глобальные, локальные), либо после компиляции ты смотришь результат не в той папке (запускаешь все время один и тот же сбойный вариант, поэтому не работает).
Насчет переменной счас попробую, хотя непонятно, как это может поломать логику работы операторов.
P.S. Как и ожидалось, введение промежуточной переменной CurrentBalance ничего не изменило.
if(MathRound(AccountBalance()) == InitialBalanse )
KMM=K0;
if(AccountBalance() > ABL)
KMM=K1;
if(AccountBalance() < ABL)
KMM=К2;
ABL=AccountBalance();
P.S. Но перестал работать даже первый этап.
ab=AccountBalance()
if(MathRound(ab) == InitialBalanse )
KMM=K0;
if(ab > ABL)
KMM=K1;
if(ab < ABL)
KMM=К2;
ABL=AccountBalance();
Проблема была в объявлении переменных и задании их начальных значений.
Мне с этим помог специалист из Киева.
ABL=ab;
По хорошему все последующие if операторы надо сменить на elseif чтоб лишний раз поток не гонять.
Мне на этом этапе важнее смысл, а оптимизацию кода я потом буду делать, если нужно будет.
Нашлась ошибка-то?
Насколько я НЕ разбираюсь — это что-то Си-шное.
Я вынес переменный в разряд глобальных и объявил их начальные значения. Все работает.
После того, как прошел блок обработки сделки и изменились данные хорошо бы через окно отладчика проверить их (переменных) содержимое.
и при отладке ошибка станет ясной
Различные варианты каскадной реализации тоже.
Вопрос в том, что записанная цепочка должна работать, а не работает. И почему не работает непонятно. Логика процесса нигде не нарушена. А результата нет.
При инициализации InitialBalanse=AccountBalance()
или в первом операторе написать так: ABL=MathRound(AccountBalance())
Ваш вариант вместо начального балансу будет записывать текущий.
(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), что явный прогресс )))
что-то я совсем запутался в этих трех соснах.
Отложу этот вопрос на неопределенное время.
Сильно палками не бейте, если херню спорол или она не влияет на работоспособность:)
Но исправил. Нужно быть точным и в мелочах.
Спасибо.
Я подозреваю, что проблема в этом, поскольку все остальное ничего не дает. Но как корректно устранить эту проблему я пока что не представляю. Двухнедельного опыта близкого знакомства с языком для этого пока что недостаточно…
уже неправильно. прелести плавающей арифметики.
у программистов 1/3 + 4/3 совсем не равны 5/3. не верите? скомпилируйте проверьте.MathRound не поможет
правильно
if(Abs(AccountBalance() — InitialBalanse) < 0.0001 ) // к примеру
дальше. на > < проверили, а если == ?
ну это сходу
На старте баланс вообще точно равен начальному. Округление я ввел только из-за различного формата данных — начальный баланс — формат int, а плавающий — double .
Ошибки возникают потом, в процессе изменения баланса от начального значения.
Инициализация проходит нормально.
Далее баланс уменьшился, объемы должны (в тестовом примере) вдвое упасть, а они вдвое увеличились и такими и остаются...
int start()
{
a = NormalizeDouble( AccountBalance(), 0 );
if( a == InitialBalanse )
{
KMM=K0; }
if(a > ABL)
{
KMM=K1; }
if(AccountBalance() < ABL)
{
KMM=K2; }
ABL=a;
}
у меня без NormalizeDouble нормально сравнивать не хотело
// где-то в начале программы
// задаем начальную ситуацию
balancePrevious = 1000.0;
// где-то после сделки
// берем текущий баланс
balanceCurrent = AccountBalance();
// определяем ситуацию
KMM = (balanceCurrent > balancePrevious)? K1: K2;
// переписываем баланс
balancePrevious = balanceCurrent;
//---Инициализация
double ABL=0;
double KMM=1;
//----Исполняемй код
void OnTick(void)
{
Посмотрите документацию. www.mql5.com/ru/docs
Специалисты говорят, что там хорошо написано. Для того, кто уже знает процентов 60 написанного.
Но цикл публицаций «ММ: Игры разума» пожалуй напишу…
>AccountBalance()) == InitialBalanse
делать не надо, надо
Math.Abs(AccountBalance()) — InitialBalanse) < SOME_CONST
это и решарпер подсказывает.
Дальнейшие совпадения меня не волнуют, хотя они будут портить чистоту эксперимента. Ваше предложение приведет к тому, что таких «порч» будет больше, так как у меня требуется абсолютное совпадение двух целых чисел, а в вашем варианте — совпадение с точностью до некоторой константы.
впрочем в окончательном варианте эта операция исключена, идет сравнение в нулём.
операцию == следует применять по сути ко всему, кроме double и float из-за вечных косяков в округлении вроде 0.1249999999999 или 0.125000000001
ставьте константу <= 0 и все
if(MathRound(CurrentBalance) == InitialBalanse )
InitialBalanse по определению целое число :)
Упреждая вопрос — я его так определил.