[pshaiBot] Simple Market Maker (SPOT MODE)

stable
By Firetron in Trading Bots Published November 2020 👁 2,700 views 💬 0 comments

Description

Simple Market Maker by pshai @ 2020 Introduction: This simple market maker makes the market! It doesn't stop, it has no limits (other than max. pos. size) and it's amazing. Get familiar with the bot before using it! I strongly suggest doing backtests and especially running it using a simulated account until you are confident that you know that this bot knows what it is doing! Also remember that backtests cannot represent the results you would see with a live bot; the difference is very...different. --== !NEW! Spot Version ==-- This version is for spot not leverage! *THINGS TO NOTE:* - This bot will not work well on: --> Bybit; bot is too intense for their API, dont trade there... --> Bitmex; API Incompatibilities ~~ May the profits be with you ~~ ~pshai Consider donating to support my work! BTC: 3FRx1EkG4T4izrkaS34xeZHJFK4kQefHKf
HaasScript
-- Simple Market Maker
-- by pshai @ 2020
--
-- Introduction:
-- This simple market maker makes the market!
-- It doesn't stop, it has no limits (other than max. pos. size)
-- and it's amazing. Get familiar with the bot before using it!
-- I strongly suggest doing backtests and especially running it
-- using a simulated account until you are confident that you know that
-- this bot knows what it is doing! Also remember that backtests cannot
-- represent the results you would see with a live bot; the difference
-- is very...different.
--
-- --== !NEW! Spot Version ==--
-- This version is for spot not leverage!
--
-- *THINGS TO NOTE:*
--  - This bot will not work well on:
--    --> Bybit; bot is too intense for their API, dont trade there...
--    --> Bitmex; API Incompatibilities
--  - BE VERY CAREFUL with fixed high leverage!
--
--
-- ~~ May the profits be with you ~~
-- ~pshai
--
--
-- Consider donating to support my work!
-- BTC: 3FRx1EkG4T4izrkaS34xeZHJFK4kQefHKf
-- --------------------------------------------------------------------------

EnableHighSpeedUpdates(true)
HideOrderSettings()
HideTradeAmountSettings()

-- inputs
local slotCount = Input('01. Slot Count', 5, 'How many orders are constantly kept open on both long and short side')
local slotSize = Input('02. Slot Size', 0.01, 'Trade amount per slot')
local slotSpread = Input('03. Slot Spread %', 0.1, 'Percentage based spread value between each slot')
local slotCancel = Input('04. Cancel Distance %', 0.1, 'How much price can move to the opposite direction before orders are cancelled and replaced')
local minSpread = Input('05. Minimum Spread %', 0.1, 'Minimum spread percentage between the first long and short entries. This setting only works when bot has no position.')
local maxSize = Input('06. Max. Size', 120, 'Maximum open contracts at any given time. After exceeding this value, the bot will dump a portion of position at a loss')
local reduceSize = Input('07. Size Reduction %', 25, 'How big of a portion the bot will dump once Max. Open Contracts is exceeded')
local reduceOrderType = InputOrderType('08. Reduction Order Type', MarketOrderType, 'The order type for size reduction dump')
local takeProfit = Input('09. Take-Profit %', 0.2, 'Fixed take-profit value, based on price change')
local tpOrderType = InputOrderType('10. TP Order Type', MakerOrCancelOrderType, 'The order type for take-profit')

--
minSpread = minSpread / 2.0

-- price and data
local cp = CurrentPrice()
local aep = GetPositionEnterPrice()
local pamt = GetPositionAmount()
local proi = GetPositionROI()

Log('position ROI: '..Round(proi, 4)..'%')

-- not using spread if we have a position
if pamt > 0 then
  minSpread = 0
end

-- slot function
local slot = function(index, amount, spread, cancelDist)
  local prefix = 'L'
  local name = prefix .. index
  local priceBase = cp.bid
  local spr = minSpread + spread * index

  -- if we have average entry price
  if aep > 0 then
    priceBase = Min(aep, priceBase)
  end

  -- get price
  local price = SubPerc(priceBase, spr)

  local oid = Load(name..'oid', '') -- order id

  if oid != '' then
    local order = OrderContainer(oid)

    if order.isOpen then
      local delta = Delta(AddPerc(order.price, spr), priceBase)

      if delta >= cancelDist then
        CancelOrder(oid)
        oid = '' -- reset id immediately, otherwise need 2 updates to get new order
        LogWarning('Delta cancelled '..name)
      end
    else
      oid = ''
    end
  else
      oid = PlaceBuyOrder(price, amount, {type = MakerOrCancelOrderType, note = name, timeout = 3600})
  end

  Save(name..'oid', oid)
end

-- update take-profit
local updateTakeProfit = function(currentSize, entryPrice, targetRoi, cancelDist)
  local name = 'Take-Profit'
  local oid = Load('tp_oid', '')
  local price = cp.ask
  local timer = Load('tp_timer', Time())
  local tp_delta = Delta(entryPrice, cp.bid)

  if oid != '' then
    local order = OrderContainer(oid)

    if order.isOpen then
      local delta = Delta(order.price, cp.close)

      if delta >= cancelDist then
        CancelOrder(oid)
        LogWarning('Delta cancelled '..name)
      end
    else
      oid = ''
    end
  else
    if tp_delta >= targetRoi and Time() >= timer then
      oid = PlaceSellOrder(price, currentSize, {type = tpOrderType, note = name, timeout = 3600})
      timer = Time() + 60 -- 1min
    end
  end

  Save('tp_oid', oid)
  Save('tp_timer', timer)
end


-- update position size
local updatePositionManagement = function(currentSize, sizeLimit, cancelDist)
  local name = 'Size Reduction'
  local oid = Load('pos_oid', '')
  local amount = SubPerc(currentSize, 100 - reduceSize) -- take X% of position
  local price = cp.ask
  local timer = Load('pos_timer', Time())

  if oid != '' then
    local order = OrderContainer(oid)

    if order.isOpen then
      local delta = Delta(order.price, cp.close)

      if delta >= cancelDist then
        CancelOrder(oid)
        LogWarning('Delta cancelled '..name)
      end
    else
      oid = ''
    end
  else
    if currentSize > sizeLimit and Time() >= timer then
      oid = PlaceSellOrder(price, amount, {type = reduceOrderType, note = name, timeout = 6000})
      timer = Time() + 60 -- 1min
    end
  end

  Save('pos_oid', oid)
  Save('pos_timer', timer)
end


-- da logica

-- take profit
updateTakeProfit(pamt, aep, takeProfit, slotCancel)

-- risk management
updatePositionManagement(pamt, maxSize, slotCancel)


-- update slots
for i = 1, slotCount do
  slot(i, slotSize, slotSpread, slotCancel) -- long slot
end

if aep > 0 then
  local posId = PositionContainer().positionId
  Plot(0, 'AvgEP', aep, {c=Purple, id=posId, w=2})
end

0 Comments

Sign in to leave a comment.

No comments yet. Be the first!