[EXPERIMENTAL] [pshaiProto] Keltner Grid Bot (KGB)

stable
By pshai in Trading Bots Published April 2020 👁 2,161 views 💬 0 comments

Description

EXPERIMENTAL prototype of yet another grid bot, utilizing Keltner Channels but this time, the orders are not place beforehand! Instead, bot checks the price against the KC upper and lower bands and places an order when these bands are breached. This bot runs shorts and longs simultaneously, but still has take-profit in-place, similarly as the FBI has. Main interval setting will work as the interval for all data this bot processes, so make sure you have set it up correctly as you wish. Bot has no input parameters, are all hard-coded in the script. Please feel free to fiddle with it and make improvements/expose settings. Happy profit-hunting! Disclaimer: USE AT YOUR OWN RISK. It is not advised to run this experimental prototype with live accounts!
HaasScript
-- [EXPERIMENTAL] prototype bot: Keltner Grid Bot (KGB)

EnableHighSpeedUpdates(true)

local take_profit_prc = 0.2

local h = HighPrices()
local l = LowPrices()
local c = ClosePrices()
local cp = CurrentPrice()

local pos_id_long = Load('poidl', NewGuid())
local pos_id_short = Load('poids', NewGuid())

local pos_long = PositionContainer(pos_id_long)
local pos_short = PositionContainer(pos_id_short)

local long_index = Load('lix', 1)
local short_index = Load('six', 1)

local slot_count = 10
local base_ma = MA(c, 20, EmaType)
local atr = ATR(h, l, c, 50)

function getSlotAmount(index)
    return 10
end

function updateSlot(index, is_long)
    if index > slot_count then
        return
    end

    local prefix = is_long and 'L' or 'S'
    local mem_id = prefix..index
    local atr2 = is_long and atr * -index or atr * index
    local trigger_price = base_ma + atr2
    local oid = Load(mem_id..'oid', '')
    local is_filled = Load(mem_id..'if', false)
    local amt = getSlotAmount(index)

    Plot(0, mem_id, trigger_price, {c=is_long and Green or Red, id = is_long and pos_id_long or pos_id_short})

    if is_long then
        if oid == '' and cp.close < trigger_price then
            oid = PlaceGoLongOrder(SubPerc(cp.bid, 0.01), amt, {type=MakerOrCancelOrderType, note=mem_id, positionId=pos_id_long, timeout=604800})
        elseif oid != '' and IsOrderOpen(oid) then
            CancelOrder(oid)
        end
    else
        if oid == '' and cp.close > trigger_price then
            oid = PlaceGoShortOrder(AddPerc(cp.ask, 0.01), amt, {type=MakerOrCancelOrderType, note=mem_id, positionId=pos_id_short, timeout=604800})
        elseif oid != '' and IsOrderOpen(oid) then
            CancelOrder(oid)
        end
    end

    if oid != '' and IsOrderOpen(oid) == false then
        if IsOrderFilled(oid) then
            is_filled = true
            
            if is_long then
                long_index = long_index + 1
            else
                short_index = short_index + 1
            end
        end

        oid = ''
    end

    Save(mem_id..'oid', oid)
    Save(mem_id..'if', is_filled)

end

function updatePosition(pos_id)
    local position = PositionContainer(pos_id)
    local price = position.isLong
        and AddPerc(position.enterPrice, take_profit_prc)
        or SubPerc(position.enterPrice, take_profit_prc)
    local prefix = position.isLong and 'LX' or 'SX'
    local oid = Load(prefix..'oid', '')
    local last_amt = Load(prefix..'la', position.amount)

    if not (position.isLong or position.isShort) then
        return pos_id
    end

    if position.amount != last_amt and oid != '' and IsOrderOpen(oid) then
        CancelOrder(oid)
        oid = ''
    elseif oid == '' then
        oid = PlaceExitPositionOrder({price=price, type=MakerOrCancelOrderType, note=prefix, positionId=pos_id, timeout=604800})
    else
        if IsOrderOpen(oid) == false then
            if IsOrderFilled(oid) then
                pos_id = NewGuid()
                
                if position.isLong then
                    long_index = 1
                elseif position.isShort then
                    short_index = 1
                end
            end

            oid = ''
        end
    end

    if oid != '' and IsOrderOpen(oid) then
        local order = OrderContainer(oid)
        Plot(0, prefix, order.price, {c=Purple(50), id=pos_id})
    end

    Save(prefix..'oid', oid)
    Save(prefix..'la', position.amount)

    return pos_id
end


updateSlot(long_index, true)
updateSlot(short_index, false)

pos_id_long = updatePosition(pos_id_long)
pos_id_short = updatePosition(pos_id_short)

Save('poidl', pos_id_long)
Save('poids', pos_id_short)
Save('lix', long_index)
Save('six', short_index)

0 Comments

Sign in to leave a comment.

No comments yet. Be the first!