Глюк терминала

 

Понадобилось поработать на "пятизнаке". Пошёл на сайт Альпари, скачал терминал, установил, открыл демосчёт. Далее начинаем эксперименты. Пишем скрипт:

int start(){
   string s_PNT;
   double d_PNT;
   Alert("Digits = ",Digits);
   s_PNT=DoubleToStr(Point,Digits);
   Alert("s_PNT = ",s_PNT);
   d_PNT=StrToDouble(s_PNT);
   Alert("d_PNT = ",d_PNT);
   Alert("============= ",Symbol()," =============");
   return(0);
}

Логика работы скрипта:

Чтоб получить корректное, автоматически распознаваемое значение переменной Point, вгоняем её значение в строку, округляем до дигитса и перегоняем в вещественное число. Вроде должно сработать. Ну а чтоб видеть результат работы скрипта  НА КАЖДОМ его этапе, после выполнения этого самого этапа снимаем дамп данный тем же Алертом.

Скрипт готов. Кидаем его на график фунта и что мы видим?


Что это, господа разработчики? Может я в чём-то не прав?

Вот тот торговый счёт, на котором я тестил данный скрипт

Вас приветствует Компания «Альпари»!
Благодарим Вас за открытие ДЕМО-счета в нашей компании.
Реквизиты Вашего счета:

    • Логин: 1905782
    • Основной пароль: daca8mc
    • Пароль инвестора: mxxe6hz(только просмотр)

    Попробуйте сами.

    Возникает как и обычно вопрос, так как всё-таки обрабатывать котировки, у которых не 4, а 5 чисел после запятой?



     

    void Alert( ...)
    Отображает диалоговое окно, содержащие пользовательские данные. Параметры могут быть любого типа. Количество параметров не может превышать 64.



    Массивы нельзя передавать в функцию Alert(). Массивы должны выводиться поэлементно.

    Данные типа double выводятся с 4 десятичными цифрами после точки.
    Для вывода чисел с большей точностью используйте функцию DoubleToStr().
    Данные типы bool, datetime и color будут выведены как числа.
    Чтобы вывести данные типа datetime в виде строки, необходимо использовать функцию TimeToStr().


    Может в этом и проблема? Пятый знак не был воспринят в строке

    Alert("d_PNT = ",d_PNT);


    Поясните ещё раз - что нужно получить? Простите, но что-то Вы делаете тут через одно место.


     

    Вы все правильно написали - 5-й знак double не выводится, потому что он и не должен выводится в Alert. Элементарная ошибка. Правда, при чем тут 5-й знак и его использование - непонятно - согласен. Разве что в использование в Alert? Ну тогда зачем было выводить дабл, когда уже есть готовый стринг, который и положено, если нужен разряд после 4-го, использовать.

     
    Parabellum >>:


    Может в этом и проблема? Пятый знак не был воспринят в строке


    Поясните ещё раз - что нужно получить? Простите, но что-то Вы делаете тут через одно место.




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

    Предопределённая переменная Point на пятизнаке имеет какое значение? И насколько корректно это значение?

    НЕТУ ОТЛАДЧИКА!!!! Вот и вынуждены смотреть всякими алертами, что же там лежит в переменных.

    >> Может в этом и проблема? Пятый знак не был воспринят в строке

    Может. Я кстати и не знал, что там переменные типа double выводят 4 знака после запятой. За эту инфу спасибо. Оказывается что Comment() и Print() тож выводят данные в таком же формате.

    Нужно теперь ещё попробовать выводить данные не на экран и не принтовать, а записывать их вовнутрь текстового документа. Если там данные выводятся корректно, то это лучше, чем использование алерта. Хотя и тоже через то самое место. :)


     

    Напрограммился (читай намучился) уже я с этой разрядностью в своё время по самое нихочу. Вот и осторожничаешь там, где по-идее не следовало бы.

    Неоднократно возникали ошибки в конструкциях типа

    doble PR;

    PR=Bid;

    Короче в функции OrderSend() ставишь цену установки того же шорта = Bid, а советник возвращает ошибку не верной цены установки ордера. И с проскальзыванием у тебя всё нормально, и ошибок вроде нет... и рынок спокоен как удав.... Начинаешь искать. Перед самым вызовом функции OrderSend() пишешь:

    Alert("Bid = ",Bid);

    Кидаешь советника на евробакс и получаешь чудеса алетра типа

     Bid = 1.235000000001. (Лайтфорекс мне выдавал одно время такие котировки)

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

    doble PR;

    PR=Bid;

    PR=NormalizeDouble(PR,Digits);

    OrderSend(.. и тут уже пишешь не Bid, а PR)

    И, о чудо!!! ВСЁ работает как положенно...



     

    Продолжаем изощряться. Переписываем скрипт:

    //+------------------------------------------------------------------+
    //| script program start function                                    |
    //+------------------------------------------------------------------+
    int start(){
       
       string   FileName,TextInFile;
       int      FileHandlе;
       
       string s_PNT;
       double d_PNT;
       
       FileName=Symbol()+"_"+DoubleToStr(Day(),0)+"_"+DoubleToStr(Month(),0)+"_"+DoubleToStr(Year(),0)+".txt";
       
       TextInFile=TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS);
       TextInFile=TextInFile+" ============ "+Symbol()+" ============";
       WritingLineInFile(FileName,TextInFile);
       
       TextInFile=TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS);
       TextInFile=TextInFile+" Digits = "+Digits;
       WritingLineInFile(FileName,TextInFile);
       
       TextInFile=TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS);
       TextInFile=TextInFile+" Point = "+Point;
       WritingLineInFile(FileName,TextInFile);
       
       s_PNT=DoubleToStr(Point,Digits);
       
       TextInFile=TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS);
       TextInFile=TextInFile+" s_PNT = "+s_PNT;
       WritingLineInFile(FileName,TextInFile);
       
       d_PNT=StrToDouble(s_PNT);
       
       TextInFile=TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS);
       TextInFile=TextInFile+" d_PNT = "+d_PNT;
       WritingLineInFile(FileName,TextInFile);
       
       return(0);
    }
    //+------------------------------------------------------------------+
    
    //+------------------------- WritingLineInFile() ----------------------------
    //| Дописывание строки в конец файла
    //+---------------------------------
    void WritingLineInFile(string FlName, string Text){
      int file_handle=FileOpen(FlName, FILE_CSV|FILE_READ|FILE_WRITE, " ");
    	if (file_handle>0){
    		FileSeek(file_handle,0,SEEK_END);
    		FileWrite(file_handle,Text);
    		FileClose(file_handle);
    	}
    	else{
    	  Print("Ошибка ",GetLastError()," - Не удалось открыть файл ",FlName);
       }
    }
    //--------------------------------------------------------------------------- 

    Компилируем, кидаем на график. Открываем только что созданный текстовый документ и что мы видим:

    2009.10.06 00:41:47 ============ GBPUSD ============
    2009.10.06 00:41:47 Digits = 5
    2009.10.06 00:41:47 Point = 0.00001000
    2009.10.06 00:41:47 s_PNT = 0.00001
    2009.10.06 00:41:47 d_PNT = 0.00001000

    Прекрасно. Просто расчудесно. Переменную d_PNT, проинициализированную Point-ом что теперь нужно в блоке инициализации округлять до дигитса?

     
    Почему вы не используете нормализацию? Она ведь именно для этого. Зачем делаете обратное преобразование из стринга в дабл? Зачем все это вы проделываете, где применить хотите?
     
    Svinozavr >>:
    Почему вы не используете нормализацию? Она ведь именно для этого. Зачем делаете обратное преобразование из стринга в дабл? Зачем все это вы проделываете, где применить хотите?


    Чтоб применять нормализацию, нужно сперва разобраться какие из значений нужно нормализовывать и до какого предела. Вот в этом-то я и попытался разобраться. Если бы вы мне тут на форуме не указали, что Alert(), Print() и Comment() автоматически округляют значения типа double до 4 знаков после запятой, то я наверно ещё долго не мог бы понять почему Alert("Point = ",Point); выдаёт в результате ноль на пятизнаке.

    Мне и в голову не могло прийти, что вывод значения переменной на экран может быть автоматически округлён. Ладно я понимаю, когда в переменную кто-то пытается впихнуть значение больше/меньше, чем предопределено для переменной самим языком - впихнуть невпихуемое. Тут я вполне бы понял обрезку числа знаков после запятой. Но не в обычном же выводе значения переменной на экран!!! Нормальной переменной с нормальным значением, не превышающим предельно допустимого!

    Короче, понял я что к чему - нужно выводить в файл полностью всю информацию о торговом инструменте (размер пункта, тиксайз, спред и так далее), смотреть полученные значения и думать, как их обрабатывать програмно, чтоб на трёх- и пяти-знаке советник/индикатор/скрипт работал корректно и автоматически распознавал всё, что ему нужно.

    Ещё раз спасибо за подсказку.

     

    Посколь мы пишем в файл текст, то это нам поможет:

    TextInFile=TextInFile+" Point = "+DoubleToStr(Point, Digits);
    //...
    TextInFile=TextInFile+" d_PNT = "+DoubleToStr(d_PNT, Digits);

    Результат записи:

    2009.10.06 02:59:16 ============ EURUSD ============
    2009.10.06 02:59:16 Digits = 5
    2009.10.06 02:59:16 Point = 0.00001
    2009.10.06 02:59:16 s_PNT = 0.00001
    2009.10.06 02:59:16 d_PNT = 0.00001


    С добавкой:

       TextInFile=TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS);
       TextInFile=TextInFile+" Bid = "+DoubleToStr(Bid, Digits);
       WritingLineInFile(FileName,TextInFile);


    2009.10.06 03:03:03 ============ USDJPY ============
    2009.10.06 03:03:03 Digits = 3
    2009.10.06 03:03:03 Point = 0.001
    2009.10.06 03:03:03 s_PNT = 0.001
    2009.10.06 03:03:03 d_PNT = 0.001
    2009.10.06 03:03:03 Bid = 89.133
    2009.10.06 03:02:01 ============ EURUSD ============
    2009.10.06 03:02:01 Digits = 5
    2009.10.06 03:02:01 Point = 0.00001
    2009.10.06 03:02:01 s_PNT = 0.00001
    2009.10.06 03:02:01 d_PNT = 0.00001
    2009.10.06 03:02:01 Bid = 1.46904

     
    kombat >>:

    Посколь мы пишем в файл текст, то это нам поможет:

    Блин, да есть уже это значение в стринге - s_PNT. Чего по десять раз гонять из дабла в стринг и потом обратно?

    Да и не об этом речь. Чего автор хочет добиться этим скриптом? Выяснить, что нужно нормализовать? Ну, можно считать, что выяснил.

     
    Svinozavr >>:

    Блин, да есть уже это значение в стринге - s_PNT. Чего по десять раз гонять из дабла в стринг и потом обратно?

    Да и не об этом речь. Чего автор хочет добиться этим скриптом? Выяснить, что нужно нормализовать? Ну, можно считать, что выяснил.

    Насколько понял, автор хочет писать даблы красивым образом.

    Что и достигается простым :

    DoubleToStr(Bid, Digits);
    А ежли хоцца разбора с дигитсом, то и юзай себе DoubleToStr(дабл, Digits); да NormalizeDouble(дабл, Digits); в удовольствие,
    и в нужном месте... ;)
    Здесь например оно явно излишне:

    FileName=Symbol()+"_"+DoubleToStr(Day(),0)+"_"+DoubleToStr(Month(),0)+"_"+DoubleToStr(Year(),0)+".txt";


    Причина обращения: