VPM написал: Но сколько копий сломано, пока разобрался с кольцевым буфером
Выложи пожалуйста свой вариант кольцевого буфера, мне тоже он был нужен, вот что через gpt получилось (может кому-то нужно):
Код
function CycleRowIndex(arr_input, operation)
-- Пример вызова, есть массив arr:
-- local currentRow = CycleRowIndex(arr, "current") выдаст текущую строку
-- local firstRow = CycleRowIndex(arr, "first") выдаст первую строку
-- local shiftRow = CycleRowIndex(arr, "shift") "сдвинет" строку
if #arr_input == 0 then
return nil -- если массив пуст, возвращаем nil
end
arr_input.currentRow = arr_input.currentRow or 0 -- используем строковый ключ
local arraySize = #arr_input
local currentRow
if operation == "first" then
local lastRow = arr_input.currentRow
if lastRow <= arraySize then
currentRow = 1
else
currentRow = ((lastRow) % arraySize) + 1
end
elseif operation == "current" then
currentRow = (arr_input.currentRow) % arraySize
if currentRow == 0 then
if arr_input.currentRow >= arraySize then
currentRow = arraySize
else
currentRow = 1
end
end
elseif operation == "shift" then
currentRow = (arr_input.currentRow) % arraySize + 1
arr_input.currentRow = arr_input.currentRow + 1
end
return currentRow
end
Вручную на практике снимать удается (хорошо, что он не рыночные заявки создает), смотришь в таблицу - новая заявка и сразу отменяешь. Возможно брокер и прав, но, не называя имена брокеров хочу сказать, что у старого такой фигни не было, он позволял держать опционы до дня исполнения даже если не хватает обеспечения, а новый за пару дней уже мутит что хочет. Старого брокера выкупили...
Ставить такие заявки могут в региональном офисе брокера. Дело конечно ваше, полагаю зря в опционы полезли. Возможно у Вас позиция при которой в случае неудачи Вы будете должны брокеру кучу бабла. Вот он и страхуется, так как деньги не его а клиентов.
Дело вот в чем. Опционы куплены (а не проданы, то есть не short) с запасом на балансе (потерять в данном случае больше стоимости самих опционов невозможно). Далее если опционы "в цене" есть два варианта: либо ДО момента исполнения обеспечить деньгами сумму ГО для фьючерсов, либо продать эти опционы. Но брокер заранее, за несколько дней уже продает эти опционы обратно (если на балансе не хватает ГО) и пропускается хорошие движения цен (я бы их продал например за пару часов до исполнения, а не за 3 дня). А к примеру, на 70 опционов Si нужно иметь на счете 1 000 000 рублей, что то не хочется доверять брокеру такие деньги с таким поведением... Да и вообще никому нельзя доверять большие деньги)
Вручную на практике снимать удается (хорошо, что он не рыночные заявки создает), смотришь в таблицу - новая заявка и сразу отменяешь. Возможно брокер и прав, но, не называя имена брокеров хочу сказать, что у старого такой фигни не было, он позволял держать опционы до дня исполнения даже если не хватает обеспечения, а новый за пару дней уже мутит что хочет. Старого брокера выкупили...
Кто может подсказать, как отследить заявку от администратора, и моментально снять ее? А то брокер совсем ... . До исполнения опционов еще два торговых дня, а он делает что хочет... Тут даже дело не в отслеживании конкретного номера заявки, можно простой код для снятия всех заявок (буду ночью запускать скрипт от вредителей) Примерно так: отследит колбек черер OnTransReply() и далее снять все активные заявки. Вот со снятием всех активных заявок нужно разобраться.
Где почитать подробое руководство по этой версии? Какие ошибки могут возникнуть, и особенно интересует поддерживает ли комментарии, имена переменных и т.д. на русском языке?
Скорее всего, многие в курсе, как брать инфу по открытому интересу. Допустим в моменте 5 секунд он = + 500. Возможно ли в моменте как-то вычислить поподробнее, например что стало с участниками - кого больше прибавилось, кто в ЛОНГ или в ШОРТ, и т.д.?
Хотя если указать, что заявка лимитировання (["TYPE"]="L") и указать конкретную цену (на n пунктов хуже ["STOPPRICE2"]) - то я думаю проблемы этой не будет
Ренат написал: Всех с наступившими праздниками. Всем спасибо за помощь. Выставляется заявка. Но при достижении стоп цены появляются две ошибки.
Заявка, выставляемая по стоп-заявке N [10872095], отвергнута торговой системой: Order price 0.00 is out of set interval from 106.85 to 178.07
или
Стоп-заявка N [10872094] не прошла контроль лимитов
От чего так?
Проверьте параметр ["PRICE"]. Из руководства: ["PRICE"] - Цена заявки, за единицу инструмента. Обязательный параметр. При выставлении рыночной заявки (TYPE=M) на Срочном рынке FORTS необходимо указывать значение цены – укажите наихудшую (минимально или максимально возможную – в зависимости от направленности), заявка все равно будет исполнена по рыночной цене. Для других рынков при выставлении рыночной заявки укажите price=0
Для себя когда то делал, даже с рисунком, вроде все правильно. Может пригодится ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ table_stop_order= { ["ACTION"]="NEW_STOP_ORDER", ["STOP_ORDER_KIND"]="TAKE_PROFIT_AND_STOP_LIMIT_ORDER", ["EXPIRY_DATE"]="GTC", --до отмены ["IS_ACTIVE_IN_TIME"]="NO", ["SECCODE"]=tostring("SiH3"), ["ACCOUNT"]=tostring("111GJBJ"), ["OPERATION"]=tostring("B"), --Значения: «S»–продать, «B»–купить ["STOPPRICE"]=string.format("%.0f",72850), --Цена условия «тэйк-профит» для заявки типа «Тэйк-профит и стоп-лимит» ["STOPPRICE2"]=string.format("%.0f",72800), --Цена условия «стоп-лимит» для заявки типа «Тэйк-профит и стоп-лимит» ["PRICE"]=string.format("%.0f",72750), --Цена, по которой выставится заявка при срабатывании стоп-лимита ["MARKET_STOP_LIMIT"]="NO", --Признак исполнения заявки по рыночной цене при наступлении условия «стоп-лимит». ["QUANTITY"]=string.format("%.0f",1), --Объем ["CLIENT_CODE"]=tostring("111GJBJ"), --Номер торгового счета вообще не нужен здесь без него работает ["OFFSET"]="0", --Величина отступа от максимума (минимума) цены последней сделки ["OFFSET_UNITS"]="PRICE_UNITS", --Единицы измерения отступа. Возможные значения: «PERCENTS» – в процентах «PRICE_UNITS» – в параметрах цены ["SPREAD_UNITS"]="PRICE_UNITS", --Единицы измерения защитного спрэда. Возможные значения: «PERCENTS» – в процентах «PRICE_UNITS» – в параметрах цены ["SPREAD"]=tostring("100"), --Величина защитного спрэда. Возможные значения: «PERCENTS» – в процентах «PRICE_UNITS» – в параметрах цены ["MARKET_TAKE_PROFIT"]="NO", --Признак исполнения заявки по рыночной цене при наступлении условия «тэйк-профит» ["CLASSCODE"]=tostring("SPBFUT"), ["TRANS_ID"]=tostring("2147483647") --TRANS_ID заявки должен быть числом --["TYPE"]="L", --«L»–лимитированная (по умолчанию), «M»–рыночная } result=sendTransaction(table_stop_order) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Айдар написал: Допустим, крайняя сделка была по цене ask - в данном случае цена поднялась вверх. Но может ли такое быть, что если далее сделка тоже по ask - но цена опустилась вниз? При просмотре сохраненных данных иногда выявляются такие моменты. Вот хочу понять, или у меня в коде косяк или что-то другое
Этот вопрос для меня важен, для понимания прикрепляю скриншот. Тут я как понимаю может такое случаться при спрэде или из-за того, что поток обезличенных сделок как-то не попорядку что-ли передается. Кто сможет объяснить?
Допустим, крайняя сделка была по цене ask - в данном случае цена поднялась вверх. Но может ли такое быть, что если далее сделка тоже по ask - но цена опустилась вниз? При просмотре сохраненных данных иногда выявляются такие моменты. Вот хочу понять, или у меня в коде косяк или что-то другое
В колбеке OnStopOrder зацепился за параметр "filled_qty" (исполненное количество). И по нему ставлю условия - если >0 (неважно весь объем исполнился или нет) - то заявку удалять уже поздно. Пока проверяю
Айдар написал: Чтобы изменить параметры действующей стоп-заявки я удаляю действующую и выставляю новую. Но иногда происходит так, что во время удаления эта стоп-заявка успевает сработать - и в этом случае новая уже не требуется, но в алгоритме это не прописано и все-равно выставляется новая-стоп заявка. Как можно это исправить? Спасибо
При отправке стоп-заявки переменная Param_sdelki["PRICE_CLOSE_STOP"] = 0. Затем в OnTrade если стоп-заявка срабатывает то ей присваивается цена: function OnTrade(TABLE_trade) --номер стоп-заявке тоже присваивается с этим проблем нет if TABLE_trade.trans_id==Param_sdelki["NUM_USER_STOP"] then if bit_set(TABLE_trade.flags, 0)==false and bit_set(TABLE_trade.flags, 1) == false then --стоп заявка исполнилась Param_sdelki["PRICE_CLOSE_STOP"]=TABLE_trade.price --итоговая цена закрытия стоп заявки end end
И даже проверка переменной (if Param_sdelki["PRICE_CLOSE_STOP"]=0) не всегда помогает.
Чтобы изменить параметры действующей стоп-заявки я удаляю действующую и выставляю новую. Но иногда происходит так, что во время удаления эта стоп-заявка успевает сработать - и в этом случае новая уже не требуется, но в алгоритме это не прописано и все-равно выставляется новая-стоп заявка. Как можно это исправить? Спасибо
У меня значит так. 1. "Напридумывал" кучу формул и переменных, данные берутся: - из стакана (getQuoteLevel2()), - из ф-ции getParamEx() - количество общих заявок на покупки и продажи, - из таблицы сделок (OnAllTrade()). Все это считается и обновляется каждый тик. И затем идет вычисление разницы этих значений: - за крайние 30 сек, - за крайнюю минуту, - за крайнюю 01:30 мин, -... - за крайнюю 03:30 минуты.
2. Все данные на каждый тик сохраняются в txt файл. И чтобы дальше решить, какие значения этих переменных должны быть идеальными для long или short - все определяется уже при помощи VBA макросов в EXCEL. Там тоже напридумывано куча всего. Если коротко объяснить - там на каждый тик (по истории) расчитано какова будет цена через 10 секунд, минуту и т.д. и на основе этого уже подбираются нужные значения переменных. Для статистики берется крайние 3-4 дня. Готовый скрипт создается по нажатию кнопки (в EXCEL). Даже если данные из QUICK передаются с тормозами - то статистика же будет на основе этих данных, а значит мини запоздания уже не играет важную роль (то есть статистика уже предусматривает эти тормоза)
В общем, осталось добить пару макросов в EXCEL и уже смотреть как будет работать (пока проверяю даже не на демо счете - а просто при помощи меток, результат норм).
Спустя год мозго***бства хотелось бы понять, может у кого-то все по-проще и не нужно еб***т себе мозг?
Подскажите, пожалуйста, для понимания вот полный код: time_0=0 time_now=0 Price={}--массив сумм цен инструмента --всего в массиве пусть для примера будет 5 строк: max_rows_arr_Price=5 --в каждой строке массива сохраняется сумма сделок за 30 секунд n_sec=30 --счетчик строк n_rows=0 --================================================================================================ function OnAllTrade(alltrade) if alltrade.sec_code==instr1 then time_now=os.date("%X") local t1=os.time(Vremya_v_tablicu(time_now)) local t2=os.time(Vremya_v_tablicu(time_0)) if os.difftime(t1,t2)>=n_sec or t1.min~=t2.min or time_0==0 then n_rows=n_rows+1 time_0=os.date("%X") if max_rows_arr_Price <= 2 then Price[n_rows]=alltrade.price else --!И ВОТ ЗДЕСЬ НУЖНО ПРОПИСАТЬ КОД КАК СДВИНУТЬ МАССИВ НА 1 СТРОКУ ЖЕЛАТЕЛЬНО БЕЗ ЦИКЛА FOR???
end else Price[n_rows]=Price[n_rows]+alltrade.price end end end --================================================================================================ --c этой пользовательской функцией мне легче выполнять операции со временем function Vremya_v_tablicu(priem) priem=tostring(priem) local otpravka=os.date("!*t",os.time()) local len=string.len(priem) if len>6 then otpravka.hour,otpravka.min,otpravka.sec=string.match(priem,"(%d%d)%p(%d%d)%p(%d%d)") elseif len==6 then otpravka.hour,otpravka.min,otpravka.sec=string.match(priem,"(%d%d)(%d%d)(%d%d)") elseif len==5 then otpravka.hour,otpravka.min,otpravka.sec=string.match(priem,"(%d)(%d%d)(%d%d)") end return otpravka end --================================================================================================
Владимир написал: Айдар, Функции обратного вызова не имеют ни малейшего отношения к способу хранения данных - это просто прерывания. И немного найдётся способов затормозить терминал, чем использование OnAllTrade. ::
Не совсем правильно вопрос задал) А как сделать так, чтобы в моей пользовательской таблице были следующие данные, которые будут обновлятся на каждом тике: 1) сделки; 2) таблица данных из стакана котировок. И при этом чтобы в рабочем окне не было открыто ни графика, ни стакана, ни таблицы сделок?
Добрый день. Иногда на форуме встречается рекомендация не использовать стандартные таблицы QUICK потому, что они тормозят терминал, и вместо этого использовать пользовательские. Но как реализовать потом функцию обратного вызова, к примеру, как в OnAllTrade()?
Anton написал: Для простоты посмотрим на четырехбитные числа. Пусть есть сборник флагов flags = 0b0010 и нам надо проверить, установлен ли бит с индексом 1 (второй бит то есть). Мы берем единицу 0b0001, сдвигаем влево до позиции интересующего бита (в примере на 1 бит, получаем 0b0010) и выполняем побитовую операцию AND с флагами: 0b0010 AND 0b0010 = 0b0010, результат не равен нулю, то есть TRUE. А если бит 1 не установлен, а установлен другой какой-то, пусть нулевой, т.е. flags = 0b0001, наша операция даст 0b0001 AND 0b0010 = 0b0000, результат равен нулю, то есть FALSE. А при проверке нулевого бита код тот же, просто сдвиг на 0 позиций делает ничего .
Из функции OnTrade() я хочу узнать, активна ли заявка, для этого использую эту пользовательскую функцию: if bit_set(TABLE_trade.flags, 0)==true then --то есть, если в бите 0 флаг установлен, значит заявка активна end
Теперь вопрос к этой функции. function bit_set(flags,index) local n=1 --Вопрос 1. Не могу догнать, зачем тут сдвигают бит влево (что это дает)? n=bit.lshift(1,index) if bit.band(flags,n)~=0 then return true else return false end end
Артем написал: Sleep передаёт управление процессором обратно операционной системе, с указанием вернуть управление программе не менее чем через указанный период. Операционная система ставит процессор в режим простоя когда он ничем не используется.
Теперь приблизительно понятно, вопрос был конечно же в контексте функции Main(), думал, что в самой функцииSleep() тоже выполняются какие-нибудь специальные расчеты для "торможения" времени. Значит толк от нее есть
Эффективно ли применять фунцкию Sleep() для понижения нагрузки процессора? Или, к примеру, если написать код, время которого будет равно времени Sleep() - ресурс процессора будет затрачен одинаково?
Айдар написал: Возможно при помощи скрипта добавить/удалить индикатор на график? Вообще сама цель - перерисовать линии которые уже были изначально нанесены на график. Функция SetValue в данном случае не помогает - то что было нанесено ранее до выполнения этой функции - не перерисовывается. Нужны такие же действия, как добавить индикатор, изменить параметры индикатора, изменить время графика и т.д. Можете как-нибудь помочь?
то есть меня интересует, как при помощи скрипта обновить индикатор, к примеру каждый час
Возможно при помощи скрипта добавить/удалить индикатор на график? Вообще сама цель - перерисовать линии которые уже были изначально нанесены на график. Функция SetValue в данном случае не помогает - то что было нанесено ранее до выполнения этой функции - не перерисовывается. Нужны такие же действия, как добавить индикатор, изменить параметры индикатора, изменить время графика и т.д. Можете как-нибудь помочь?
Добрый день. Создаю индикатор, он рисует линию только тогда, когда в заданном периоде (Period) есть определенное число совпадений (Sovpadeniya) Hi или Low свеч. Вопрос. Как чертить линии не от начала периода и до конца графика, а только в промежутке, от первого совпадения до Sovpadeniya. Думаю вопрос понятен. Прилагаю код и скриншот. Подозреваю, что нужно как то создать массив в массиве, но не могу до этого додуматься. Settings = { Name = "*Sovpadeniya_cen_po_Hi_i_Low", Sovpadeniya = 3, Period = 150 }
function Init() --объявляем нужные переменные arr1={} schetchik_1=0 skolko_lin=0 --эта переменная нужна для: 1) подсчета линий (передачи их в функцию Init); 2) определения количества элементов в массиве
--вызываем функцию - один раз перед загрузкой OSN_1() if skolko_lin>0 then --если совпадений не будет, то вернуть 1 линию, а то вернет 0 и выскочит ошибка return skolko_lin else return 1 end end
function OSN_1() n_bars = getNumCandles('SBER_5_MINUT') moy_grafik, NUMBER, STRING = getCandlesByIndex ('SBER_5_MINUT', 0, 0, n_bars) --[[все, нужный график определили, теперь ищем количество нужных совпадений, если они найдутся - запоминаем их цену в массив. Ищем не во всем графике, а на определенном периоде, указанном в Settings:]]
for i = (n_bars-Settings.Period), n_bars-Settings.Sovpadeniya-1 do schetchik_1=0 --каждый раз обнуляем счетчик for n = (i+1), (n_bars-1) do if moy_grafik[i].high == moy_grafik[n].high or moy_grafik[i].high == moy_grafik[n].low then schetchik_1=schetchik_1+1 -- если есть совпадения - то считаем их количество end --[[если нашли количество нужных совпадений набралось - запоминаем значение цены в массив и выходим из цикла, дальше нет смысла искать:]] if schetchik_1 == Settings.Sovpadeniya then skolko_lin = skolko_lin + 1 arr1[skolko_lin]=moy_grafik[i].high break end end end end
function OnCalculate(index) if index-1 < (Size()-(Settings.Period)-1) then return nil else return unpack(arr1) end end
Айдар написал: return ---как правильно прописать весь массив? return arr1[1] это понятно, возвращается 1 элемент массива. А как прописать, что бы возвращалось 5 элементов массива?
Помогите разобраться с кодом. Settings = { Name = "*Primer123", }
function Init() Settings.line = {} for i = 1, 5 do Settings.line[i] = {} Settings.line[i] = { Color = RGB(20, 255, 20), Type = TYPE_LINE, Width = 1 } end return 5 --'это означает, что в графике всего будет 5 линий end
--объявляем массив для возврата значений линии arr1={} for i = 1, 5 do arr1[i]=i+185 end
function OnCalculate(index) return ---как правильно прописать весь массив? return arr1[1] это понятно, возвращается 1 элемент массива. А как прописать, что бы возвращалось 5 элементов массива? ---можно конечно вот так return arr1[1],arr1[2],arr1[3],arr1[4],arr1[5] - но если в массиве элементов будет 1000? ---просто return arr1 - не работает end