Блог им. Bondiator

Вопрос 2 по Lua

Всем привет!

Продолжаю изучать волшебный мир Луа в волшебном мире Квика и добрался до размещения скриптом заявок.
На текущий момент есть такой скрипт (в общем виде).

local SecCode = «LKU0»
local Quantity=1

function main()

while stopped == false do


local Quotes = getQuoteLevel2(«SPBFUT», SecCode)
local Offer_Price = tonumber(Quotes.offer[1].price)
local Offer_Vol = tonumber(Quotes.offer[1].quantity)

--отправка формы заявки
local LimitOrderBuy = { ххххх}

--условие входа в лонг

if Offer_Vol>10 then
message(Order)
local Order = sendTransaction(LimitOrderBuy)
end

sleep (200)
end

Смысл его такой: если количество лукойла в первой строке стакана больше 10, то покупается 1 бумага и работа скрипта завершается.
Так как скрипт срабатывает при определенном условии, то для перезапуска используется while stopped == false do и sleep (200).
Прикол в том, что при наступлении условия, скрипт начинает бомбить заявки по 1 шт  пока не кончаются деньги (виртуальные).

Вопрос: какой размыкатель цикла можно тут использовать, чтобы после покупки 1 бумаги работа скрипта завершилась?

На ресурсах есть getItem, битовые флаги и пр., но изложено это как-то непонятно.
Помогите плиз..)
ЗЫ: обещаю поставить лайк хорошим ответам )


  • обсудить на форуме:
  • Quik Lua
★2
25 комментариев
exit есть в луа? )
ну или обычно конструкция работает так
while (stopped == false) and (buyed==false)

не знаю по правилам луа нужны там скобки или нет?
а при покупке ставишь buyed=true

if Offer_Vol>10 then
buyed=true
message(Order)
local Order = sendTransaction(LimitOrderBuy)
end

p.s. на луа ничего ни разу не писал )))
Свой Мужик, пора уже начинать )
то покупается 1 бумага и работа скрипта завершается.

по приведенному тексту не видно, чтобы работа завершалась.
Возможно, в теле условия имеет смысл написать типа
stopped = true
avatar
kachanov, нет, не срабатывает такой вариант…
Врач-бондиатОр, возможно. Покажите полный текст — смогу сказать точней почему.
Например, я не вижу как и где Вы присвоили первое значение переменной stopped.
Если не присвоили нигде, то будет работать, так как по умолчанию она будет nil, который по умолчанию в логических конструкциях определяется как false.
Допускаю, что Вы в условии написали local stopped = true (просто судя по количеству local по тексту). Тоже не будет работать, если требуется могу пояснить почему.
Общий принцип Вам уже изложили и он работает.
Использовать return тоже вариант, но, рано или поздно это решение исчерпает себя.
avatar
kachanov, спасибо. Вопрос решился )
Вначале проги поставь is_run=true, а после выполнения покупки вставь is_run=false
avatar
Ask, А покупку вставь в конструкцию  while is_run do
avatar
Ask, не срабатывает — может не туда вставил..
А есть варианты что-то вроде: если в портфеле есть 1 бумага, то работа заканчивается?
Врач-бондиатОр, 
Надо в самом начале программы поставить is_run=false
Потом все что написано выше в

function main()
while is_run do
...
  покупка
  is_run=false
...

end
end

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

function OnTrade(trd)

if trd[«account»] and trd[«account»] == account and trd[«trade_num»] > untrade and trd[«sec_code»] == sec then
if bit.band(tonumber(trd[«flags»]), 4) > 0 then — bit.band(tonumber(trd[«flags»]), 4) > 0 флаг 4 больше нуля — продажа
Position = Position — tonumber(trd[«qty»]) — продажа
else
Position = Position + tonumber(trd[«qty»]) — покупка
end
if Position ~= 0 then




elseif Position == 0 then




end

untrade = trd[«trade_num»] 
end

end

avatar
Сергей Сергаев, Вот человек грамотно разжевал.
avatar
В глобальной области в одной переменной храните плановое кол-во лотов, во второй — подтвержденное набранное. Значение во второй переменной обновляете по мере исполнения заявок. Как только плановое кол-во лотов совпало с подтвержденным набранным, обнуляете плановое. В цикле выставления заявки прописываете условие о том, что цикл должен выполняться, если плановое кол-во лотов > 0 и > набранного. Как-то так.
avatar
return — выход из функции
break — выход из цикла

То есть, по логике «покупается бумага и работа скрипта завершается» необходимо

if Offer_Vol>10 then
message(Order)
local Order = sendTransaction(LimitOrderBuy)
return
end
avatar
Но вообще, конечно, кровь из глаз такие скрипты :)
avatar
PSH, сработал ваш вариант. Но других скриптов пока нет, извините уж…
Врач-бондиатОр, Москва не сразу строилась, я без претензий, не подумайте, это мой внутренний перфекционист лютует :)
avatar
Что тут особенно зубодробительно:
while stopped == false

Сравнение булевой переменной с булевым значением для того только, чтобы получить булево значение, абсолютно избыточно. К тому же, переменная stopped вообще нигде не инициализируется, то есть равно null

Работать будет и

while not stopped

но читать удобнее второе.

Более того, раз нам нужно впасть в бесконечный цикл, вполне достаточно будет

while true

Тут вообще никаких переменных нет и сразу видно, что это бесконечный цикл
avatar
Вообще, использование бесконечных циклов — это плохая практика. Функция должна что-то сделать и отвалиться, а не зависать на неопределенный срок
avatar

function OnInit()

is_run = true

end

function main()

CurrentPos() — проверка начального остатка

local StarttNetPos = TotalNetPos — запоминание остатка

while is_run do

— ваше условие выставление ордера

CurrentPos() — проверка остатка по бумажке

if TotalNetPos ~= StarttNetPos then is_run = false end — если изменился, то сделка исполнена — ОСТАНОВКА СКРИПТА

end

end

function CurrentPos()

for i = 0, getNumberOf(«FUTURES_CLIENT_HOLDING») — 1 do

if getItem(«FUTURES_CLIENT_HOLDING»,i).sec_code == p_SECCODE and getItem(«FUTURES_CLIENT_HOLDING»,i).totalnet ~= 0 then

TotalNetPos = getItem(«FUTURES_CLIENT_HOLDING»,i).totalnet

end

end

end

Вот так будет работать

avatar
 Только единственное вместо этого FUTURES_CLIENT_HOLDING надо посмотреть как обращаться к таблице с остатками по акциям
avatar
 

function OnInit()

SecCode = «LKU0»
Quantity=1

is_run = true

end

function main()

CurrentPos() — проверка начального остатка

local StarttNetPos = TotalNetPos — запоминание остатка

while is_run do

local Quotes = getQuoteLevel2(«SPBFUT», SecCode)
local Offer_Price = tonumber(Quotes.offer[1].price)
local Offer_Vol = tonumber(Quotes.offer[1].quantity)

--отправка формы заявки
local LimitOrderBuy = {xxx}

--условие входа в лонг

if Offer_Vol>10 then
message(Order)
local Order = sendTransaction(LimitOrderBuy)
end

sleep (200)

CurrentPos() — проверка остатка по бумажке

if TotalNetPos ~= StarttNetPos then is_run = false end — если изменился, то сделка исполнена — ОСТАНОВКА СКРИПТА

end

end

function CurrentPos()

for i = 0, getNumberOf(«ACCOUNT_BALANCE») — 1 do

if getItem(«ACCOUNT_BALANCE»,i).sec_code == SecCode and getItem(«ACCOUNT_BALANCE»,i).currentpos ~= 0 then

TotalNetPos = getItem(«ACCOUNT_BALANCE»,i).currentpos

else

TotalNetPos = 0

end

end

end

Вот так будет точнее

avatar

теги блога Врач-бондиатОр

....все тэги



UPDONW
Новый дизайн