Свопы в mql4

 

Пытаюсь рассчитать своп, но не получается

Вот код который выводит свопы 20 последних сделок.

for ( j=OrdersHistoryTotal( )-1; j>=OrdersHistoryTotal( )-21; j--) {
OrderSelect(j, SELECT_BY_POS, MODE_HISTORY);
if(OrderType()==OP_BUY)
Print(OrderSwap()+" "+MarketInfo(OrderSymbol(),MODE_SWAPLONG)*MarketInfo(OrderSymbol(),MODE_BID)*OrderLots()*MarketInfo(OrderSymbol(),MODE_TICKVALUE));
if(OrderType()==OP_SELL)
Print(OrderSwap()+" "+MarketInfo(OrderSymbol(),MODE_SWAPSHORT)*MarketInfo(OrderSymbol(),MODE_BID)*OrderLots()*MarketInfo(OrderSymbol(),MODE_TICKVALUE));
}


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

Почему то отличие кратно именно 10.

То есть расчетный своп в 10 раз превышает реальный.

Сам уже не могу догадаться в чем тут дело.

 
Наверное все дело в том, что расчетный своп дается для целого лота, а ваши сделки были 0.1 лота
 
Scriptong писал(а) >>
Наверное все дело в том, что расчетный своп дается для целого лота, а ваши сделки были 0.1 лота

Мои сделки были по 0.46, 0.46 и 0.34 лота.

Поэтому, если убрать из кода OrderLots(), то результат станет вообще неузнаваемым.

MarketInfo(OrderSymbol(),MODE_SWAPTYPE) возвращает единицу, то есть

«Метод вычисления свопов 1 - в базовой валюте инструмента;»

Я беру значения свопа в пунктах, которое возвращает

MarketInfo(OrderSymbol(),MODE_SWAPLONG)

Умножаю это значение на Bid,

*MarketInfo(OrderSymbol(),MODE_BID)

затем на размер лота

*OrderLots()

и умножаю на ценность одного пункта в валюте депозита с одного лота

*MarketInfo(OrderSymbol(),MODE_TICKVALUE)

Возвращаются такие значения:

EURGBP ЛОТ = 0.46000000 РЕАЛЬНЫЙ СВОП = -1.31000000 РАСЧЕТНЫЙ СВОП -13.05244609

Вот код

for ( int j=OrdersHistoryTotal( )-1; j>=OrdersHistoryTotal( )-21; j--) {
OrderSelect(j, SELECT_BY_POS, MODE_HISTORY);
if(OrderType()==OP_BUY)
Alert(OrderSymbol()+" ЛОТ = "+OrderLots()+" РЕАЛЬНЫЙ СВОП = "+OrderSwap()+" РАСЧЕТНЫЙ СВОП "+MarketInfo(OrderSymbol(),MODE_SWAPLONG)*MarketInfo(OrderSymbol(),MODE_BID)*OrderLots()*MarketInfo(OrderSymbol(),MODE_TICKVALUE));
if(OrderType()==OP_SELL)
Alert(OrderSymbol()+" ЛОТ = "+OrderLots()+" РЕАЛЬНЫЙ СВОП = "+OrderSwap()+" РАСЧЕТНЫЙ СВОП "+MarketInfo(OrderSymbol(),MODE_SWAPSHORT)*MarketInfo(OrderSymbol(),MODE_BID)*OrderLots()*MarketInfo(OrderSymbol(),MODE_TICKVALUE));
}

 
vasya_vasya писал(а) >>

«Метод вычисления свопов 1 - в базовой валюте инструмента;»

Я беру значения свопа в пунктах, которое возвращает


-----------------------------------------------------------------------------------------------


зачем ты в пунктах то берешь если в базовой валюте инструмента

раз своп в базовой валюте, а депозит в usd то (для eurgbp) надо умножать на MarketInfo("EURUSD",MODE_BID)

и зачем вообще MODE_TICKVALUE (еще раз в базовой валюте а не в пунктах!)

хотя это тоже не совсем корректно для истории

по хорошему надо найти цену для EURUSD в этот момент времени и умножать на неё

и вообще надо период учитывать сколько дней начислялся своп

если ничего не напутал то для одного дня так (не со среды на четверг)

sw=MarketInfo(OrderSymbol(),MODE_SWAPLONG)*OrderLots()*MarketInfo("EURUSD",MODE_BID);

 
kaisa писал(а) >>
vasya_vasya писал(а) >>

«Метод вычисления свопов 1 - в базовой валюте инструмента;»

Я беру значения свопа в пунктах, которое возвращает

-----------------------------------------------------------------------------------------------

зачем ты в пунктах то берешь если в базовой валюте инструмента

раз своп в базовой валюте, а депозит в usd то (для eurgbp) надо умножать на MarketInfo("EURUSD",MODE_BID)

и зачем вообще MODE_TICKVALUE (еще раз в базовой валюте а не в пунктах!)

хотя это тоже не совсем корректно для истории

по хорошему надо найти цену для EURUSD в этот момент времени и умножать на неё

и вообще надо период учитывать сколько дней начислялся своп

если ничего не напутал то для одного дня так (не со среды на четверг)

sw=MarketInfo(OrderSymbol(),MODE_SWAPLONG)*OrderLots()*MarketInfo("EURUSD",MODE_BID);

и зачем вообще MODE_TICKVALUE (еще раз в базовой валюте а не в пунктах!)

Спасибо за ответ

MODE_TICKVALUE взят с вполне конкретными целями

Я исходил из предположения, что

MarketInfo(OrderSymbol(),MODE_TICKVALUE)

Содержит в себе котировку GBPUSD

То есть, чтобы сделать EURUSD, нужно EURGBP * GBPUSD

А EURGBP это и есть цена бид, а GBPUSD должна быть в

MarketInfo(OrderSymbol(),MODE_TICKVALUE)

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

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

Итоговая формула выглядит так

MarketInfo(OrderSymbol(),MODE_SWAPLONG)*OrderLots()*MarketInfo(OrderSymbol(),MODE_BID)*MarketInfo(OrderSymbol(),MODE_TICKVALUE)/( MarketInfo(OrderSymbol(),MODE_POINT)*MarketInfo(OrderSymbol(),MODE_LOTSIZE));

Я сравнил оба способа, результаты разумеется иногда отличаются на тысячные доли.

Сравнил производительность 1000 циклов вашего и моего кода, мой код оказался быстрее

TIME1 = 1203 миллилсек

TIME2 = 891 миллилсек

код

//ВАШЕ

double kk1;
string Symb;
int time0,time4,dif2;
time0=GetTickCount();
for( int mm=0;mm<1000;mm++){
for ( j=OrdersHistoryTotal( )-1; j>=0; j--) {
OrderSelect(j, SELECT_BY_POS, MODE_HISTORY);
if(OrderSwap()!=0){
Symb=StringSubstr(OrderSymbol(),0,3)+AccountCurrency( );
GetLastError();MarketInfo(Symb,MODE_TRADEALLOWED);
int error=GetLastError();
if(error!=4108){ kk1=MarketInfo(Symb,MODE_BID);}else{
Symb=AccountCurrency( )+StringSubstr(OrderSymbol(),0,3);
GetLastError();MarketInfo(Symb,MODE_TRADEALLOWED);
error=GetLastError();
if(error!=4108){ kk1=1/MarketInfo(Symb,MODE_BID);}}
if(StringSubstr(OrderSymbol(),0,3)==AccountCurrency( )){kk1=1;}
double ff,ff1;
if(OrderType()==OP_BUY){
ff1=MarketInfo(OrderSymbol(),MODE_SWAPLONG)*OrderLots()*kk1;
time4=GetTickCount();
}
if(OrderType()==OP_SELL){
ff1=MarketInfo(OrderSymbol(),MODE_SWAPSHORT)*OrderLots()*kk1;
time4=GetTickCount();
}}} }
dif2=time4-time0;
Alert(" TIME1 = "+dif2);

//МОЕ
time0=GetTickCount();
for( mm=0;mm<1000;mm++){
for ( j=OrdersHistoryTotal( )-1; j>=0; j--) {
OrderSelect(j, SELECT_BY_POS, MODE_HISTORY);
if(OrderSwap()!=0){
if(OrderType()==OP_BUY){
ff=MarketInfo(OrderSymbol(),MODE_SWAPLONG)*OrderLots()*MarketInfo(OrderSymbol(),MODE_BID)*MarketInfo(OrderSymbol(),MODE_TICKVALUE);
ff=ff/MarketInfo(OrderSymbol(),MODE_POINT)/MarketInfo(OrderSymbol(),MODE_LOTSIZE);
time4=GetTickCount();
}
if(OrderType()==OP_SELL){
ff=MarketInfo(OrderSymbol(),MODE_SWAPSHORT)*OrderLots()*MarketInfo(OrderSymbol(),MODE_BID)*MarketInfo(OrderSymbol(),MODE_TICKVALUE);
ff=ff/MarketInfo(OrderSymbol(),MODE_POINT)/MarketInfo(OrderSymbol(),MODE_LOTSIZE);
time4=GetTickCount();
}}}}
dif2=time4-time0;
Alert(" TIME2 = "+dif2);

И это не говоря о том, что мой код гораздо короче.

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

CHFNOK -16.96000000 -5.60063204 0.00000000 3 4 1.00000000

3, 4 - дни недели, 1 – метод расчета свопа, 16.96 – реальный своп, 5.6 – своп через тиквэлью, 0 – своп без тиквэлью.

Вот код

for ( j=OrdersHistoryTotal( )-1; j>=0; j--) {
OrderSelect(j, SELECT_BY_POS, MODE_HISTORY);
if(OrderSwap()!=0){
Symb=StringSubstr(OrderSymbol(),0,3)+AccountCurrency( );
GetLastError();MarketInfo(Symb,MODE_TRADEALLOWED);
error=GetLastError();
if(error!=4108){ kk1=MarketInfo(Symb,MODE_BID);}else{
Symb=AccountCurrency( )+StringSubstr(OrderSymbol(),0,3);
GetLastError();MarketInfo(Symb,MODE_TRADEALLOWED);
error=GetLastError();
if(error!=4108){ kk1=1/MarketInfo(Symb,MODE_BID);}}
if(StringSubstr(OrderSymbol(),0,3)==AccountCurrency( )){kk1=1;}
if(OrderType()==OP_BUY){
ff1=MarketInfo(OrderSymbol(),MODE_SWAPLONG)*OrderLots()*kk1;
ff=MarketInfo(OrderSymbol(),MODE_SWAPLONG)*OrderLots()*MarketInfo(OrderSymbol(),MODE_BID)*MarketInfo(OrderSymbol(),MODE_TICKVALUE);
ff=ff/MarketInfo(OrderSymbol(),MODE_POINT)/MarketInfo(OrderSymbol(),MODE_LOTSIZE);
Alert(OrderSymbol()+" "+OrderSwap()+" "+ff+" "+ff1+" "+TimeDayOfWeek(OrderOpenTime()) +" "+TimeDayOfWeek(OrderCloseTime()) +" "+MarketInfo(OrderSymbol(),MODE_SWAPTYPE)+" ");
}
if(OrderType()==OP_SELL){
ff1=MarketInfo(OrderSymbol(),MODE_SWAPSHORT)*OrderLots()*kk1;
ff=MarketInfo(OrderSymbol(),MODE_SWAPSHORT)*OrderLots()*MarketInfo(OrderSymbol(),MODE_BID)*MarketInfo(OrderSymbol(),MODE_TICKVALUE);
ff=ff/MarketInfo(OrderSymbol(),MODE_POINT)/MarketInfo(OrderSymbol(),MODE_LOTSIZE);
Alert(OrderSymbol()+" "+OrderSwap()+" "+ff+" "+ff1+" "+TimeDayOfWeek(OrderOpenTime()) +" "+TimeDayOfWeek(OrderCloseTime()) +" "+MarketInfo(OrderSymbol(),MODE_SWAPTYPE)+" ");
}}}

достаточно странно, что она возвратила ноль, при расчете вашим методом, поэтому возможно его нельзя применять в принципе.

возможно вы знаете формулу рачета свопа через пункты, когда

MarketInfo(OrderSymbol(),MODE_SWAPTYPE)=0

 

Василий давай на ты?

Давай уж как нибуть эту тему добьем.

Для тех компаний у которых swaptype = 0 или 1 я считаю так

// расчет свопа для одного лота
// не для тех компаний у которых используется rollower (MRC,Life и т.д)
// валюта счета USD
void start() {
   string symbolName;
   int    oper;
   symbolName="NZDJPY";  
   oper      =OP_BUY;
   Print("Своп для пары ",symbolName," ",CalkSwapUSD(symbolName,oper)," USD ",oper);
   oper      =OP_SELL;
   Print("Своп для пары ",symbolName," ",CalkSwapUSD(symbolName,oper)," USD ",oper);
  
}
//+------------------------------------------------------------------+
double CalkSwapUSD(string symbolName,int oper){
   double swap;
   int    swapType    = MarketInfo(symbolName,MODE_SWAPTYPE);
   string symbolFirst = StringSubstr(symbolName,0,3);    
   string symbolCombi = symbolFirst+"USD";    
   double swapOper;
  
   if (oper==OP_BUY){
      swapOper = MarketInfo(symbolName,MODE_SWAPLONG);
   }
   else {  
      swapOper = MarketInfo(symbolName,MODE_SWAPSHORT);
   }   
   switch (swapType){
      case 0:   // в пунктах 
         swap = swapOper*MarketInfo(symbolName,MODE_TICKVALUE);
         break;
      case 1:   // в базовой валюте ордера
         if (symbolFirst=="USD"){
            swap = swapOper;
         }   
         else {
            swap = swapOper*MarketInfo(symbolCombi,MODE_BID); 
         }
         break;
      case 2:   // в процентах
          //  swap = (100000*(swapOper/100)/360)*b;
         break;
      case 3:    // в валюте залоговых средств
 
         break;  
   } 
   return(swap);
}

остаются 2 и 3

не могу сейчас найти у кого так считается что-бы проверить (может подскажет кто)

меня просто жутко интересуют свопы

 
kaisa >>:

Василий давай на ты?

Давай уж как нибуть эту тему добьем.

Для тех компаний у которых swaptype = 0 или 1 я считаю так

остаются 2 и 3

не могу сейчас найти у кого так считается что-бы проверить (может подскажет кто)

меня просто жутко интересуют свопы



А вы не пробовали прверить свои расчеты? Я имею ввиду - сделать проверку - сравнить OrderSwap и ваши расчеты? Так же можно проверить так - взять OrderSwap и разделить на MODE_TICKVALUE, чтобы получить значение в пунктах.

 

По поводу свопов в процентах вот нашел https://www.mql5.com/ru/forum/118012

Некорректное вычисление свопа в процентах?
Некорректное вычисление свопа в процентах?
  • 2009.06.11
  • www.mql5.com
Ситуация такая. Имеем инструмент, у которого MODE_SWAPTYPE равен 2 (т.е. своп вычисляется в процентах...
Причина обращения: