sergei (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: 1 2 След.
Автоматизация процесса добавления lua-скрипта в QUIK и его запуска, Автоматизация процесса добавления lua-скрипта в QUIK и его запуска
 
Цитата
Вряд ли. Есть простое решение. Работающие скрипты не перестают работать, если закрыть QUIK, потом опять открыть и законнектиться. Можно сделать "загрузчик", который будет отслеживать какой-то файл. Этот файл может содержать название lua-скрипта для загрузки, либо непосредственно сам код.
В смысле, этот загрузчик должен будет "вставить в себя" ваш скрипт, т.е. выполняться будет только загрузчик постоянно.
Автоматизация процесса добавления lua-скрипта в QUIK и его запуска, Автоматизация процесса добавления lua-скрипта в QUIK и его запуска
 
Цитата
Николай Зятьков написал:
Добрый день!

Возможно ли работать с QUIK из командной строки Windows?
В частности, интересует автоматизация процесса добавления lua-скрипта в QUIK и его запуска. Возможно ли это?
Вряд ли. Есть простое решение. Работающие скрипты не перестают работать, если закрыть QUIK, потом опять открыть и законнектиться. Можно сделать "загрузчик", который будет отслеживать какой-то файл. Этот файл может содержать название lua-скрипта для загрузки, либо непосредственно сам код.
Как узнать id поданной заявки?
 
Цитата
Андрей написал:
Также, хотел бы спросить, не будет ли убытка в случае операции подачи заявки и практически моментального снятия?  
Скорость снятия никаких "санкций" не может повлечь. Однако, если алгоритм предполагает, что вы будете дрючить биржу валом заявок, то можете попасть за штраф за т.н. "неэффективные транзакции". Это когда число заявок огромно (насколько помню, начинается от 2000 в сутки), а число сделок минимально. Я не помню, сама биржа или брокер противодействуют таким образом необоснованной нагрузке на систему, но если тысячами пустых заявок будете заваливать брокера, влетите на этот штраф.


Там используется формула какая-то. Штраф зависит от объема заявок и только в том случае, если мало сделок. Т.е. если у вас не 2000 заявок в сутки, а 200 тыс., но при этом каждая пятая-десятая приводит к сделке, то никакой штраф вам не светит, все ОК.
левые котировки, getCandlesByIndex()
 
Цитата
появление 000000001 может произойти при любой арифметической операции.

Этого не хватало для понимания проблемы. Спасибо!

Наличие погрешности при простом запросе свечки в виде candles[i].low без необходимости каких-либо операций даже внутри функции
getCandlesByIndex все равно выглядит странно как-то. Эта функция же просто стат. данные выдает. Как там эти эффекты от плавающей точки появляются - загадка для меня :)


Цитата
[TABLE][TR][TH]Цитата[/TH][/TR][TR][TD]sergei написал:
но цикл не доходит одну итерацию. Почему?[/TD][/TR][/TABLE]не понятно что имеется ввиду.
Вот в этом цикле:
Код
        for z = candles[i].low, candles[i].high, MinPriceStep do
Последняя итерация должна бы проходить для z == candles[i].high, а фактически последней является z == candles[i].high - MinPriceStep
левые котировки, getCandlesByIndex()
 
Кроме того, вот на первых свечках вообще не видно проблемы с 000000001, но цикл не доходит одну итерацию. Почему?
левые котировки, getCandlesByIndex()
 
Цитата
Sergey Gorokhov написал:
Цитата
sergei написал:
Сергей, что-то даже с округлением не получается.

Значения округляются там где Вы их округляете.
Вы округляете в for, а не там где происходит передача данных в lst
Я не понимаю, как внутри цикла ii может не быть округлено.

Да, я пытался делать так:

Код
        lst = lst..i.." --- "..math.round(ii,2).." --- "..candles[i].low..", "..candles[i].high.."\n"

...и тогда пишет округленное в файл, но, блин, мне при любом использовании ii писать его через функцию округления?!
Как это - округление работает только в момент округления? :)
левые котировки, getCandlesByIndex()
 
Сергей, что-то даже с округлением не получается.
Код
graphId = "BRK9"
candleCount = 100
MinPriceStep = 0.01

function math.round(value, p)
    local e = 10 ^ (p or 0)
    if value >= 0 then return math.floor(tonumber(value) * e + 0.5) / e
    else return math.ceil(tonumber(value) * e - 0.5) / e end
end


local num = getNumCandles(graphId)
local candles, num, _ = getCandlesByIndex(graphId,0,0,num)
local lst = ""
ff = io.open(getScriptPath().."\\".."tst.txt", "w+t")

for i = num-1, num-candleCount, -1 do
    for ii = math.round(candles[i].low, 2), math.round(candles[i].high, 2), math.round(MinPriceStep, 2) do
        lst = lst..i.." --- "..ii.." --- "..candles[i].low..", "..candles[i].high.."\n"
    end
end

ff:write("============\n\n"..lst)
ff:flush()
ff:close()

Результат на текущий момент на фьючерсе BRK9:
Цитата
7044 --- 73.66 --- 73.66, 73.71
7044 --- 73.67 --- 73.66, 73.71
7044 --- 73.68 --- 73.66, 73.71
7044 --- 73.69 --- 73.66, 73.71
7044 --- 73.7 --- 73.66, 73.71
нет шага для 73.71
7043 --- 73.58 --- 73.58, 73.7
7043 --- 73.59 --- 73.58, 73.7
7043 --- 73.6 --- 73.58, 73.7
7043 --- 73.61 --- 73.58, 73.7
7043 --- 73.62 --- 73.58, 73.7
7043 --- 73.63 --- 73.58, 73.7
7043 --- 73.64 --- 73.58, 73.7
7043 --- 73.65 --- 73.58, 73.7
7043 --- 73.66 --- 73.58, 73.7
7043 --- 73.67 --- 73.58, 73.7
7043 --- 73.68 --- 73.58, 73.7
7043 --- 73.69 --- 73.58, 73.7
нет шага для 73.70
7042 --- 73.56 --- 73.56, 73.67
7042 --- 73.57 --- 73.56, 73.67
7042 --- 73.58 --- 73.56, 73.67
7042 --- 73.59 --- 73.56, 73.67
7042 --- 73.6 --- 73.56, 73.67
7042 --- 73.61 --- 73.56, 73.67
...

7019 --- 73.95 --- 73.71, 73.96
7018 --- 72.1 --- 72.1, 73.95
7018 --- 72.11 --- 72.1, 73.95
7018 --- 72.12 --- 72.1, 73.95
7018 --- 72.13 --- 72.1, 73.95
7018 --- 72.14 --- 72.1, 73.95
7018 --- 72.15 --- 72.1, 73.95
7018 --- 72.16 --- 72.1, 73.95
7018 --- 72.17 --- 72.1, 73.95
7018 --- 72.18 --- 72.1, 73.95
7018 --- 72.19 --- 72.1, 73.95
7018 --- 72.2 --- 72.1, 73.95
7018 --- 72.21 --- 72.1, 73.95
7018 --- 72.22 --- 72.1, 73.95
7018 --- 72.23 --- 72.1, 73.95
7018 --- 72.24 --- 72.1, 73.95
7018 --- 72.25 --- 72.1, 73.95
7018 --- 72.26 --- 72.1, 73.95
7018 --- 72.27 --- 72.1, 73.95
7018 --- 72.28 --- 72.1, 73.95
7018 --- 72.29 --- 72.1, 73.95
7018 --- 72.3 --- 72.1, 73.95
7018 --- 72.31 --- 72.1, 73.95
7018 --- 72.32 --- 72.1, 73.95
7018 --- 72.33 --- 72.1, 73.95
7018 --- 72.34 --- 72.1, 73.95
7018 --- 72.35 --- 72.1, 73.95
7018 --- 72.36 --- 72.1, 73.95
7018 --- 72.37 --- 72.1, 73.95
7018 --- 72.38 --- 72.1, 73.95
7018 --- 72.39 --- 72.1, 73.95
7018 --- 72.4 --- 72.1, 73.95
7018 --- 72.41 --- 72.1, 73.95
7018 --- 72.42 --- 72.1, 73.95
7018 --- 72.43 --- 72.1, 73.95
7018 --- 72.44 --- 72.1, 73.95
7018 --- 72.45 --- 72.1, 73.95
7018 --- 72.46 --- 72.1, 73.95
7018 --- 72.47 --- 72.1, 73.95
7018 --- 72.48 --- 72.1, 73.95
7018 --- 72.49 --- 72.1, 73.95
7018 --- 72.5 --- 72.1, 73.95
7018 --- 72.51 --- 72.1, 73.95
7018 --- 72.52 --- 72.1, 73.95
7018 --- 72.53 --- 72.1, 73.95
7018 --- 72.54 --- 72.1, 73.95
7018 --- 72.55 --- 72.1, 73.95
7018 --- 72.56 --- 72.1, 73.95
7018 --- 72.57 --- 72.1, 73.95
7018 --- 72.58 --- 72.1, 73.95
7018 --- 72.59 --- 72.1, 73.95
7018 --- 72.6 --- 72.1, 73.95
7018 --- 72.61 --- 72.1, 73.95
7018 --- 72.62 --- 72.1, 73.95
7018 --- 72.63 --- 72.1, 73.95
7018 --- 72.64 --- 72.1, 73.95
7018 --- 72.65 --- 72.1, 73.95
7018 --- 72.66 --- 72.1, 73.95
7018 --- 72.67 --- 72.1, 73.95
7018 --- 72.68 --- 72.1, 73.95
7018 --- 72.69 --- 72.1, 73.95
7018 --- 72.7 --- 72.1, 73.95
7018 --- 72.71 --- 72.1, 73.95
7018 --- 72.72 --- 72.1, 73.95
7018 --- 72.73 --- 72.1, 73.95
7018 --- 72.74 --- 72.1, 73.95
7018 --- 72.75 --- 72.1, 73.95
7018 --- 72.76 --- 72.1, 73.95
7018 --- 72.77 --- 72.1, 73.95
7018 --- 72.78 --- 72.1, 73.95
7018 --- 72.79 --- 72.1, 73.95
7018 --- 72.8 --- 72.1, 73.95
7018 --- 72.81 --- 72.1, 73.95
7018 --- 72.82 --- 72.1, 73.95
7018 --- 72.83 --- 72.1, 73.95
7018 --- 72.84 --- 72.1, 73.95
7018 --- 72.85 --- 72.1, 73.95
7018 --- 72.86 --- 72.1, 73.95
7018 --- 72.87 --- 72.1, 73.95
7018 --- 72.88 --- 72.1, 73.95
7018 --- 72.89 --- 72.1, 73.95
7018 --- 72.9 --- 72.1, 73.95
7018 --- 72.91 --- 72.1, 73.95
7018 --- 72.92 --- 72.1, 73.95
7018 --- 72.93 --- 72.1, 73.95
7018 --- 72.94 --- 72.1, 73.95
7018 --- 72.95 --- 72.1, 73.95
7018 --- 72.96 --- 72.1, 73.95
7018 --- 72.97 --- 72.1, 73.95
7018 --- 72.98 --- 72.1, 73.95
7018 --- 72.99 --- 72.1, 73.95
7018 --- 73 --- 72.1, 73.95
7018 --- 73.01 --- 72.1, 73.95
7018 --- 73.02 --- 72.1, 73.95
7018 --- 73.03 --- 72.1, 73.95
7018 --- 73.04 --- 72.1, 73.95
7018 --- 73.05 --- 72.1, 73.95
7018 --- 73.06 --- 72.1, 73.95
7018 --- 73.07 --- 72.1, 73.95
7018 --- 73.08 --- 72.1, 73.95
7018 --- 73.090000000001 --- 72.1, 73.95
7018 --- 73.100000000001 --- 72.1, 73.95
7018 --- 73.110000000001 --- 72.1, 73.95
7018 --- 73.120000000001 --- 72.1, 73.95
7018 --- 73.130000000001 --- 72.1, 73.95
7018 --- 73.140000000001 --- 72.1, 73.95
7018 --- 73.150000000001 --- 72.1, 73.95
7018 --- 73.160000000001 --- 72.1, 73.95
7018 --- 73.170000000001 --- 72.1, 73.95
7018 --- 73.180000000001 --- 72.1, 73.95
7018 --- 73.190000000001 --- 72.1, 73.95
7018 --- 73.200000000001 --- 72.1, 73.95
7018 --- 73.210000000001 --- 72.1, 73.95
7018 --- 73.220000000001 --- 72.1, 73.95
7018 --- 73.230000000001 --- 72.1, 73.95
7018 --- 73.240000000001 --- 72.1, 73.95
7018 --- 73.250000000001 --- 72.1, 73.95
7018 --- 73.260000000001 --- 72.1, 73.95
7018 --- 73.270000000001 --- 72.1, 73.95
7018 --- 73.280000000001 --- 72.1, 73.95
7018 --- 73.290000000001 --- 72.1, 73.95
7018 --- 73.300000000001 --- 72.1, 73.95
7018 --- 73.310000000001 --- 72.1, 73.95
7018 --- 73.320000000001 --- 72.1, 73.95
7018 --- 73.330000000001 --- 72.1, 73.95
7018 --- 73.340000000001 --- 72.1, 73.95
7018 --- 73.350000000001 --- 72.1, 73.95
7018 --- 73.360000000001 --- 72.1, 73.95
7018 --- 73.370000000001 --- 72.1, 73.95
7018 --- 73.380000000001 --- 72.1, 73.95
7018 --- 73.390000000001 --- 72.1, 73.95
7018 --- 73.400000000001 --- 72.1, 73.95
7018 --- 73.410000000001 --- 72.1, 73.95
7018 --- 73.420000000001 --- 72.1, 73.95
7018 --- 73.430000000001 --- 72.1, 73.95
7018 --- 73.440000000001 --- 72.1, 73.95
7018 --- 73.450000000001 --- 72.1, 73.95
7018 --- 73.460000000001 --- 72.1, 73.95
7018 --- 73.470000000001 --- 72.1, 73.95
7018 --- 73.480000000001 --- 72.1, 73.95
7018 --- 73.490000000001 --- 72.1, 73.95
7018 --- 73.500000000001 --- 72.1, 73.95
7018 --- 73.510000000001 --- 72.1, 73.95
7018 --- 73.520000000001 --- 72.1, 73.95
7018 --- 73.530000000001 --- 72.1, 73.95
7018 --- 73.540000000001 --- 72.1, 73.95
7018 --- 73.550000000001 --- 72.1, 73.95
7018 --- 73.560000000001 --- 72.1, 73.95
7018 --- 73.570000000001 --- 72.1, 73.95
7018 --- 73.580000000001 --- 72.1, 73.95
7018 --- 73.590000000001 --- 72.1, 73.95
7018 --- 73.600000000001 --- 72.1, 73.95
7018 --- 73.610000000001 --- 72.1, 73.95
7018 --- 73.620000000001 --- 72.1, 73.95
7018 --- 73.630000000001 --- 72.1, 73.95
7018 --- 73.640000000001 --- 72.1, 73.95
7018 --- 73.650000000001 --- 72.1, 73.95
7018 --- 73.660000000001 --- 72.1, 73.95
7018 --- 73.670000000001 --- 72.1, 73.95
7018 --- 73.680000000001 --- 72.1, 73.95
7018 --- 73.690000000001 --- 72.1, 73.95
7018 --- 73.700000000001 --- 72.1, 73.95
7018 --- 73.710000000001 --- 72.1, 73.95
7018 --- 73.720000000001 --- 72.1, 73.95
7018 --- 73.730000000001 --- 72.1, 73.95
7018 --- 73.740000000001 --- 72.1, 73.95
7018 --- 73.750000000001 --- 72.1, 73.95
7018 --- 73.760000000001 --- 72.1, 73.95
7018 --- 73.770000000001 --- 72.1, 73.95
7018 --- 73.780000000001 --- 72.1, 73.95
7018 --- 73.790000000001 --- 72.1, 73.95
7018 --- 73.800000000001 --- 72.1, 73.95
7018 --- 73.810000000001 --- 72.1, 73.95
7018 --- 73.820000000001 --- 72.1, 73.95
7018 --- 73.830000000001 --- 72.1, 73.95
7018 --- 73.840000000001 --- 72.1, 73.95
7018 --- 73.850000000001 --- 72.1, 73.95
7018 --- 73.860000000001 --- 72.1, 73.95
7018 --- 73.870000000001 --- 72.1, 73.95
7018 --- 73.880000000001 --- 72.1, 73.95
7018 --- 73.890000000001 --- 72.1, 73.95
7018 --- 73.900000000001 --- 72.1, 73.95
7018 --- 73.910000000001 --- 72.1, 73.95
7018 --- 73.920000000001 --- 72.1, 73.95
7018 --- 73.930000000001 --- 72.1, 73.95
7018 --- 73.940000000001 --- 72.1, 73.95
7017 --- 72.06 --- 72.06, 72.09
7017 --- 72.07 --- 72.06, 72.09
7017 --- 72.08 --- 72.06, 72.09
7016 --- 72.07 --- 72.07, 72.09
7016 --- 72.08 --- 72.07, 72.09
7016 --- 72.09 --- 72.07, 72.09
7015 --- 72.07 --- 72.07, 72.08
7015 --- 72.08 --- 72.07, 72.08
7014 --- 72.07 --- 72.07, 72.09
7014 --- 72.08 --- 72.07, 72.09
левые котировки, getCandlesByIndex()
 
Цитата
          for  z  =  candles[i].low, candles[i].high, MinPriceStep  do  
Код
            ZZZ[z]  =  ZZZ[z]  +  что - то
         end   
Сейчас мне кажется, что подобные конструкции совершенно непредсказуемы, т.к.

z может принимать значения на 0.000000000001 больше или меньше ожидавшегося, в результате чего вместо суммирования значений в одном ZZZ[67.55] мы можем получить до трех или более разных ZZZ: ZZZ[67.5499999999999], ZZZ[67.55], ZZZ[67.5500000000001]
Кроме того, еще и ошибки полезут, когда ZZZ[z] внезапно окажется nil вопреки ожиданиям
левые котировки, getCandlesByIndex()
 
Цитата
Sergey Gorokhov написал:

Цитата
sergei написал:
Насколько плохая идея использовать в таблицах индексы в виде чисел с плавающей точкой?

Вопрос не понятен, просьба уточнить подробней что имеется ввиду, можно на примере.
Код
        for z = candles[i].low, candles[i].high, MinPriceStep do
            ZZZ[z] = ZZZ[z] + что-то
        end
Сейчас мне кажется, что подобные конструкции совершенно непредсказуемы, т.к.

z может принимать значения на 0.000000000001 больше или меньше ожидавшегося, в результате чего вместо суммирования значений в одном ZZZ[67.55] мы можем получить до трех или более разных ZZZ: ZZZ[67.5499999999999], ZZZ[67.55], ZZZ[67.5500000000001]
левые котировки, getCandlesByIndex()
 
Цитата
Sergey Gorokhov написал:
Цитата
sergei написал:
ЧТО ЗА ФИГНЯ?! :)

это особенность типа данных с плавающей точкой.
Почитать что это такое можно в википедии
https://ru.wikipedia.org/wiki/Число_с_плавающей_запятой
Сергей, как корректно округлить до нужного знака, чтобы в итоге не получить новое подобное число?
Насколько плохая идея использовать в таблицах индексы в виде чисел с плавающей точкой?
левые котировки, getCandlesByIndex()
 
добрый день!

беру данные так:
Код
    local num = getNumCandles(graphId)
    local candles, num, _ = getCandlesByIndex(graphId,0,0,num)

Возникают две проблемы, которые есть суть одной.
Если вот так я хочу перебрать внутри свечки все значения с минимальным шагом инструмента (MinPriceStep), то...

Код
        for z = candles[i].low, candles[i].high, MinPriceStep do
...то:
1. candles[i].low фьючерса нефти, например, может оказаться такой: 73.270000000001 при шаге цены 0.01
2. в результате такой штуки цикл регулярно выполняется на итерацию меньше (что, в общем, понятно, когда low или high на 0.00000000001 больше или меньше допустимой

Как бы вопрос-то сформулировать...
ЧТО ЗА ФИГНЯ?! :)
Qlua автономно, Qlua автономно
 
Цитата
Борис Гудылин написал:
Цитата
В выходной и без интернета можете запустить любой свой скрипт.
Можем, но и он тоже может - не заработать.
Я так понимаю, что ключевое слово в вопросе - "автономно", а вы во все тяжкие :)

Понятно, что без соединения в принципе невозможно всё то, ради чего lua и был портирован в quik.
Автору топика стоит уточнить, чего он хочет-то.
Qlua автономно, Qlua автономно
 
В каком смысле автономный? Без подключения к серверу внутри Quik можно запускать любые скрипты. Там все может работать "автономно", если не нужны потоки данных, работа с заявками и сделками, колбэки :) В выходной и без интернета можете запустить любой свой скрипт.
доступ к большим таблицам
 
в соседней ветке есть на эту тему:
Цитата
Цитата
BlackBoar написал:
Подскажите пожалуйста, порректно ли вообще измерять время на вызов функций квик подобным способом. Или "дерганье" их миллион раз подряд вызывает какие-то аномалии в работе квик?
"дерганье" миллион раз не должно вызывать никаких аномалий.
Другой вопрос в том что каждая итерация цикла может выполняться раз в 15.625 мс, почитать можно например тут: https://habrahabr.ru/company/intel/blog/186998/

сама тема: https://forum.quik.ru/forum10/topic3995/
доступ к большим таблицам
 
data mining вряд ли целесообразно на lua делать, особенно в таких масштабах
производительность должна быть в разы (если не на порядки) ниже более целесообразного варианта

при сбое в электропитании даже промежуточных результатов не будет, да?
сортировка таблицы, ключ и значения - натуральные числа
 
Цитата
SDL написал:
Цитата
sergei написал:

1. почему не сортирует вообще никак, ни по ключу, ни по значению, хотя то и другое - натуральные числа?
Чтобы table.sort работала, нужно чтобы ключи были в терминологии Lua "массивом" (array), то есть являлись:
1. Положительными целыми числами.
2. Начинались с 1.
3. Не имели пропусков (максимальный индекс равен общему количеству элементов).

Что касается своих правил сортировки, table.sort предоставляет возможность задать вторым аргументом функцию, где эти собственные правила можно и реализовать. Подробности в документации на Lua.
Спасибо!

#2 & #3 у меня не выполняются.
сортировка таблицы, ключ и значения - натуральные числа
 
Добрый день

Пытался найти максимумы-минимумы в таблице.
Код
        table.sort(TBsorted)

        for key, val in pairs(TBsorted) do
            lst = lst..key.." - "..val.."\n"
        end
Выводит подобное:
Цитата
64287 - 7
64282 - 1
64284 - 27
64286 - 112
64281 - 16
64280 - 1
64285 - 10
64278 - 2

Использование функции в table.sort тоже никак не помогает почему-то.
Вопросы:
1. почему не сортирует вообще никак, ни по ключу, ни по значению, хотя то и другое - натуральные числа?
2. как отсортировать значения, сохраняя ассоциации с ключами?
3. известен ли лучший способ поиска максимумов-минимумов без сортировки?

Максимумов-минимумов может быть несколько. В приведенном конкретном случае, если бы ключи были отсортированы, хотелось бы найти волны макс.-мин.-макс.-мин. таким образом, чтобы максимумы и минимумы стояли друг от друга не ближе какого-то диапазона. При этом в абсолютных значениях максимумы могут не быть самыми большими числами, а минимумы - самыми маленькими
Цитата
64278 - 2
64279 - 0 min
64280 - 1
64281 - 16 max
64282 - 1
64283 - 0 min
64284 - 27            - не max, хотя и больше 64281 - 16, т.к. слишком близко к min
64285 - 10            - не min, слишком близко к max
64286 - 112 max
64287 - 7
Как и где правильно написать условие по выполненной заявке?, ...когда она не перемещена, не убита, а именно полностью filled?
 
Цитата
Imersio Arrigo написал:
Поразительное упорство незамечать на что нужно обратить внимание :) Три человека говорят одно и тоже, а он упорно игнорирует :))
А кто третий? Я? Так я автор топика, только переименовался, поскольку Сергеев тут слишком до фига :)

Вопрос в оптимизации. Вот _sk_ утверждал, что менее, чем в 1000 строк управление заявками-сделками организовать нельзя, причем большинство пытается использовать абсолютно все поступающие данные, включая OnTransReply().

Вы используете OnTransReply()? Если да, то зачем?


Цитата
Цитата
Пожалуйста, обоснуйте. Чем OnTrade() в данном плане хуже OnOrder()?
Что значит "обоснуйте"? Он не хуже. Он другой, и сообщает о других событиях.
Это примерно как "обоснуйте почему ноги хуже рук".
OnTrade вызывается при приходе сделок(!). И только их. Неважно откуда они взялись. (может брокер за вас исполнил заявку, или маржинколл, или экспирация опционов. Неважно).
А OnOrder вызвается когда есть изменения в ЗАЯВКЕ(!). Сделок может и не быть (например если заявка выставлена и тут же снята), и поэтому если нужен статус заявки, то анализировать нужно OnOrder.

OnTrade() прекрасен тем, что приходит только один раз с одним trade_num, а также там есть trans_id из заявки.
Есть там и флаги ЗАЯВКИ. Не сделки, не транзакции, а именно заявки. Если бы они корректно показывали, что заявка полностью налита и более не существует, то очень разумно не ждать более ничего в OnOrder().


Цитата
OnTrade может срабатывать раньше, может позже. Колбеки - штука асинхронная. Вообще нельзя полагаться на порядок их вызова.
Понять  что по OnTrade "на заявку можно забить" только в том случае, если все  OnTrade-ы по одной заявке (надо отслеживать номер) в сумме дали кол-во  указанное в заявке. Но этого может не произойти, потому что частично  исполненная заявка может быть снята, и тогда это никогда не произойдет.
Опять же, вопрос исключительно в поиске оптимального и надежного решения.

Ну, приходит в OnTrade() статус заявки. Как без ваших ответов и экспериментов можно было узнать, что это неправильный путь?
Но глобально для меня вопрос решен, спасибо за помощь!
Как и где правильно написать условие по выполненной заявке?, ...когда она не перемещена, не убита, а именно полностью filled?
 
Эксперимент показал, что SDL абсолютно прав. В OnTrade() заявка может быть и снята, и исполнена по флагам, но OnOrder() все равно надо дождаться, т.к. там order.balance может не быть равен нулю. В OnTrade() остаток не проверить.
Как и где правильно написать условие по выполненной заявке?, ...когда она не перемещена, не убита, а именно полностью filled?
 
Цитата
Применять к сделкам эти биты никак нельзя. Документация и здравый смысл правы. Смотреть на них в OnTrade() просто не надо. Совсем.
Пожалуйста, обоснуйте. Чем OnTrade() в данном плане хуже OnOrder()?
Код
bit.band(order.flags,1) == 0 and bit.band(order.flags,2) == 0
Код
bit.band(order.flags,3) == 0
Данные два варианта точно эквивалентны? Я всерьез, т.к. не проф. программер и биты не люблю :)
Загрузить одну функцию
 
Интересно вы роботов пишете! Ни одной тривиальной проблема :)

Что там с темным окошком и питоном было? Хоть о финалах этих битв сообщайте! Жуть, как интересно )
Баг в квике под virtualbox
 
я работаю под virtual box

из странностей наблюдаю только то, что если main сколь-нибудь нагружена кодом, то часто при работе скрипта все виртуальные машины падают разом, и ничего даже в логи не успевает записаться :)
просто держу main() пустой =)

возможно, с виртуальной машиной такое поведение тоже не связано, просто никогда не видел quik вне virtual box... может, ошибки какие-то вылезали бы... а тут бац-бац... и мимо :) мимо каких-либо ошибок, вообще без объявления войны.
Как и где правильно написать условие по выполненной заявке?, ...когда она не перемещена, не убита, а именно полностью filled?
 
Цитата
Imersio Arrigo написал:
Цитата
Сергей написал:
В документации и на форумах много разных вариантов проверки. Какой гарантирует, что заявка была на 100% filled?"Не активна" + "исполнена" почему-то не работает.Только флагами и непосредственно в OnTrade() определяется или без order.balance не обойтись?
Причем тут OnTrade? Надо узнать статус заявки? Обрабатываем OnOrder.
Нас интересуют два флага:
OF_ACTIVE = 0x01
OF_KILL = 0x02
По определению: первый флаг показывает активная ли заявка, второй снята или исполнена если не активна. Т.о. существует всего 3 состояния.
0х01 = активна. order.balance (если не ошибаюсь) показывает неисполненный остаток.
0х02 = неактивна, снята.  order.balance  показывает неисполненный остаток.
0х00 = неактивна, исполнена полностью.

OnTrade показывает статусы сделок.

Цитата
Сергей написал:
"Не активна" + "исполнена" почему-то не работает.
Почему не работает? Можно кусочек кода?
Конкретные проверки выше.
OnTrade() стабильно срабатывает раньше OnOrder(), и я б не стал дожидаться ничего другого, если мне в OnTrade() сразу и скажут, что на эту заявку можно "забить", т.к. она более не существует.

В официальной справке QLUA по OnTrade() указано, что первый и второй биты касаются именно ЗАЯВКИ. Собственно, по-другому их и интерпретировать нельзя. Что значит применительно к сделке "снята" и как сделка может не быть исполнена (частично хотя бы), если OnTrade() сработал? Определенно о заявках это.
Как и где правильно написать условие по выполненной заявке?, ...когда она не перемещена, не убита, а именно полностью filled?
 
В документации и на форумах много разных вариантов проверки. Какой гарантирует, что заявка была на 100% filled?
"Не активна" + "исполнена" почему-то не работает.
Только флагами и непосредственно в OnTrade() определяется или без order.balance не обойтись?



OnTrade()?
Код
if bit_set(trade.flags, 0) == false and bit_set(trade.flags, 1) == false then

OnOrder()?
Код
if bit.band(order.flags,2) > 0 then
Выбор источника данных для скрипта, Обсуждение выбора наилучшего источника данных для скрипта
 
http://luaq.ru/CreateDataSource.html
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Спасибо всем, кто поучаствовал и всем, кто не захотел :)
Проблема решена, вроде. Сегодня впервые запустил робота "по-боевому" в геморройное время - с открытия.

Для такой сутолоки и пипсовки робот не предназначен, запускался только в качестве теста управления заявками и сделками.

Прототип убил вирт.машину через 4 минуты с момента запуска, вылетев из памяти, очевидно.
Однако, управление заявками и сделками, работает корректно. Позу ни разу не потерял.


Основные идеи решения:
1. не использую колбек по транзакциям, только OnOrder(), OnTrade()
2. trans_id не уникален и не инкрементируется, указывает на логический тип операции (что она делает в логике ТС, может также быть идентификатором робота, если распределить диапазоны значений между разными роботами)
3. для характеристики заявки по определенному trans_id использую только номер заявки и время отправки транзакции. Время отправки используется, как статус (0 = ничего не ждем, не было отправлено ни MoveOrder, ни KillOrder в отношении нее)
4. если прилетает заявка с бОльшим order_num, чем "рабочая" для данного типа заявок (тот же trans_id у нее), то мы сразу делаем ее "рабочей", о предыдущей сразу забываем, не ждем никаких "исполнена", но отслеживаем order.balance. Примечание: OnOrder() может не срабатывать 2-3 раза. Может прийти только 1 раз, и там уже сразу будет "исполнена".
5. OnTrade() нас интересует только один раз для каждого trade_num. К чему именно относится сделка определяем через order_num -> trans_id.

Цитата
10:00:01    Si-3.19    Купля    65 902    2
10:00:03    Si-3.19    Продажа    65 923    2
10:00:05    Si-3.19    Купля    65 887    2
10:00:05    Si-3.19    Продажа    65 914    2
10:00:06    Si-3.19    Продажа    65 914    1
10:00:06    Si-3.19    Продажа    65 914    1
10:00:07    Si-3.19    Купля    65 913    2
10:00:15    Si-3.19    Купля    65 915    2
10:00:17    Si-3.19    Продажа    65 914    2
10:00:17    Si-3.19    Продажа    65 914    2
10:00:19    Si-3.19    Купля    65 908    2
10:00:19    Si-3.19    Купля    65 904    2
10:00:23    Si-3.19    Продажа    65 899    2
10:00:23    Si-3.19    Продажа    65 902    2
10:00:24    Si-3.19    Купля    65 888    2
10:00:24    Si-3.19    Купля    65 882    2
10:00:27    Si-3.19    Продажа    65 891    2
10:00:27    Si-3.19    Продажа    65 899    2
10:00:29    Si-3.19    Купля    65 886    2
10:00:29    Si-3.19    Купля    65 886    2
10:00:31    Si-3.19    Продажа    65 891    2
10:00:31    Si-3.19    Продажа    65 893    2
10:00:34    Si-3.19    Купля    65 911    1
10:00:34    Si-3.19    Купля    65 911    1
10:00:36    Si-3.19    Продажа    65 919    2
10:00:39    Si-3.19    Купля    65 917    1
10:00:39    Si-3.19    Купля    65 917    1
10:00:41    Si-3.19    Продажа    65 920    2
10:00:43    Si-3.19    Купля    65 917    2
10:00:47    Si-3.19    Продажа    65 924    2
10:00:50    Si-3.19    Купля    65 935    2
10:00:58    Si-3.19    Продажа    65 938    2
10:01:00    Si-3.19    Купля    65 929    2
10:01:04    Si-3.19    Купля    65 932    2
10:01:07    Si-3.19    Продажа    65 939    2
10:01:09    Si-3.19    Продажа    65 944    2
10:01:10    Si-3.19    Купля    65 941    1
10:01:11    Si-3.19    Купля    65 941    1
10:01:30    Si-3.19    Продажа    65 948    2
10:01:34    Si-3.19    Купля    65 948    1
10:01:34    Si-3.19    Купля    65 948    1
10:01:43    Si-3.19    Купля    65 942    2
10:01:45    Si-3.19    Продажа    65 941    2
10:01:57    Si-3.19    Купля    65 934    2
10:01:59    Si-3.19    Продажа    65 934    2
10:02:03    Si-3.19    Купля    65 937    2
10:02:04    Si-3.19    Продажа    65 937    1
10:02:04    Si-3.19    Продажа    65 937    1
10:02:32    Si-3.19    Купля    65 942    2
10:02:44    Si-3.19    Продажа    65 948    2
10:03:37    Si-3.19    Купля    65 942    2
10:03:50    Si-3.19    Продажа    65 938    2
Чёрное окошко (Питон, Луа)
 
Файл tmp.txt может быть залочен или что-то подобное?
В lua ошибку искать просто негде. Отдельно питоновский скрипт всегда работает?
Не знаю, как идет процесс отладки питонов под виндой, но можно тупо добавить там print после каждой строки. Может, он у вас до седьмой строки часто не доходит, не только до 14.
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Еще вопрос по "исполненным" заявкам. Если проверять только флаги:
Код
bit.band(order.flags,2) > 0
...то они назовут "исполненными": 1. реально исполненные заявки, превратившиеся в трейды, 2. убитые заявки, 3. переставленные заявки, т.е. вообще любые неактуальные более заявки. Как отличить реально сработавшие заявки от "просто неактуальных".
Код
bit.band(order.flags,2) > 0 and order.balance == 0
Такая комбинация тоже не работает, как я ожидал.

_sk_ написал:
Цитата
9) В limit-заявке нужно помнить volume, volumeTraded, volumeLeft. Обычно  volumeTraded + volumeLeft == volume, но иногда при снятии частично  исполненной заявки становится понятно, чему равен volumeLeft и надо  дождаться событий OnTrade(), которые ещё пока не пришли. При приходе  OnTrade() нужно отбрасывать дубликаты (в 7-й версии) и корректировать  volumeTraded, volumeLeft. Как только volumeLeft == 0, так удалять заявку  из таблицы актуальных вместе со всеми связанными с ней kill-заявками и  ответами на них.
Поскольку в OnOrder() ничего такого не приходит, я решил, что volume, volumeTraded, volumeLeft - это его синтетические фишки, которые он сам придумал и корректирует из order.qty, order.balance и данных из OnTrade(). Это решение "моей" проблемы?


Без OnTrade() не понять, что произошло с "исполненной" заявкой?

Спасибо!
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Коллеги, как надежно сделать MOVE_ORDERS?
Как я понял, по старому номеру заявка может быть уже "исполнена", а новая заявка если уже и пришла, то может быть пока еще неинформативной, т.е. в каком-то первичным виде без нужных параметров типа trans_id. Соответственно, велика вероятность, что робот успеет выставить новую заявку, решив, что в этом направлении у нас никакой заявки нет вообще, а потом уже "дойдет" переставленная заявка, в результате получим две заявки в одном направлении вместо одной.
Я правильно понимаю, что у переставленной заявки будет новый order_num? Извините за глупый, возможно, вопрос. В выходные проверить возможности нет, а мыслительный процесс идет, он вне расписания праздников и выходных =)
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Цитата
_sk_ написал:
Например, сейчас у робота куплено 200 контрактов (текущая позиция). Закончилась очередная 15-минутная свеча и логика торговой системы говорит, что теперь хочется иметь 300 контрактов (желаемая позиция). В работу вступает модуль исполнения, который, скажем, раз в 5 секунд:
- выставляет по цене бид 10 контрактов,
- ждёт сделок, если они будут;
- снимает заявку, если там что-то осталось;
- снова выставляет в бид 10 контрактов (или сколько там осталось, чтобы получилась желаемая позиция).
Таким образом, сведение позиций занимает довольно много времени, зато меньше проскальзывание и влияние на рынок. Кроме того, логика расчёта желаемых позиций отделена от логики их достижения.
Любопытно. Вероятно, вы торгуете неликвид, используя усреднение или пирамидинг.

А что делает робот, если цена резко уходит в "неправильную" сторону? Просто так и не выйдешь, да без сдвига рынка...
Я б себе часто подгузники менял при такой стратегии, и роботу тоже ))



Цитата
Цитата
Учитываете ли вы заявки или сделки только на основании OnTransReply() и до срабатывания OnOrder() или OnTrade()?
Информация  о заявке берётся из OnTransReply() в обязательном порядке. Список  сделок пишется только на основании OnTrade(). Если что-то где-то  пропало, выдаются предупреждения. Если у неактивной заявки долго не  сходится сумма объёмов по сделкам и разность между объёмом и остатком,  выдаётся ошибка.
Честно говоря, смысл этих телодвижений так и остался для меня непонятным. Поскольку вы все равно на основании результатов OnTransReply() торговых решений не принимаете, никаких уникальных данных оттуда не получаете + у вас полностью все автоматизировано, включая редкие аномалии, то зачем эти предупреждения об ошибках и кто их читает вообще?
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Цитата
_sk_ написал:
Цитата
Сергей написал:
1. что есть такого критичного и необходимого в OnTransReply(), чего нельзя поймать через OnOrder() и OnTrade()?
1) Детали уже не помню, давно дело было. При программировании мне хотелось:
а) использовать как можно больше источников информации, чтобы повысить надёжность системы;
б) реализовать быструю систему работы с заявками.
В результате получилась хоть и непростая система, зато с коррекцией всякого рода редких ошибок и нетипичных ситуаций, которая работает на полном автомате.

Учитываете ли вы заявки или сделки только на основании OnTransReply() и до срабатывания OnOrder() или OnTrade()?
Программирую я редко и кривовато, при анализе избыточной информации и ловле редких ошибок надежность моей системы наверняка только снизится.


Цитата
2) Шаблона робота нет. На моей  практике кроме менеджера заявок нужен ещё и модуль сведения позиций,  который приводит текущие позиции робота к желаемым. Это ещё примерно  столько же строк кода. Таких модулей у меня три, каждый со своей  спецификой работы с заявками. Продать что-то из кода нет возможности.

Здесь подробнее, пожалуйста. Что из двух?

1. "Желаемые позиции" - это чисто алгоритмическая вещь ТС? Например, как вторую ногу поставить при парном трейдинге или арбитраже.
2. Это проверка текущей расчетной позиции в роботе с реальной позицией? Например, в лишний раз куда-то в табличку терминала заглянуть и проверить, правильно ли робот держит позу или он пропустил какие-то сделки, в результате чего его расчетная позиция не совпадает с фактической. Почему тогда много строк кода?
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Цитата
Цитата
Сергей написал:

судя по всему, у первой пришедшей trade_num был больше  

А вот это легко. Хотя более поздние сделки при регистрации имеют  бОльшие номера, мы точно не знаем, как устроены потоки данных от биржи  до терминала (и скрипта). Поэтому предложенный мной вариант более  надежен, мне пока непонятно, почему вы его назвали некорректным. Пока  всё говорит о том, что как раз наоборот.
Выявление уникальных сделок у вас, безусловно, куда надежнее моего. Свой в утиль, ваш на вооружение уже принял :) СПАСИБО!
Я имел в виду, что нельзя одним только OnTrade() решить проблему заявок и сделок, как единое целое. Без OnOrder() и анализа заявок точно не обойтись.

Цитата
Цитата
Сергей написал:

Зачем чистильщик с таким периодом? Серьезно 86400, а не 300, например?

24 * 60 * 60 = 86400 с, т.е. это 1 сутки. Разумеется, используйте любой подходящий вам лично "срок давности".
В программинге я не очень, но умножать обучен :) Увидев там "сутки", удивился именно этому. Вы неделями своих роботов не отключаете?

Цитата

Цитата
Сергей написал:

1. что есть такого критичного и необходимого в OnTransReply(), чего нельзя поймать через OnOrder() и OnTrade()?  

В принципе, ничего. Для новых заявок позволяет связать trans_id с  order_num. Для снятых полезная информация - неисполненный остаток  (balance). Можно обойтись без него, но есть одно преимущество.  OnTransReply(), как правило, приходит первым из всех событий, связанных с  транзакцией. Для алгоритмов, критичных к быстродействию, позволяет  сделать код более "интерактивным", т.е. быстрее реагирующим на  происходящее.

Подозреваю, так сильно не ускориться. Для пипсовки и HFT QLua так себе вариант :)
Вы реально учитываете заявки или сделки только на основании OnTransReply() и до того, как сработают OnOrder() или OnTrade()?
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Цитата
_sk_ написал:
Биржа работает быстро, у нескольких сделок могут микросекунды совпадать.

OnTransReply() лучше использовать. В принципе, можно и без него обойтись, но тогда исполнение заметно замедлится.

Если программируете свой исполнитель заявок, то лучше делайте его корректно работающим, а не компактным.
Вас хотелось бы расспросить больше, чем кого бы то ни было :)
1. что есть такого критичного и необходимого в OnTransReply(), чего нельзя поймать через OnOrder() и OnTrade()?

2. нет ли у вас шаблона робота, который можно просто купить и вставить туда логику? :) Сколько стоит?
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Цитата
SDL написал:
... ну и надо периодически прибираться, а то память кончится:
Код
     if   os.time ()  -  tradeDT  >  =   86400  
Зачем чистильщик с таким периодом? Серьезно 86400, а не 300, например?
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Цитата
SDL написал:
Цитата
Сергей написал:
как отличать повторный вызов OnTrade() от вызова с тем же объемом (и всем остальным ?)
Разумеется, одна заявка с объемом >1 может исполняться несколькими разными сделками. А у   разных   сделок номера (trade_num) тоже   разные   (во всяком случае в пределах одного класса инструментов). Предложенное решение позволяет отфильтровывать именно   дубликаты   одной сделки, т.е. имеющие одинаковые номера trade_num.
Вероятно, у меня проблема с реализацией этой идеи была.

Я не в таблице trade_num запоминал, а просто номер последней сделки сравнивал:
Цитата
               if LastTrade >= trade.trade_num then return end
...
               LastTrade = trade.trade_num
Обе сделки прошли за одну секунду и, судя по всему, у первой пришедшей trade_num был больше. Другого объяснения я найти не могу, почему реальная позиция получилась больше, чем в скрипте.

Логика говорит, что trade_num должны быть разными, даже когда сделки порождаются одной заявкой, но сегодняшний опыт меня очень смутил. Хотел уж копать в сторону trade.datetime и микросекунды сравнивать :)


С перестановкой заявок вы как боретесь и используете ли OnTransReply()?

Спасибо!
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Цитата
SDL написал:
Заводите такую таблицу:
Код
  Trades  =  {}
  
В обработчике пишете:
Код
   function   OnTrade (trade)
   if  Trades[trade.trade_num]  then   return   end   -- Это дубль, ничего не делать 
  Trades[trade.trade_num]  =   os.time ()  -- Запомним время, понадобится для последующей очистки 
   < здесь ваш полезный код > 
 end 
  
... ну и надо периодически прибираться, а то память кончится:
Код
   function   OnCleanUp ()
   for  tradeNum, tradeDT  in  pairs(Trades)  do 
     if   os.time ()  -  tradeDT  >  =   86400   then  Trades[tradeNum]  =   nil   end 
   end 

   <  .. . > 
 end 
  
Достаточно компактное решение?
Компактное, но вряд ли корректное )

1. игнорировать повторные OnTrade() через trade_num - это первое, до чего я додумался, но сегодня в эксперименте мою заявку из двух лотов исполнили по частям. После первого лота в скрипте и фактически я получил позицию в 1 лот, а вот когда доели второй лот, то скрипт игнорировал повторный вызов OnTrade() с тем же trade_num, поэтому в скрипте позиция осталась 1, а фактически стала уже 2. Получилось случайно. Пока я не могу надежно утверждать, что trade_num был тем же, но практически уверен в этом. Отсюда и вопрос в теме - как отличать повторный вызов OnTrade() от вызова с тем же объемом (и всем остальным ?)

2. основная суета идет вокруг заявок - их перемещения в зависимости от торговой ситуации. OnOrder() вряд ли можно игнорировать совсем после отсылки транзакции. Текущая позиция имеет мало смысла, если в стакане полно "забытых" заявок не исполненных или частично исполненных.

3. как-то раньше я обходился без OnTransReply(), используя только OnTrade() и OnOrder(). Почему-то везде серьезные люди смотрят на мир и через OnTransReply() тоже. Критическая необходимость использования этого коллбэка мне пока не понятна.
Как бороться с неоднозначностью в заявках и сделках?, OnOrder(), OnTrade()
 
Добрый день!

Погряз в рутине с заявками и сделками.
На соседних ветках тут уже были предложены решения. В частности, от уважаемого _sk_, например.

Но, блин, это ж надо операционную систему написать...

Кто как борется с неоднозначностями?

Например, прилетает мне сделка в OnTrade(). И я знаю наверняка, что прилетит еще её дубль, а может, и в третий раз сработает.
Как узнать, это просто дубль пришел или моя заявка последовательно разбирается частями? В отличие от OnOrder(), в OnTrade() нет поля остатка balance (что и логично). Есть только qty. И чем тогда отличается повторное срабатывание от нового на такой же объем? trade_num у них одинаковые. Все остальное (order_num, trans_id, ...) тоже. Заявка-то одна была.

В саму заявку тоже не очень посмотришь. Во-первых, порядок срабатывания OnOrder(), OnTrade() достоверно не предопределен. Во-вторых, там свои неоднозначности. Допустим, использую я move_order. Прилетает сделка, а заявка еще пришла, а если пришла в OnOrder() и "исполнена", то надо еще разобраться, что это означает: а) успела исполниться старая заявка до перестановки, б) успешно переставилась, в) исполнилась уже новая после перестановки.


Есть ли компактные решения менее 1000 строк? :)

Спасибо!
Пропадает функция в процессе выполнения, не могу записать лог в определенных местах кода, хотя функция логирования срабатывает до и после этих мест
 
Цитата
Sergey Gorokhov написал:
Цитата
Сергей написал:
  myLog(msg)    -- ругается так: attempt to call global 'MyLog' (a nil value)

В Lua регистр имеет значение.
MyLog это НЕ тоже самое что myLog

Проверьте внимательней, раз в тексте ошибки большая буква M то и в коде она такая же, хотя Вы это не указали.
Пффф... вот я дятел )))))

Спасибо! :)
Пропадает функция в процессе выполнения, не могу записать лог в определенных местах кода, хотя функция логирования срабатывает до и после этих мест
 
Добрый день!

Кажется, я туплю на пустом месте.
Проблема в описании темы: функция MyLog видна с срабатывает при OnInit(), в OnStop(), в другие моменты функция "исчезает". В частности, в NewOrder() ругается.



function myLog(msg)end

function NewOrder()
   myLog(msg)    -- ругается так: attempt to call global 'MyLog' (a nil value)
end

...

function OnInit()
   myLog(msg)    -- срабатывает
end

function main()
end

function OnStop(stop_flag)
   myLog(msg)    -- срабатывает
end

function OnOrder(order)
   myLog(msg)
end

function OnTrade(trade)
   myLog(msg)
end

function OnQuote(class_code, sec_code)
   ..
   NewOrder()
   ..
end
Изменяя копию таблицы, меняется оригинальная таблица., Особенность языка lua?
 
Сергей и Mike, спасибо вам!
Изменяя копию таблицы, меняется оригинальная таблица., Особенность языка lua?
 
Цитата
Смотрите документацию Lua

https://www.lua.org/manual/5.3/manual.html#3.3.3

Там сказано:

Цитата
Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.
Жесть... Как люди с этим живут? :) В цикле по элементам копию создавать для манипуляций без повреждения оригинала?
Изменяя копию таблицы, меняется оригинальная таблица., Особенность языка lua?
 
Обнаружил неприятную (для себя) штуку. Нужно проанализировать как-то таблицу. В моем конкретном случае понадобилось выбросить несколько максимальных значений и найти среднее среди остальных.


Соответственно, я создал копию таблицы простым присваиванием. Затем отсортировал копию, по неполному циклу прогнал этот массив - сложил элементы, потом разделил на число оставшихся элементов. Обнаружил, что после сортировки оказалась отсортированной и оригинальная таблица. Что за фигня? Очень непривычная особенность языка.

Получается, когда я присваиваю массив, я фактически просто создаю ссылку на оригинальный массив. При обращении по любому имени редактируются одни и те же данные? Как создать фактическую копию таблицы? По элементам в цикле присваивать? :))
странный update quik, onTrade 3-6 раз
 
Ну и флейм там Старатель развел... Но именно благодаря ему многое стало понятно "очень" :)
Старателю, наверно, стоило бы свой собственный терминал написать, чем так с поддержкой рубиться :)
Столько нервов потрачено с обеих сторон... Нерентабельная битва :)
странный update quik, onTrade 3-6 раз
 
05/23/16 15:54:22  Order=21375094379
Таких пришло 6 штук. Подозреваю, все же это были две серии с разными trade_num. Позавчера я еще тупил с возможностью различать такие сделки :) Свежих нет.
странный update quik, onTrade 3-6 раз
 
1. то есть, внутри одного класса "SPBFUT" нет такой вероятности? Указанная выше проверка надежна?
2.
Код
function OnTrade(trade)
...
        myLog('OnTrade:  qty='..trade.qty.." Order="..trade.order_num.." Trade="..trade.trade_num..' Value='..trade.value)
end
...и потом наблюдаю их в логе по 6 штук (редко), обычно по 3
странный update quik, onTrade 3-6 раз
 
Sergey Gorokhov,
1. есть ли вероятность, что колбек с меньшим trade.trade_num впервые придет позже, чем колбек с каким-то бОльшим trade.trade_num?
2. у меня реально приходят по 6 вызовов иногда. Торгую через Промсвязьбанк. Что за параметры можно в сделке менять и дополнять по шесть раз?
странный update quik, onTrade 3-6 раз
 
Повторное срабатывание колбеков - явление нормальное... OnOrder у меня и раньше многократно срабатывали, никак не мешали, а OnTrade стал многократно срабатывать только на днях.

Я не стал запоминать Id сделок в таблице, в тектовую переменную пихать и т.п. Можно все проще сделать:
Цитата
LastTrade = 0
...
function OnTrade(trade)
       if LastTrade >= trade.trade_num then return end
       [здесь тело обработки вызова]
       LastTrade = trade.trade_num
end

Идентификаторы сделок увеличиваются. Это порядковый номер сделки на сервере. То есть, обрабатывать нужно только те вызовы, где идентификатор больше ранее приходивших.
странный update quik, onTrade 3-6 раз
 
Эээээ... блин... а чего-то это их не отличить?! trade_num же есть... )))))
Извините, редко программлю, не все помню )
Большое спасибо!
странный update quik, onTrade 3-6 раз
 
Сергей, предложенное решение выглядит очень рискованным. У меня парный трейдинг. Заявки по инструментам А и B выставляются одновременно. Конкретный сегодняшний пример. По инструменту А заявка была исполнена за две сделки А1 и А2, причем, по первой OnTrade сработал 6 раз, по второй 3 раза и по другому инструменту тоже 3 раза, и все это было жутко перемешано:

A1
A1
A1
A1
A2
A1
A1
A2
B
A2
B
B

Если бы объем по А1 и А2 был одинковым, их бы вообще не отличить... Мне как сравнение с номером последней сделки помочь может и как часто обновляется эта таблица сделок?
Все это нужно для быстрого расчета текущей позиции, которую вообще-то можно и в getItem("FUTURES_CLIENT_HOLDING",i).totalnet посмотреть... только эта таблица обновляется жутко редко. Наверно, где-то в настройках можно это время уменьшить, но все равно... За время между обновлениями можно так наторговать, что торговать будет нечем :) И каков вообще практический смысл от этих колбэк фукнций, если собственную позицию приходится определять вот так криво через анализ таблиц?

Не припомните ли вы обсуждение какого-либо более быстрого и надежного способа?

Спасибо!
странный update quik, onTrade 3-6 раз
 
Сергей, а изменения-то где и с чем они связаны? Робот у меня работает всего два месяца, все это время приходило по одному OnTrade на одну фактическую сделку. Это было удобно. Что и почему изменилось сейчас... и как теперь отличать новые и повторные OnTrade с одинаковыми идентификаторами?
Страницы: 1 2 След.
Наверх