DESHLI
-
Публикации
8 -
Зарегистрирован
-
Посещение
Сообщения, опубликованные пользователем DESHLI
-
-
-
Мне надо сделать из xsarATR.lua Торгового робота.
кто поможет пожалуйста, где там вывод покупки и продажи?
xsarATR.lua:
Скрытый текстSettings = { Name = "xSarATR", periodATR =21, ddd=3, line= { { Name = "xSarATR", Color = RGB(0, 192, 0), Type = TYPET_BAR, Width = 2 }, { Name = "xSarATR", Color = RGB(192, 0, 0), Type = TYPET_BAR, Width = 2 } , { Name = "xSarATR", Color = RGB(0, 0, 255), Type = TYPE_TRIANGLE_UP, Width = 3 } , { Name = "xSarATR", Color = RGB(255, 0, 0), Type = TYPE_TRIANGLE_DOWN, Width = 3 } } } function cached_SAR() local cache_H={} local cache_L={} local cache_SAR={} local cache_ST={} local AMA2={} local CC={} local CC_N={} local ATR={} return function(ind, _p4,_ddd) local index = ind local ZZZ = 0 if index == 1 then cache_H={} cache_L={} cache_SAR={} cache_ST={} AMA2={} CC={} CC_N={} ATR={} ------------------ CC[index]=C(index) CC_N[index]=(C(index)+H(index)+L(index))/3 cache_H[index]=H(index) cache_L[index]=L(index) cache_SAR[index]=L(index)-2*(H(index)-L(index)) AMA2[index]=(C(index)+O(index))/2 cache_ST[index]=1 ATR[index]=math.abs(H(index)-L(index)) return nil end ------------------------------ ZZZ=math.max(math.abs(H(index)-L(index)),math.abs(H(index)-C(index-1)),math.abs(L(index)-C(index-1))) ATR[index]=(ATR[index-1]*(_p4-1)+ZZZ)/_p4 cache_SAR[index]=cache_SAR[index-1] CC[index]=C(index) AMA2[index]=(2/(_p4/2+1))*CC[index]+(1-2/(_p4/2+1))*AMA2[index-1] CC_N[index]=(C(index)-AMA2[index])/2+AMA2[index] cache_ST[index]=cache_ST[index-1] cache_H[index]=cache_H[index-1] cache_L[index]=cache_L[index-1] --------------------------------------------------------------------------------------- if index ==2 then return nil end ---------------------------------------------------------------------- if cache_ST[index]==1 then if cache_H[index] < CC[index] then cache_H[index]=CC[index] end cache_SAR[index]=math.max((cache_H[index]-ATR[index]*_ddd),cache_SAR[index-1]) if (cache_SAR[index] > CC_N[index])and(cache_SAR[index] > C(index)) then cache_ST[index]=0 cache_L[index]=CC[index] cache_SAR[index]=cache_L[index]+ATR[index]*_ddd*1 return nil,cache_SAR[index], nil,cache_H[index]-ATR[index]*_ddd end return cache_SAR[index], nil, nil, nil end --------------------------------------------------------------------------------------- if cache_ST[index]==0 then if cache_L[index] > CC[index] then cache_L[index]=CC[index] end cache_SAR[index]=math.min((cache_L[index]+ATR[index]*_ddd),cache_SAR[index-1]) if (cache_SAR[index] < CC_N[index])and (cache_SAR[index] < C(index)) then cache_ST[index]=1 cache_H[index]=CC[index] cache_SAR[index]=cache_H[index]-ATR[index]*_ddd*1 return cache_SAR[index], nil, cache_L[index]+ATR[index]*_ddd,nil end return nil,cache_SAR[index], nil, nil end end end --------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------- function Init() mySAR = cached_SAR() return 4 end function OnCalculate(index) return mySAR(index, Settings.periodATR,Settings.ddd) end
-
Язык Lua
И один из них робот а другой код это индикатор, и то есть мне надо как-то сделать так, чтобы этот робот работал по индикаторе. То-есть Судак должен работпть по индикатору Xsar
-
У меня есть два торговых робота: один "Судак", а другой "Xsar"
Вот их код:
Судак:
Скрытый текст-- ************************ СЕКЦИЯ ОБЩИХ ПАРАМЕТРОВ **************************** CLIENT_CODE = "D62154" -- общий код для акций и фьючерсов. LogFileName = "c:\\SudakTudak\\short\\sudaktudak_log.txt" -- Технический лог. ParamPath = "c:\\SudakTudak\\short\\" -- здесь хранятся файлики с параметрами. Три файла на каждый инструкмент. SdelkaLog = "c:\\SudakTudak\\short\\sudaktudak_sdelki.txt" -- Лог сделок. Сюда пишутся ТОЛЬКО сделки. SleepDuration = 20; -- отдыхаем 10 секунд. Слишком часто не надо молотить. DemoMode = false -- Включите, чтобы начать "боевые" сделки. Если = false, сделок не будет, просто запишет в лог. -- ************************ СЕКЦИЯ МАССИВОВ ДЛЯ ИНСТРУМЕНТОВ ************************ aTickerList = {"MMM0"}; -- сюда массив инструментов. Не забывайте перекладывать фьючерсы!!! -- А при перекладывании фьючерсов не забывайте менять код как здесь, так и в следующих массивах. -- Следующие массивы должны иметь значения для каждого инструмента из aTickerList aClassCode = {MMM0="SPBFUT"} -- TQBR для акций, SPBFUT для фьючерсов. aAccountCode = {MMM0="SPBFUT00Q00"} -- может отличаться для акций и фьючерсов. aLotSize = {MMM0=1}; -- Массив лотов для покупки. aProskalzivanie = {MMM0=0.05}; -- Проскальзывание при сделке. maxVolume = -8; -- Сколько всего можем набрать aCurrentPrice = 0; aHour_1 = 10; -- Час начала работы aHour_2 = 23; -- Час конца работы aMinutes_1 = 00; -- Минуты начала работы fibo = 0.1; -- Множитель увеличения каждого уровня усреднения fiboStepSize = {MMM0=20}; -- Размер уровня для усреднения по каждому инструменту full_flat_size = false; -- false - торговля между средней и крайней линией ББ, true - между крайними линиями is_run=true function main() while is_run do curr_date=os.date("*t") if (curr_date["hour"]>=aHour_1 and curr_date["min"]>aMinutes_1) and curr_date["hour"]<aHour_2 then for k,v in pairs(aTickerList) do Obrabotka(v,k); end end; sleep(SleepDuration*1000) -- Отдыхаем SleepDuration секунд. end end function GetLastPrice(TickerName, CandleType) -- Берем цену из графика. CreateDataSource пока не используем, т.к. при необходимости модификации -- алгоритма, хотим легко добавлять индикаторы. -- Плюс меньше зависим от коннекта - графики всегда с нами. local NL=getNumCandles(TickerName.."_Price_Sudak") tL, nL, lL = getCandlesByIndex (TickerName.."_Price_Sudak", 0, NL-1, 1) -- last свеча if tL ~= nil then if tL[0] ~= nil then if CandleType=="LOW" then aCurrentPrice=tL[0].low -- получили текущую цену (ЦПС) elseif CandleType=="OPEN" then aCurrentPrice=tL[0].open elseif CandleType=="HIGH" then aCurrentPrice=tL[0].high else aCurrentPrice=tL[0].close end end; end; return aCurrentPrice end function GetXsar(TickerName, LineCode) -- получаем текущие значения Боллинлжера. -- LineCode может иметь значения: "High", "Middle", "Low" local NbbL=getNumCandles(TickerName.."_BB_Sudak") tbbL, nbbL, lbbL = getCandlesByIndex (TickerName.."_BB_Sudak", 0, NbbL-1, 1) -- last свеча, средняя линия Боллинджера iBB_Local_Middle = tbbL[0].close -- тек значение средней BB Local tbbL, nbbL, lbbL = getCandlesByIndex (TickerName.."_BB_Sudak", 1, NbbL-1, 1) -- last свеча, верхняя линия Боллинджера iBB_Local_High = tbbL[0].close -- тек значение верхней BB Local tbbL, nbbL, lbbL = getCandlesByIndex (TickerName.."_BB_Sudak", 2, NbbL-1, 1) -- last свеча, нижняя линия Боллинджера iBB_Local_Low = tbbL[0].close -- тек значение нижней BB Local if LineCode == "High" then return iBB_Local_High end if LineCode == "Middle" then return iBB_Local_Middle end if LineCode == "Low" then return iBB_Local_Low end end function PriceCrossMAToUp(TickerName) -- Функция возвращает TRUE, если пересекли среднюю линию Боллинджера снизу вверх if GetLastPrice(TickerName, "OPEN")<GetBollinger(TickerName, "Middle") and GetLastPrice(TickerName, "LAST")>GetBollinger(TickerName, "Middle") then return true else return false end; end function PriceCrossMAToDown(TickerName) -- Функция возвращает TRUE, если пересекли среднюю линию Боллинджера снизу вверх if GetLastPrice(TickerName, "OPEN")>GetBollinger(TickerName, "Middle") and GetLastPrice(TickerName, "LAST")<GetBollinger(TickerName, "Middle") then return true else return false end; end function PriceEnterToBollingerFromDown(TickerName) -- Функция возвращает TRUE, если пересекли нижнюю линию Боллинджера снизу вверх -- (то есть вошли внутрь канала Боллинджера снизу). if GetLastPrice(TickerName, "LOW")<GetBollinger(TickerName, "Low") and GetLastPrice(TickerName, "LAST")>GetBollinger(TickerName, "Low") then return true else return false end; end function PriceEnterToBollingerFromUp(TickerName) -- Функция возвращает TRUE, если пересекли верхнюю линию Боллинджера сверху вниз -- (то есть вошли внутрь канала Боллинджера сверху). if GetLastPrice(TickerName, "HIGH")>GetBollinger(TickerName, "High") and GetLastPrice(TickerName, "LAST")<GetBollinger(TickerName, "High") then return true else return false end; end --Функция Обработки отдельного тикера function Obrabotka(sTickerName, sNum) -- Теперь откываем файлы с нашим тикетом, и читаем оттуда значения: LastPrice, LastDirection, Объем Позы. LastPrice = tonumber(GetValueFromFile(ParamPath..sTickerName.."_LastPrice.txt")); LastDirection = GetValueFromFile(ParamPath..sTickerName.."_LastDirection.txt"); iVolume = tonumber(GetValueFromFile(ParamPath..sTickerName.."_Volume.txt")); local CurrentPrice=GetLastPrice(sTickerName) -- вытаскиваем из графика текущую цену. local profit = tonumber(GetValueFromFile(ParamPath..sTickerName.."_Profit.txt")); -- Логируем текущую и последнюю цены и разницу между ними. WLOG(sTickerName.. " Current="..CurrentPrice.. " Last="..LastPrice.." Razn = "..((CurrentPrice-LastPrice) - (CurrentPrice-LastPrice)%aProskalzivanie[sTickerName]).. " FlatBBSize = "..FiboSize(sTickerName).." Vol="..iVolume.." LastDir="..LastDirection.." FiboStepSize = "..FiboLevels(sTickerName).." Profit="..profit); -- Теперь проверяем, не надо ли докупиться или скинуть шорт if (((CurrentPrice<LastPrice-FiboSize(sTickerName) and LastDirection=="S") or (CurrentPrice<LastPrice-FiboLevels(sTickerName))) and iVolume<0) and PriceEnterToBollingerFromDown(sTickerName) then -- Покупаем или Начинаем if LastDirection=="S" then WLOG("BUY PROFIT "..(LastPrice-CurrentPrice)); SetValueToFile(ParamPath..sTickerName.."_Profit.txt", profit + LastPrice-CurrentPrice) -- начислили прибыль и записали. else WLOG("BUY PROFIT NEW LEVEL"..(LastPrice-CurrentPrice)); SetValueToFile(ParamPath..sTickerName.."_Profit.txt", profit + LastPrice-CurrentPrice) -- начислили прибыль и записали. end if (DoFire(sTickerName, "B", CurrentPrice) == "") then iVolume = tonumber(iVolume)+aLotSize[sTickerName]; SetValueToFile(ParamPath..sTickerName.."_LastPrice.txt", CurrentPrice) SetValueToFile(ParamPath..sTickerName.."_LastDirection.txt", "B") SetValueToFile(ParamPath..sTickerName.."_Volume.txt", tostring(iVolume)) LastPrice = CurrentPrice; -- чтобы не продать сразу на следующем условии. end end -- Теперь проверяем, не надо ли еще продать? Если поза нуль, то набираем в шорт if (((CurrentPrice>LastPrice+FiboLevels(sTickerName)) or (CurrentPrice>LastPrice+FiboSize(sTickerName) and LastDirection=="B")) or iVolume==0) and PriceEnterToBollingerFromUp(sTickerName) and iVolume>maxVolume then -- Продаем if LastDirection=="B" then WLOG("SELL AGAIN"); else WLOG("SELL NEW LEVEL"); end if (DoFire(sTickerName, "S", CurrentPrice) == "") then iVolume = tonumber(iVolume)-aLotSize[sTickerName]; SetValueToFile(ParamPath..sTickerName.."_LastPrice.txt", CurrentPrice) SetValueToFile(ParamPath..sTickerName.."_LastDirection.txt", "S") SetValueToFile(ParamPath..sTickerName.."_Volume.txt", tostring(iVolume)) end end end; function FiboLevels (sTickerName) -- Функция увеличения размера уровня в зависимости от позиции по тикеру local Volume = math.abs(iVolume / aLotSize[sTickerName]); local iniStepSize = fiboStepSize[sTickerName]; local newStepSize = iniStepSize + (iniStepSize * fibo)^Volume; return newStepSize; end; function FiboSize (sTickerName) -- Функция определение ширины между линиями Боллинжера local CurrentPrice=GetLastPrice(sTickerName, "OPEN") -- вытаскиваем из графика текущую цену. local Size=0 if full_flat_size then Size = math.floor (GetBollinger(sTickerName, "High") - GetBollinger(sTickerName, "Low")) return Size end if CurrentPrice >= GetBollinger(sTickerName, "Middle") and full_flat_size==false then Size = math.floor (GetBollinger(sTickerName, "High") - GetBollinger(sTickerName, "Middle")) return Size else Size = math.floor (GetBollinger(sTickerName, "Middle") - GetBollinger(sTickerName, "Low")) return Size end end; function DoFire(SEC_CODE, p_dir, p_price) -- Функция - СДЕЛКА ПО РЫНКУ! if p_dir == "B" then AAA = 1 else AAA = -1 end t = { ["CLASSCODE"]=aClassCode[SEC_CODE], ["SECCODE"]=SEC_CODE, ["ACTION"]="NEW_ORDER", -- новая сделка. ["ACCOUNT"]=aAccountCode[SEC_CODE], ["CLIENT_CODE"]=CLIENT_CODE, ["TYPE"]="L", -- "M" "L". По M давал ошибку на TQBR. ["OPERATION"]=p_dir, -- направление сделки, "B" или "S" ["QUANTITY"]=tostring(aLotSize[SEC_CODE]), -- объем, (акции - в лотах, а не штуках). ["PRICE"]=tostring(p_price+(aProskalzivanie[SEC_CODE]*AAA)), -- цену лимитки ставим для мгновенного исполнения. ["TRANS_ID"]="1" } if DemoMode==false then -- Если всё по серьезному, то ... res1 = sendTransaction(t) -- ... передаем сделку по рынку. end if (res1~="") then -- Ошибочка вышла. Логируем ошибку. WLOG("SendTransaction Error = "..res1); end local l_file1=io.open(SdelkaLog, "a") l_file1:write(os.date()..";SECCODE="..SEC_CODE..";PRICE="..p_price..";DIR="..p_dir.."\n") l_file1:close() return res1 end function GetValueFromFile(FileName) -- Читаем параметр из файла. local f = io.open(FileName, "r"); if f == nil then -- если файла нет, но создаем пустой. f = io.open(FileName,"w"); DefaultValueForFile = "0" -- по умолчанию пишем нуль. -- Для LastDirection надо бы писать не нуль, а "B", но пусть будет нуль, т.к. -- этого условия достаточно для открытия начальной сделки. f:write(DefaultValueForFile) f:close(); -- Открывает уже гарантированно существующий файл в режиме "чтения/записи" f = io.open(FileName, "r"); end; aValue = f:read("*l") f:close() return aValue end function SetValueToFile(FileName, aValue) -- Пишем параметр в файл. local ff=io.open(FileName, "w") -- используем "w", а не "a", чтобы перезаписать существующий. ff:write(aValue) ff:close() end function OnStop(stop_flag) is_run=false end function WLOG(st) -- Универсальная функция записи в лог. local l_file=io.open(LogFileName, "a") -- используем "a", чтобы добавить новую строку. l_file:write(os.date().." "..st.."\n") l_file:close() end
Xsar:
Скрытый текстSettings = { Name = "xSarATR", periodATR =21, ddd=3, line= { { Name = "xSarATR", Color = RGB(0, 192, 0), Type = TYPET_BAR, Width = 2 }, { Name = "xSarATR", Color = RGB(192, 0, 0), Type = TYPET_BAR, Width = 2 } , { Name = "xSarATR", Color = RGB(0, 0, 255), Type = TYPE_TRIANGLE_UP, Width = 3 } , { Name = "xSarATR", Color = RGB(255, 0, 0), Type = TYPE_TRIANGLE_DOWN, Width = 3 } } } --------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------- function cached_SAR() local cache_H={} local cache_L={} local cache_SAR={} local cache_ST={} local AMA2={} local CC={} local CC_N={} local ATR={} return function(ind, _p4,_ddd) local index = ind local ZZZ = 0 if index == 1 then cache_H={} cache_L={} cache_SAR={} cache_ST={} AMA2={} CC={} CC_N={} ATR={} ------------------ CC[index]=C(index) CC_N[index]=(C(index)+H(index)+L(index))/3 cache_H[index]=H(index) cache_L[index]=L(index) cache_SAR[index]=L(index)-2*(H(index)-L(index)) AMA2[index]=(C(index)+O(index))/2 cache_ST[index]=1 ATR[index]=math.abs(H(index)-L(index)) return nil end ------------------------------ ZZZ=math.max(math.abs(H(index)-L(index)),math.abs(H(index)-C(index-1)),math.abs(L(index)-C(index-1))) ATR[index]=(ATR[index-1]*(_p4-1)+ZZZ)/_p4 cache_SAR[index]=cache_SAR[index-1] CC[index]=C(index) AMA2[index]=(2/(_p4/2+1))*CC[index]+(1-2/(_p4/2+1))*AMA2[index-1] CC_N[index]=(C(index)-AMA2[index])/2+AMA2[index] cache_ST[index]=cache_ST[index-1] cache_H[index]=cache_H[index-1] cache_L[index]=cache_L[index-1] --------------------------------------------------------------------------------------- if index ==2 then return nil end ---------------------------------------------------------------------- if cache_ST[index]==1 then if cache_H[index] < CC[index] then cache_H[index]=CC[index] end cache_SAR[index]=math.max((cache_H[index]-ATR[index]*_ddd),cache_SAR[index-1]) if (cache_SAR[index] > CC_N[index])and(cache_SAR[index] > C(index)) then cache_ST[index]=0 cache_L[index]=CC[index] cache_SAR[index]=cache_L[index]+ATR[index]*_ddd*1 return nil,cache_SAR[index], nil,cache_H[index]-ATR[index]*_ddd end return cache_SAR[index], nil, nil, nil end --------------------------------------------------------------------------------------- if cache_ST[index]==0 then if cache_L[index] > CC[index] then cache_L[index]=CC[index] end cache_SAR[index]=math.min((cache_L[index]+ATR[index]*_ddd),cache_SAR[index-1]) if (cache_SAR[index] < CC_N[index])and (cache_SAR[index] < C(index)) then cache_ST[index]=1 cache_H[index]=CC[index] cache_SAR[index]=cache_H[index]-ATR[index]*_ddd*1 return cache_SAR[index], nil, cache_L[index]+ATR[index]*_ddd,nil end return nil,cache_SAR[index], nil, nil end end end --------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------- function Init() mySAR = cached_SAR() return 4 end function OnCalculate(index) return mySAR(index, Settings.periodATR,Settings.ddd) end
-


QUIK: Как сделать из индикатора торгового робота?
в Общие
Опубликовано:
@Zer0Galaxy Так ок, у меня сейчас достаточно времени и я могу всё подробно описать... И так , ЧТО ДЕЛАЕТ ЭТОТ ИНДИКАТОР: он рисует точки на графике по которым можно отследить общую тенденсыю (надеюсь правильно написал) и он работает примерно как BB (Bollinger Bance) но у него вместо линей точки, а вместо трёх линёй одно полос на которой он выставляет точки. Так вот он мжет менять направление точек т.е ставить их либо над графиком или под него, выыполняя определённые математические операции. Воооот так, ага, то есть теми такая: когда точки посались (или рисовались не важно) под графиком, а потом поменяли своё положение и начали рисоваться над графиком то мы открываемся, а если наоборот то... Наоборот!