Как с помощью колбека OnTrade понять, что заявка с известным номером исполнилась полностью или частично? Как то же самое узнать с помощью колбека OnOrder?
Скрипт организован вот так: То есть он не видит файл в той же папке где лежит запускаемый скрипт. Но стоит запускамый скрипт Unitas 3.0.lua удалить а потом добавить, как всё начинает работать:
Запустил КВИК, нажал кнопку Запустить - не работает. Удалил скрипт из списка, добавил снова, запустил - работает.
биржа штрафует за ошибочные транзакции. хочу уточнить - если я вижу такое сообщение, значит моя транзакция не долетела до биржи и отбита сервером брокера?
Пытаюсь переписать на Питоне индикатор Фрактал (код ниже). Но не могу понять что в этом коде происходит. Помогите пожалуйста написать на питоне индикатор фрактал для самого простого случая - список цен: Например, как найти верхний фрактал (для пиков)? price=[186.99,190.99,191.24,197,196.75,196.8,196.8,198,201.26,203.32,208.44,207.17,207.95,210.4,212.2,212,209.7,213.61,213.14,217.9,216.29,215.5,217.85,216.59,211.01,210.43,214,219.1,213.9,204.43,208,204.19,202.08,206.89,203.41,205.25,205.86,205.8,205.4,207.8,206.54,205.5,202.92,205,203.95,205.25,205.1,206,203.66,203.55,205.9,207.7,209.8,210.61,207.7,214,218,214.1,215.07,214.42,217.7,218.23,219.05,221.8,227.5,232.3,238,243.68,238.86,239.5,237.8,233.24,234.3,232.79,232.6,235.41,235.67,236,227.8,223.18,228.8,225.17,229.1,232.52,232.8,231.49,230,227,224.22,227.88,228.69,228.19,226.94,226]
Код
Settings = {
Name = "*FRACTALS (Fractals)",
Period = 5,
line = {{
Name = "Horizontal line",
Type = TYPE_LINE,
Color = RGB(140, 140, 140)
},
{
Name = "FRACTALS - Up",
Type = TYPE_TRIANGLE_UP,
Color = RGB(0, 206, 0)
},
{
Name = "FRACTALS - Down",
Type = TYPE_TRIANGLE_DOWN,
Color = RGB(221, 44, 44)
}
},
Round = "off",
Multiply = 1,
Horizontal_line="off"
}
function Init()
func = FRACTALS()
return #Settings.line
end
function OnCalculate(Index)
local Out1,Out2 = func(Index, Settings)
SetValue(Out1, 2, ConvertValue(Settings,H(Out1)))
SetValue(Out2, 3, ConvertValue(Settings,L(Out2)))
return tonumber(Settings.Horizontal_line),nil,nil
end
function FRACTALS() --Fractals ("FRACTALS")
local H_tmp={}
local L_tmp={}
local it = {[1]=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 5)
if (P>0) then
if I == 1 then
H_tmp={}
L_tmp={}
it = {[1]=0, l=0}
end
if CandleExist(I,ds) then
if I~=it[Squeeze(it.l,P)] then
it.l = it.l + 1
it[Squeeze(it.l,P)] = I
end
local Ip,Ipppp = Squeeze(it.l,P),Squeeze(it.l,P-1)+1
local nP = math.floor(P/2)*2+1
H_tmp[Ipppp] = GetValue(it[Ip],HIGH,ds)
L_tmp[Ipppp] = GetValue(it[Ip],LOW,ds)
if it.l >= nP then
local S = it[Squeeze(it.l-nP+1+math.floor(nP/2),P)]
local val_h=math.max(unpack(H_tmp))
local val_l=math.min(unpack(L_tmp))
local L = GetValue(S,LOW,ds)
local H = GetValue(S,HIGH,ds)
if (val_h == H) and (val_h >0)
and (val_l == L) and (val_l > 0) then
return S,S
else
if (val_h == H) and (val_h > 0) then
return S,nil
end
if (val_l == L) and (val_l > 0) then
return nil,S
end
end
end
end
end
return nil,nil
end
end
SMA,MMA,EMA,WMA,SMMA,VMA = "SMA","MMA","EMA","WMA","SMMA","VMA"
OPEN,HIGH,LOW,CLOSE,VOLUME,MEDIAN,TYPICAL,WEIGHTED,DIFFERENCE,ANY = "O","H","L","C","V","M","T","W","D","A"
function CandleExist(I,ds)
return (type(C)=="function" and C(I)~=nil) or
(type(ds)=="table" and (ds[I]~=nil or (type(ds.Size)=="function" and (I>0) and (I<=ds:Size()))))
end
function Squeeze(I,P)
return math.fmod(I-1,P+1)
end
function ConvertValue(T,...)
local function r(V, R)
if R and string.upper(R)== "ON" then R=0 end
if V and tonumber(R) then
if V >= 0 then return math.floor(V * 10^R + 0.5) / 10^R
else return math.ceil(V * 10^R - 0.5) / 10^R end
else return V end
end
if arg.n > 0 then
for i = 1, arg.n do
arg[i]=arg[i] and r(arg[i] * ((T and T.Multiply) or 1), (T and T.Round) or "off")
end
return unpack(arg)
else return nil end
end
function GetValue(I,VT,ds)
VT=(VT and string.upper(string.sub(VT,1,1))) or ANY
if VT == OPEN then --Open
return (O and O(I)) or (ds and ds:O(I))
elseif VT == HIGH then --High
return (H and H(I)) or (ds and ds:H(I))
elseif VT == LOW then --Low
return (L and L(I)) or (ds and ds:L(I))
elseif VT == CLOSE then --Close
return (C and C(I)) or (ds and ds:C(I))
elseif VT == VOLUME then --Volume
return (V and V(I)) or (ds and ds:V(I))
elseif VT == MEDIAN then --Median
return ((GetValue(I,HIGH,ds) + GetValue(I,LOW,ds)) / 2)
elseif VT == TYPICAL then --Typical
return ((GetValue(I,MEDIAN,ds) * 2 + GetValue(I,CLOSE,ds))/3)
elseif VT == WEIGHTED then --Weighted
return ((GetValue(I,TYPICAL,ds) * 3 + GetValue(I,OPEN,ds))/4)
elseif VT == DIFFERENCE then --Difference
return (GetValue(I,HIGH,ds) - GetValue(I,LOW,ds))
else --Any
return (ds and ds[I])
end
return nil
end
Мне нужна непрерывная запись изменяющегося лучшего бида. Объясните пожалуйста, как мне его получить с помощью CreateDataSource. Или всё-таки придётся писать онлайн лог изменения текущей таблицы?
Let_it_go написал: Записываю лучшие биды и аски по акциям средней ликвидности, например Распадская RASP. Что лучше выбрать: OnParam или OnQuote? Сомнения связаны с тем, что текущая таблица транслируется срезами раз в 50 миллисекунда, то есть будут пропущенные данные. А стакан? Он транслируется срезами или безостановочно?
получать историю параметра 'лучший бид' через createdatasource
Майк, спасибо за ответ. Не первый раз выручаете. Но я не понимаю как это сделать. Документация не раскрывает подробности:
Записываю лучшие биды и аски по акциям средней ликвидности, например Распадская RASP. Что лучше выбрать: OnParam или OnQuote? Сомнения связаны с тем, что текущая таблица транслируется срезами раз в 50 миллисекунда, то есть будут пропущенные данные. А стакан? Он транслируется срезами или безостановочно?
Есть цикл, внутри которого качаются котировки с финама по многим инструментам. for i=start_year,cur_year,1 do
end В начале почти по всем акциям прилетают пустые годы (котировок ещё нет) Первый НЕпустой год я брать не хочу, потому что котировки ещё не адекватные. Я хочу брать второй не пустой год. То есть цикл должен быть таким
Код
for i=start_year,cur_year,1 do
--если размер таблицы нулевой, шагаем на 2 шага
--после этого всегда шагаем 1 шагом
end
sergei написал: data mining вряд ли целесообразно на lua делать, особенно в таких масштабах производительность должна быть в разы (если не на порядки) ниже более целесообразного варианта
при сбое в электропитании даже промежуточных результатов не будет, да?
Есть две огромных таблицы, которые описывают одни и те же свечки
Код
t_big[candle] --хранит цены: {1=open,2=high,3=low,4=close}
sd[candle]--хранит стандартные отклонения для этих свечек: sd[candle]=4.6432234444
Брут форс многкратно обращается к этим полям в поисках наилучших параметров. Крутит цикл, внутри него ещё цикл, а потом ещё цикл. На просчёт пятиминуток за 12 лет по 21 акции у меня ушла неделя. Объединение этих таблиц в одну приведёт ли к ускорению доступа к их полям? Хотя бы небольшому. Или это нейтрально?
Сергей написал: Интересно вы роботов пишете! Ни одной тривиальной проблема :)
Что там с темным окошком и питоном было? Хоть о финалах этих битв сообщайте! Жуть, как интересно )
Поставил sleep(100) между записью в файл и запуском этого файла в питоне. Пока проблема не повторялась. Возможно раньше, на момент когда питон обращался к этому файлу, с ним ещё что то происходило.
Сергей написал: Файл tmp.txt может быть залочен или что-то подобное? В lua ошибку искать просто негде. Отдельно питоновский скрипт всегда работает? Не знаю, как идет процесс отладки питонов под виндой, но можно тупо добавить там print после каждой строки. Может, он у вас до седьмой строки часто не доходит, не только до 14.
Когда всё работает нормально, в чёрном окошке пишется то, что задумано. Это пишет питоновская функция print: Lua-функция os.execute возвращает 0 (признак успеха). Но часто бывает такая ерунда. Чёрное окошко появляется, в нём ничего не пишется. До print в 14 строчке не доходит. И так навеки, пока это окошко не закрыть. После закрытия окошка функция os.execute раздупляется и возвращает огромное отрицательное число, например -1073741510 Данные не получены, надо запускать скрипт заново. Помогите побороть этот глюк. Самое обидное то, что функция os.execute на время пустого чёрного окошка оказывается в подвешенном состоянии. Пока висит чёрное окошко, она ничего не возвращает, а значит нельзя обработать ошибку.
Есть ряд чисел от 0 до 10 с шагом 0,1 0 - белый цвет (точнее розовый, доведённый до стадии белого) промежуточные цвета - розовые разной насыщенности 10 - красный цвет Чем ближе к 10, тем сильнее розовый превращается в красный. помогите пожалуйста задать это на Луа. Это будет работать в таблице КВИКа и задаваться через SetColor Если по простому, мне это надо, чтобы сильно упавшие акции были ярко-красными, а слабо упавшие были розовыми. Чем сильнее упала акция, тем интенсивнее красный цвет. Надеюсь, понятно выразил мысль.
Когда-то скачал робота, который заходит на сайт Смарт Лаб и считывает с него календарь дивидендов, сигналит в КВИК если завтра ожидается дивидендный гэп. Сейчас скрипт не работает, потому что смарт лаб поменял вёрстку дивидендной страницы, но раньше я этот скрипт запускал и всё работало.
Код
if string.find(package.path,'C:\\Program Files (x86)\\Lua\\5.1\\lua\\?.lua')==nil then
package.path=package.path..';C:\\Program Files (x86)\\Lua\\5.1\\lua\\?.lua;'
end
if string.find(package.path,'C:\\Program Files\\Lua\\5.1\\lua\\?.lua')==nil then
package.path=package.path..';C:\\Program Files\\Lua\\5.1\\lua\\?.lua;'
end
require "socket"
is_run=true
http = require 'socket.http'
local address = 'http://smart-lab.ru/dividends/index/order_by_t2_date/desc/'
local ts={"tr","strong","span"}
local lMax=91 --число строк в таблице
function do_smart ()
local body = http.request(address)
----------------------
for i=1,#ts do
body = string.gsub (body,"(<%s*"..ts[i].."[^>]*>)","")
body = string.gsub (body,"(<%s*/"..ts[i].."[^>]*>)","")
end
body = string.gsub (body," "," ")
local t={} -- результат
local j=0; local k=0; local text=0;
local m=1;
local n=string.find(body,"td>",m,#body,true);
local x=string.byte(body,n-1);
m=m+3;
-----------------
while #body>m do
n=string.find(body, "td>",m,#body,true);
if n then local n1=n;
if x~=47 then
x=string.byte(body,n-1); if x==47 then n=n-1; end
text = string.sub(body, m,n-2); text = nkdelspace(text);
local len=string.len(text);
if len<20 then
j=j+1; if j==1 then k=k+1; t[k]={} end
local tt=t[k]; tt[#tt+1]=text;
if j==8 then if k==lMax then break end
j=0 end
end
else
x=string.byte(body,n-1);
end
m=n1+3;
else break;
end
end
trade_date=getParamEx("TQBR","GAZP","TRADE_DATE_CODE").param_image
prev_date=getParamEx("TQBR","GAZP","PREVDATE").param_image
for k,v in ipairs (t) do
local td=trade_date.." "
local pd=prev_date.." "
if td==t[k][2] then
message ("Zavtra GAP "..t[k][1].." div="..t[k][6].." | "..t[k][8],1)
end
if pd==t[k][2] then
message ("Segodnya GAP "..t[k][1].." div="..t[k][6].." | "..t[k][8],1)
end
end
end
function OnCleanUp ()
sleep (700000)
do_smart ()
end
function OnConnected ()
do_smart ()
end
function OnStop ()
return 100
end
--------------------
function nkdelspace(s)
local len=string.len(s); local z=""; local x1=32;
for i=1,len do local x=string.byte(s,i); if x<32 then x=32 end
if (x~=32 or x1~=32) then
if z=="" then z=string.char(x) else z=z..string.char(x) end
x1=x; end
end --убираем проблелы
return z;
end
do_smart ()
function main ()
while is_run do
sleep (1000)
end
end
в комплекте скрипта в архиве были библиотеки Socket и mime Вот пост где автор опубликовал этого робота с описанием что он делает https://smart-lab.ru/blog/401675.php
Этот код будет выводить Вам все слова из введённой строки, пока Вы не введёте пустую строку. Если не проверять на ввод пустой строки, то программа сама не завершится, т.к. пустая строка -- это всё ещё строка (т.е. не nil).
Всё же оно чуть по другому работает. дублирует одну строку. Если бы я как-то ухитрился ввести здесь 10 строк, он бы выдал 10 строк. Но не понятно как в этом окошке ввести ради тестов более чем 1 строку.
И раз уж пошла такая пьянка, второй вопрос оттуда же.
Код
function allwords ()
local line = io.read() -- текущая строка
local pos = 1 -- текущая позиция в строке
return function () -- итерирующая функция
while line do -- повторяет, пока есть строки
local s, e = string.find(line, "%w+", pos)
if s then -- слово найдено?
pos = e + 1 -- следующая позиция после этого слова
print(string.sub(line, s, e))
return string.sub(line, s, e) -- возвращает это слово
else
line = io.read() -- слово не найдено; пробуетследующую строку
pos = 1 -- перезапуск с первой позиции
end
end
return nil -- строк больше нет; конец обхода
end
end
Как эту функцию вызвать? io.read считывает вводимый мною текст, и ничего не просиходит
Читаю книжку Иерусалимскиса про Луа. Вот код оттуда.
Код
function values (t)
local i = 0
return function () i = i + 1; return t[i] end
end
t = {10, 20, 30}
iter = values(t) -- создает итератор
while true do
local element = iter() -- вызывает итератор
if element == nil then break end
print(element)
end
Если у вашего брокера несколько серверов, вы можете запустить три КВИКа и в каждом открыть по 200 стаканов. Не вживую открыть, а с помощью Луа естественно. Я в Открытии так и делаю. Если приноровиться и понять какие сервера позволяют это делать, можно залогиниться одновременно тремя квиками. Например Сервер Билайн Сервер №3 Сервер Макомнет.
function newCounter ()
local i = 0
return function () i = i + 1 return i end
end
c1 = newCounter()
print(c1()) --> 1
print(c1()) --> 2
Почему второй принт выводит 2, а не 1? Ведь во второй строчке идёт обнуление переменной i. Она не может сохранить старое значение 1 и превращается в 0. Откуда 2?
Иду по книжке иерусалимскиса "Программирование на Луа" Поясните пожалуйста этот пример
Код
function derivative (f, delta)
delta = delta or 1e-4
return function (x) return (f(x + delta) - f(x))/delta end
end
c = derivative(math.sin)
print(math.cos(5.2), c(5.2))
Подскажите пожалуйста, что в этом коде делает _Window и чем она отличается от Window?
Код
function Window (options)
-- проверка обязательных опций
if type(options.title) ~= "string" then
error("no title")
elseif type(options.width) ~= "number" then
error("no width")
elseif type(options.height) ~= "number" then
error("no height")
end
-- everything else is optional
_Window(options.title,
options.x or 0, -- значение по умолчанию
options.y or 0, -- значение по умолчанию
options.width, options.height,
options.background or "white", -- по умолчанию
options.border -- по умолчанию false (nil)
)
end
Это код из Главы 5.3. книги Иерусалимскиса Программирование на Луа. Речь идёт про именованные аргументы. Перед приведённым кодом идёт текст:
Добрый день. Функция os.clock() почему то вернула неадекватное значение, хотя всегда работала нормально согласно ожиданиям. Терминал стоит на виртуалке, не выключался несколько недель. Произошёл "перешаг" в новый месяц с ноября на декабрь... Не знаю важно ли это для установления проблемы. Из за чего это может быть?
Я в этом толком не разбираюсь, но Луа преподносится как язык настолько лёгкий для внедрения, что мне это кажется элементарной задачей - поменять старую версию на новую. Наверное я просто ничего не понимаю в этом.
пишу dll на C++ для КВИКа (вызывается через Lua) Схема действий такая. Десятки файлов, каждый по 50-100 тысяч строк хранят биржевую информацию, которую я каждый день записываю. Тестер будет прочёсывать множество таких накопленных файлов. Поиск наилучшего параметра будет проходить обычным брутфорсом, например, параметр А прогнать на каждом из файлов, меняя значение параметра с 1 до 100, то есть сто итераций. Какой путь лучше избрать с точки зрения скорости исполнения? 1. Значения из файла (те самые 50 тысяч строк) считываются в оперативную память и хранятся в массиве map. Робот прогоняет 100 значений параметра на содержимом этого map. 2. На каждой итерации робот читает файл строчку за строчкой, то есть каждый раз обращается к тексту, не запоминая содержимое файла. Что будет быстрее? Попробовать оба варианта мне будет сложно из-за слабых программистских навыков, поэтому прошу опытных людей подсказать лучший путь.
Ещё один вопрос из разряда простых, но для меня он не решаем. Поставил текстовый редактор SciTE - родной блокнот для Луа. Пытаюсь что-то в нём написать и исполнить: Расшифровка кроказябр справа даёт такой текст: "lua5.1" не является внутренней или внешней командой, исполняемой программой или пакетным файлом.
Уже не первый год работаю с индикаторами INDICATORS.ZIP, написанными Сергеем Гороховым. https://arqatech.com/upload/iblock/2eb/INDICATORS.zip Как в этих индикаторах, на примере Moving Average отсекать свечки премаркета (те которые 9:59)? Где ставить проверку "Если время меньше 10 часов, то игнорировать свечу?" Спасибо.
Скрипт работает и делает то что нужно, но на каждой итерации вызывается раздражающее окошко cmd.exe:
Код
for i=2000,2018 do
--подготовка настроек для скрипта питона
os.execute("C:\\InstallPython\\python.exe C:\\py+lua\\parser.py")
--работа с данными, полученными питоном
end
os.execute("C:\\py+lua\\parser.pyw") ИЛИ os.execute("C:\\InstallPython\\pythonw.exe C:\\py+lua\\parser.pyw") не решили проблему. Видимо, окошко вызывается не питоном, а командой Луа os.execute Подскажите, что ещё можно сделать, чтобы ИЛИ избавиться от окошка ИЛИ заставить его вызываться единожды, а не каждую итерацию как сейчас.
s_mike@rambler.ru написал: исправить сообщение на этом форуме невозможно (f..k), поэтому приходится писать новое сообщение вместо того чтобы исправить предыдущее. function new_main() -- это ваша новая main() end function main() pcall(new_main) end
Работает! А как мне отлавливать ошибки? Точнее "где их отлавливать"? Такой вариант ничего не возвращает.
Подскажите пожалуйста как этой функцией pcall обернуть функцию main? Чтобы если внутри main окажется ошибка nil, то скрипт не вылетал, а продолжал работать.