Форум » Синтаксис языка » Специфическая Математика и расчеты усреднений !!! » Ответить

Специфическая Математика и расчеты усреднений !!!

voldemar227: Вопрос есть бай лотом 0,01 и есть сел ордер который ниже бая, селл обьемом 0,03 как расчитать профит для села что бы обе позы закрылись в ноль ????

Ответов - 23, стр: 1 2 3 All

Scriptong: Решается путем вывода уравнения. Дано: 1. buyVolume - объем позиции Buy 2. buyPrice - цена открытия Buy 3. sellVolume - объем позиции Sell 4. sellPrice - цена открытия позиции Sell 5. spread - текущий спред Найти: X - цена Bid, при которой сумма позиций будет равна нулю. Примем, что buyCost - прибыль/убыток в валюте депозита, который будет получен в случае закрытия позиции Buy по цене X. Соответственно, sellCost - прибыль/убыток в валюте депозита, который будет получен при закрытии позиции Sell по той же цене. По условиям задачи эти значения должны быть равны. Значит: busCost + sellCost = 0 Чтобы рассчитать значения buyCost и sellCost, нам необходимо найти разницу между ценой открытия позиций и ценой X, умножить ее на стоимость одного пункта (tickValue), а затем умножить на объем позиции. В итоге имеем: buyCost = (buyPrice - X)*tickValue*buyVolume и sellCost = (X + spread - sellPrice)*tickValue*sellVolume В последнем выражении учли, что Sell закрывается по цене Ask, в то время как X - цена Bid. Подставляем выражения buyCost и sellCost в уравнение и получаем: (buyPrice - X)*tickValue*buyVolume + (X + spread - sellPrice)*tickValue*sellVolume = 0 Как видим, стоимость одного пункта (tickValue) сокращается. В этом нет ничего удивительного, т.к. мы работаем на одной и той же валютной паре. Решаем уравнение и узнаем: X = ((sellPrice - spread)*sellVolume - buyPrice*buyVolume)/(sellVolume - buyVolume) Заметим, что уравнение не имеет решения при sellVolume = buyVolume. Если Buy объемом 0.01 открыт по цене 1.3655, а Sell открыт объемом 0.03 по цене 1.3630 при спреде 0.0002, то получим цену, при которой короткая позиция компенсирует длинную: X = ((1.3630 - 0.0002)*0.03 - 1.3655*0.01)/(0.03 - 0.01) = 1.36145 Если используется 4-хзнак, то цена закрытия должна быть меньше, т.е. 1.3614. Проверка в данном случае проста. Убыток по позиции Buy: (1.3655 - 1.3614)*0.01 = 0,000041. Прибыль по позиции Sell: (1.3630 - 0.0002 - 1.3614)*0.03 = 0,000042. При стоимости пункта 10 центов, вы получите прибыль 0.1 цент.

voldemar227: показывает отрицательное значение Почему ??? Открывается бай лотом 0,01 потом сел лотом 0,03 double selp=0; double buyp=0; double lotb=0; double lots=0; double rez =0; for (int z=total; z>=0; z--) { if(OrderSelect(z, SELECT_BY_POS)) { if(OrderSymbol()==Symbol() ) { if (OrderType()==OP_BUY && OrderMagicNumber()==magic) { buyp=OrderOpenPrice(); lotb=OrderLots(); } if (OrderType()==OP_SELL&& OrderMagicNumber()==magic) { selp=(OrderOpenPrice()*OrderLots()); lots=OrderLots(); } rez =NormalizeDouble( ( selp * lots - buyp * lotb )/(lots-lotb),Digits); }}} Comment(rez);

Scriptong: voldemar227 пишет: показывает отрицательное значение Почему ??? Открывается бай лотом 0,01 потом сел лотом 0,03 Все верно. Если цена открытия ордера sell даже в два раза больше цены открытия ордера buy, то все равно первый член выражения будет намного меньше (минимум, на два порядка меньше), чем второй. Отсюда и отрицательное число. Причина в несимметричности формул расчета buyp и sellp. Например, цена открытия buy 1.2, а цена открытия sell 2.4. Получаем: buyp = 1.2 lotb = 0.01 sellp = 2.4*0.03 = 0.072 lots = 0.03. Теперь подставляем данные в выражение rez: (0.072*0.03 - 1.2*0.01)/(0.03 - 0.01) = (0.00216 - 0.012)/0.02 = -0.0984/0.02 = -0.492.


voldemar227: ок я понял , разобрался .... Еще вопрос .... мы имеем 3 ордера бай лотами 0,01 0,02 и 0,03 и 7 ордеров сел все по 0,02 при этом все ордера имеют разные цены открытия . как в таком случае найти цену по которой будет высчитан нулевой профит ????????

Scriptong: Этот вопрос Вы задавали в начале ветки. Мой ответ - второй в этой же теме (от 11.11.11). Посмотрите, пожалуйста.

voldemar227: я видел , но там вопрос стоял о двух ордерах всего , один бай один сел .... последний вопрос касается нескольких разных ордеров несколько баев несколько селов разными лотами и разными ценами открытия ... Если я правильно понимаю то для всех селов нужно высчитать среднюю цену и от нее отталкиваться ??? Также и для баев ???

Scriptong: voldemar227 пишет: Если я правильно понимаю то для всех селов нужно высчитать среднюю цену и от нее отталкиваться ??? Также и для баев ?? Да. В том то и прелесть приведенной формулы, что она подходит для любого количества ордеров. Вместо buyPrice и sellPrice подставляйте средние цены открытия buy и sell. Они находятся по формуле: где n - количество ордеров заданного типа, lot_i - объем i-го ордера, openPrice_i - цена открытия i-го ордера, lotSum - совокупный объем ордеров одного типа. Вместо sellvolume и buyVolume подставляйте совокупный объем ордеров. Тот, который в вышеприведенной формуле вы использовали в качестве lotSum.

voldemar227: Не могу понять но почему то пишет ошибку номер 1 постоянно //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// double nn=0,bb=0; double nnn=0,bbb=0; for(int ui=total-1; ui>=0; ui--) { if(OrderSelect(ui,SELECT_BY_POS)) { if(OrderSymbol()==Symbol()) { if(OrderType()==OP_BUY && OrderMagicNumber()==Magic) { double op=OrderOpenPrice(); double llot=OrderLots(); double itog=op*llot; bb=bb+itog; nn=nn+llot; double factb=bb/nn; } if(OrderType()==OP_SELL && OrderMagicNumber()==Magic) { double ops=OrderOpenPrice(); double llots=OrderLots(); double itogs=ops*llots; bbb=bbb+itogs; nnn=nnn+llots; double facts=bbb/nnn; } } } } for(int uui=total-1; uui>=0; uui--) { if(OrderSelect(uui,SELECT_BY_POS)) { if(OrderSymbol()==Symbol()&& OrderMagicNumber()==Magic) { if(b>=2 && OrderType()==OP_BUY && OrderTakeProfit()!=(factb+CORR)) //корр небольшой плюс к 0 { OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),factb+CORR,0,Blue); } if(s>=2 && OrderType()==OP_SELL && OrderTakeProfit()!=(factb-CORR)) { OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),facts-CORR,0,Blue); } } } } Взгляните в чем может быть проблема ????

Scriptong: voldemar227 пишет: Взгляните в чем может быть проблема ???? Ошибка 1 при попытке модификации ордера говорит о том, что по факту в ордере ничего не изменяется, т.е. заданы такие параметры модификации, которые равны текущим. Неравенство в Вашем случае получается из-за неправильного сравнения вещественных чисел OrderTakeProfit() и factb+CORR (facts+CORR). Два вещественных числа, которые с точки зрения пользователя имеют одинаковую величину, в виду разных способов получения результата, могут оказаться неравными. Разность может наблюдаться в пятнадцатом знаке после запятой. Есть два способа правильного сравнения двух вещественных чисел: 1. Сравнивать их абсолютную разность с некой дельтой. Если разность меньше дельты, то считается, что значения равны. Если больше или равно дельты - числа неравны. 2. Сравнивать значения чисел только тогда, когда они приведены к одинаковой точности. Реализация первого способа: double a = ....; double b = ....; double delta = 0.000001; // Требуемая точность if (MathAbs(a - b) < delta) { // Числа a и b равны } else { // числа a и b неравны } Второй способ: double a = ....; double b = ....; int digits = 7; // Требуемая точность в количестве знаков после запятой double aND = NormalizeDouble(a, digits); double bND = NormalizeDouble(b, digits); if (aND == bND) { // Числа a и b равны } else { // числа a и b неравны }

voldemar227: к сожалению данный методы не помогли , в в принцепе всегда привожу число к нужному колличеству знаков

voldemar227: ошибка где то тут for(int uui=total-1; uui>=0; uui--) { if(OrderSelect(uui,SELECT_BY_POS)) { if(OrderSymbol()==Symbol()&& OrderMagicNumber()==Magic) { if(b>=2 && OrderType()==OP_BUY && NormalizeDouble(OrderTakeProfit(),Digits)!=NormalizeDouble(factb,Digits)) { OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),NormalizeDouble(factb,Digits),0,Blue); } if(s>=2 && OrderType()==OP_SELL && NormalizeDouble(OrderTakeProfit(),Digits)!=NormalizeDouble(factb,Digits)) { OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),NormalizeDouble(facts,Digits),0,Blue); } } } } но не могу понять откуда она идет

voldemar227: Все нашел ..... Битые котировки ....

Scriptong: voldemar227 пишет: к сожалению данный методы не помогли , в в принцепе всегда привожу число к нужному колличеству знаков В коде, который Вы выложили, приведения к нужному числу знаков нет. Допустим, что приведение производилось где-то выше по коду. Но ведь в видимой части кода после операций деления вновь необходимо производить нормализацию.

Scriptong: voldemar227 пишет: Все нашел ..... Битые котировки .... Это очень странный вывод. Котировки с дырами не могут быть причиной ошибки 1.

voldemar227: После прокачки истории ошибка исчезла ..... Это первое А второе по поводу ваших котировок , сделал все по инструкции , даже виндовс с ноля переставил и не работают они , у вас котировки либо уже не совместимы с терминалом либо битые.......

Scriptong: voldemar227 пишет: После прокачки истории ошибка исчезла ..... Это первое К сожалению, Вы столкнулись с ложной корреляцией. Причиной, по которой ошибка пропала, является отсутствие сигналов на модификацию ордеров в тех местах, которые ранее приводили к ошибкам. Но суть осталась прежней - сравнение вещественных чисел. voldemar227 пишет: А второе по поводу ваших котировок , сделал все по инструкции , даже виндовс с ноля переставил и не работают они , у вас котировки либо уже не совместимы с терминалом либо битые....... Не могли бы Вы описать ситуацию подробнее? Что подразумевается под словами "несовместимые" и "битые"? На каком этапе Вы сталкиваетесь с проблемой? С каким символом возникают проблемы?

voldemar227: Вечером запишу видео что и как я делал. Но котировки не прогружлись ,

voldemar227: Как и обещал вот видео тестирование запустил с 2001 года а тест пошол с мая 2002 ... Что удивительно так как раньше тест шол только с 2010 г http://www.youtube.com/watch?v=Rwjv7ryN-cw

SK: МТ 4 работает с теми историческими котировками, которые считывает с диска сразу после включения. Чтобы обновлённая история вступила в силу, нужно выключить (будет создан новый hst файл) и включить (новый hst файл будет прочитан) МТ 4.

Scriptong: voldemar227 пишет: Как и обещал вот видео тестирование запустил с 2001 года а тест пошол с мая 2002 ... Что удивительно так как раньше тест шол только с 2010 г http://www.youtube.com/watch?v=Rwjv7ryN-cw Добрый день. Вы загрузили котировки графика М1, а тестирование производите на таймфрейме Н1. Данных для таймфрейма Н1 попросту нет. В итоге данные по Н1 терминал сгенерировал сам. На основании чего он это сделал - неизвестно. Для получения котировок по таймфрейму Н1 на основании загруженных Вами данных необходимо воспользоваться штатным скриптом period_converter. Об этом также написано в статье "История котировок". Между операциями импорта котировок и запуском скрипта необходимо перезагрузить МТ4, т.к. файл hst, необходимый для работы скрипта, сбрасывается на диск только при закрытии терминала.

voldemar227: функция вызывается на каждом тике и должна усреднить два ордера по двум тикетам int usr (string t, int x, int m1, int m2) { double nn=0,bb=0; int i=0; if ( t=="" ) t=Symbol(); for(i=OrdersTotal()-1; i>=0; i--) if(OrderSelect(i,SELECT_BY_POS)) if(OrderSymbol()==t) if(OrderType()==x)//&&(OrderTicket()==m1||OrderTicket()==m2||m1==-1&&m2==-1)) {Comment(t); bb+=OrderOpenPrice()*OrderLots(); nn+=OrderLots() ; } for(i=OrdersTotal()-1; i>=0; i--) if(OrderSelect(i,SELECT_BY_POS)) if(OrderSymbol()==t) if(OrderType()==x)//&&(OrderTicket()==m1||OrderTicket()==m2||m1==-1&&m2==-1)) { if (OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),NormalizeDouble(bb/nn,Digits),0,Gold)==true) return(0);else return (GetLastError()); } } но почему то усредняется только один ... даже при отключеной проверке на тикеты модифицируется только один ордер . В чем проблема понять не могу ....

Scriptong: voldemar227 пишет: но почему то усредняется только один Потому что после проведения первой же модификации, независимо от успешности операции, происходит выход из функции. Функция возвращает либо 0, либо код ошибки после операции модификации.

voldemar227: Scriptong пишет: X = ((sellPrice - spread)*sellVolume - buyPrice*buyVolume)/(sellVolume - buyVolume) то есть правильно ли я понял Мы цену каждого ордера по типу бай умножаем на его лот и суммируем в заданной переменной Так же мы цену каждого ордера по типу селл умножаем на его лот и суммируем в заданной переменной затем производим вычитание , Не могу понять почему мы делаем вычитание ??? И почему мы от селл лотов вычитаем бай лоты ???



полная версия страницы