Перейти к содержимому

DESHLI

Пользователи
  • Публикации

    8
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные пользователем DESHLI


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


  2. Мне надо сделать из 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

     

     

     


     

     


  3. У меня есть два торговых робота: один "Судак", а другой "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

     

     


  4. У меня вот такая проблема.

    Я программировал торгового робота и на примере увидел вот такую функцию: return function(ind,  _p4,_ddd)
    И самое не понятное IND. Кто знает подскажите пожалуйста!

     

    Скрытый текст

    2020-06-16_18-56-39.png

     

×
×
  • Создать...