1 (2013-01-18 09:20:01 отредактировано zyanov)

Тема: Формирование цен в примере

Не могу разобратсья с  [url=https://quik2dde.ru/viewtopic.php?id=22/]примером[/url]. Для сбера округляет  дробную часть 93,30=>93.У лукойла нормально.  Помогите сделать универсальный формировщик цен для всех бумаг.

-- Сформировать цену в строковом представлении с учетом PRICE_SCALE
function MakeStringPrice(price)

  local n,m = math.modf(price)
  n = tostring(n)
  if PRICE_SCALE > 0 then
    m = math.floor(m * 10^PRICE_SCALE + 0.01)
    if m > 0.01 then
      m = string.sub(tostring(m), 1, PRICE_SCALE)
      m = string.rep('0', PRICE_SCALE - string.len(m)) .. m
    else
      m = string.rep('0', PRICE_SCALE)
    end
    m = '.' .. m
  else
    m = ''
  end
  
  return (n .. m)

end

2 (2013-01-18 10:25:51 отредактировано mbul)

Re: Формирование цен в примере

С примером разбираться неохота. Вот такое есть решение, широко распространенное в мире скриптовых языков (например в перле)

function apply_scale(value, scale)
    return string.format("%."..tostring(scale) .."f", value)
end

x = 1.23456
print(x)
print(apply_scale(x, 2))
x = 1.23756
print(x)
print(apply_scale(x, 2))
print(apply_scale(x, 3))
x=1.22
print(apply_scale(x, 9))

результат:

1.23456
1.23
1.23756
1.24
1.238
1.220000000

как видно, округляется корректно, по математическим правилам

3

Re: Формирование цен в примере

спасибо очень помогло

4

Re: Формирование цен в примере

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

mbul,
спасиб за подсказку. Ваш пример действительно мнооого короче моего )
Причем он правильно работает и для скейла 0 (не выводит точку), я только для этого выдумал такой большой код, а оказывается, все можно сделать много проще.

5

Re: Формирование цен в примере

local math_floor = math.floor
--
local doStep = function (val, step)
    return math_floor(val/step)*step
end

как минимум в 14 раз быстрее, чем " return string.format("%."..tostring(scale) .."f", value) "

6 (2015-06-05 19:06:22 отредактировано swerg)

Re: Формирование цен в примере

kalikazandr,

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

7

Re: Формирование цен в примере

swerg пишет:

kalikazandr,

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

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

8 (2015-06-06 23:29:51 отредактировано swerg)

Re: Формирование цен в примере

А, получается вы не от точности цены (скейла) идёте, а от шага цены. Теперь понял. И про дробные значения цены я, конечно, тогда наврал, всё с ними в порядке.
Да, тоже вариант, наверное даже более удобный в торговле.

9

Re: Формирование цен в примере

я пол дня потратил на создание этой функции ))

10 (2015-07-26 11:12:27 отредактировано CyberTrader)

Re: Формирование цен в примере

kalikazandr пишет:
local math_floor = math.floor
--
local doStep = function (val, step)
    return math_floor(val/step)*step
end

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

print(doStep(100, 0.1)) --> 100 (должно быть "100.0")

11 (2015-07-26 12:01:54 отредактировано kalikazandr)

Re: Формирование цен в примере

CyberTrader пишет:

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

print(doStep(100, 0.1)) --> 100 (должно быть "100.0")

А вы попробуйте, а потом пишите.
Строковое представление цены нужно для цен, в которых scale > 4.
"100" и "100.0" и "100.0000" на сервере биржи будут равны 100
Или вы не знали об этом? Плохо, учите мат.часть.
Вот вам пример:

d = 0.00005
print(d) --> 5e-005
d= 0.0005
print(d) --> 0.0005

Поэтому и только поэтому нужно строковое представление числа.
Если вам не нравится мой способ, да флаг вам в руки - не пользуйтесь.

12 (2015-07-26 16:09:38 отредактировано CyberTrader)

Re: Формирование цен в примере

kalikazandr пишет:

"100" и "100.0" и "100.0000" на сервере биржи будут равны 100

Ерунда. Если шаг цены = 0.1, то при "PRICE = "100.0000" вы получите сообщение об ошибке:

Неправильно указана цена: "100.0000"
Сообщение об ошибке: Превышено допустимое число знаков после разделителя дробной части

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

kalikazandr пишет:

Строковое представление цены нужно для цен, в которых scale > 4.

d = 0.00005
print(d) --> 5e-005

Соответственно, при конвертации числа в строку разница в скорости по сравнению с вариантом из [url=https://quik2dde.ru/viewtopic.php?pid=85#p85]поста 2[/url] будет уже не в 14 раз, а ~17% (при оптимизации).
К тому же, там округление по математическим правилам, а у вас тупо отбрасывание лишних знаков.
Но вы не обижайтесь: я ж справедливую критику даю.

13

Re: Формирование цен в примере

CyberTrader пишет:

К тому же, там округление по математическим правилам, а у вас тупо отбрасывание лишних знаков.

Зачем обижаться? Я, иногда, (зачастую) туплю, особенно, когда под шафе.
Кому нужны математические правила (и кто знает арифметику за 5 класс), тот ТупО сделал так:
return math_floor(val/step + 0.5)*step

14

Re: Формирование цен в примере

CyberTrader пишет:

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

kalikazandr пишет:

Строковое представление цены нужно для цен, в которых scale > 4.

d = 0.00005
print(d) --> 5e-005

100% именно из-за этой особенности требуется строковое представление числа

15 (2015-07-26 17:02:10 отредактировано CyberTrader)

Re: Формирование цен в примере

Выше я написал, почему цену переводят в строковое представление: чтобы не получить ошибку:

Сообщение об ошибке: Превышено допустимое число знаков после разделителя дробной части

или

Сообщение об ошибке: Число не может содержать знак разделителя дробной части

Попробуйте отправить транзакцию:

local transaction = {
    TRANS_ID = '1',
    ACTION = "NEW_ORDER",
    ACCOUNT = sAccount,
    CLIENT_CODE = sClientCode,
    CLASSCODE = 'QJSIM',
    SECCODE = 'LKOH',
    OPERATION = 'B',
    TYPE = "L",
    PRICE = doStep(2450.2, 0.1),
    QUANTITY = '1'
  }

Мало того, что функция doStep формирует неправильную цену, так получите ещё ошибку:

Неправильно указана цена: "2450.100000"
Сообщение об ошибке: Превышено допустимое число знаков после разделителя дробной части

Видимо, кто-то плохо учил мат.часть lol

И для общего развития: транзакция с параметром

PRICE = 5e-005

при pricestep<=0.000005 нормально отправляется на сервер. (Другое дело, что цена должна попадать в установленный диапазон.)

Если параметр задан числом, то функция sendTransaction сама преобразует его в строку с точностью 6 знаков после запятой. Поэтому для бумаг с меньшей точностью цен, чтобы не получить ошибку, необходима принудительная конвертация.

16

Re: Формирование цен в примере

Вы видите, что возвращает функция в качестве результата? Строку или число?
Зачем делать, скажем так, "дурацкие" примеры?
Я же говорил, не нравится - не пользуйтесь, не умеете применить функцию - спросите, расскажу как, чтобы сообщений с подобными ошибками не возникало.
Вам в описании функции sendTransaction ясно дали понять, что цена должна быть в строковом представлении, а не в числовом, а вы лепите туда число.
Ну хз, как еще объяснить? Давайте не будем больше об этом беседовать?

17 (2015-07-26 19:19:47 отредактировано CyberTrader)

Re: Формирование цен в примере

kalikazandr пишет:
d = 0.00005
print(d) --> 5e-005
d= 0.0005
print(d) --> 0.0005

Поэтому и только поэтому нужно строковое представление числа.

Это чьи слова, мои или ваши?

Я же вам выше чёрным по-русски написал:

CyberTrader пишет:

Строковое представление цены нужно для формирования транзакции при отправке на сервер

Зачем теперь дурачком прикидываться?

18

Re: Формирование цен в примере

CyberTrader пишет:

Зачем теперь дурачком прикидываться?

Пусть будет по вашему, я не буду вами прикидываться.