[CMD] Weighted Slot Spread - Price and Amount

stable
By Strooth in Miscellaneous Published June 2021 👁 1,228 views 💬 0 comments

Description

Weighted amount adjusted over spread, increasing, decreasing or flat. Additional Option to use ATR instead of percent input. Returns an array to use in for each slot/order spreads - keys - price and amount.

--- example
isLong = true --- above/below calc 
slotSize = 10--- the total slot size to be distributed 
slotCount = 15-- the number of slots 
price = CurrentPrice().bid --- The price to start from
dist = 1 ---  -1 Decreating, 0 Flat, 1 Increasing 
slotSpread = 0.2
atrspr = false
slotCancel  = 0.7

 local weights = CC_WeightedSpread(isLong, slotSize, slotCount, price, dist, slotSpread, atrspr) 
          for i = 1, slotCount do
                  slot(true, i, weights.amount[i], weights.price[i], slotCancel) 
          end

Log(weights.price) 
Log(weights.amount)

41. 10 Jun 2021 18:31:30 [0.295, 0.339, 0.430, 0.439, 0.556, 0.556, 0.562, 0.566, 0.576, 0.619, 0.619, 0.621, 0.670, 0.678, 0.769, 0.774, 0.843, 0.846, 0.855, 0.919, 0.960, 0.967, 0.987, 0.988, 1.0, 1.001, 1.095, 1.096, 1.101, 1.127, 1.136, 1.240, 1.290, 1.336]40. 10 Jun 2021 18:31:30 [59.667426, 59.548, 59.429, 59.309, 59.190, 59.071, 58.951, 58.832, 58.713, 58.593, 58.474, 58.355, 58.235, 58.116, 57.997, 57.877, 57.758, 57.639, 57.519, 57.400, 57.281, 57.161, 57.042, 56.923, 56.803, 56.684, 56.565, 56.445, 56.326, 56.207, 56.087, 55.968, 55.849, 55.610041032] ****Note the lines plotting the spread in the image are not part of this command
HaasScript
-- Author: -- Discord:  @strooth#4739
DefineCommand('WeightedSpread', 'Weighted Spread of price and amount')
local od = {DECREASING=-1, INCREASING=1, FLAT=0}
DefineIntervalOptimization(CurrentInterval())
local ws_param = {
isLong = DefineParameter(BooleanType, 'isLong', 'isLong', false, true, ''),
amount = DefineParameter(NumberType, 'amount', 'amount', false, TradeAmount(), ''),
orderCount = DefineParameter(NumberType, 'orderCount', 'orderCount', false, 20, ''),
priceLimit = DefineParameter(NumberType, 'priceLimit', 'priceLimit', false, CurrentPrice().bid, ''),
distribution = DefineParameter(DynamicType, 'distribution', 'distribution', false, 1, "'DECREASING=-1', 'INCREASING=1', 'FLAT=0'"),
minPercentage = DefineParameter(NumberType, 'spread', 'The spread percentage per slot', false, 2, ''),
useATR = DefineParameter(BooleanType, 'useATR', 'use atr to calculate the spread', false, false, ''),
atrint = DefineParameter(NumberType, 'ATR_interval', 'The interval for ATR. Default 1 day', false, 1440, ''),
atrper = DefineParameter(NumberType, 'ATR_period', 'The period for ATR. Default 14.', false, 14, ''),
}
local isLong = ws_param.isLong
local amount = ws_param.amount
local orderCount = ws_param.orderCount
local priceLimit = ws_param.priceLimit
local distribution = ws_param.distribution
local minPercentage = ws_param.minPercentage
local useATR = ws_param.useATR
local atrint = ws_param.atrint
local atrper = ws_param.atrper

local reversea = IfElseIf(distribution==od.DECREASING, distribution==od.INCREASING, true, false, false)
local rnd = #StringSplit(PriceStep(), '.')[2]

local atrspr = function(orderlimit, period, int, isLong)
  return OptimizedForInterval(int, function()
    local high = HighPrices(int, true, PriceMarket(), false)
    local low = LowPrices(int, true, PriceMarket(), false)
    local close = ClosePrices(int, true, PriceMarket(), false)
    local atr = ATR(high, low, close, period)
    return IfElse(isLong, GetSwing(CurrentPrice().bid, GetLow(low, period)-atr), GetSwing(GetHigh(high, period)+atr, CurrentPrice().ask))
    end )
end


local getAmountDistribution = function(distribution, orderCount, minPercentage, maxPercentage)
local pricePointPercentages  = HNC()
if distribution != (od.FLAT) then 
    for i=1, orderCount do 
        pricePointPercentages = ArrayUnshift(pricePointPercentages, minPercentage + (i * (maxPercentage - minPercentage)) / (orderCount + 1))
    end
    return pricePointPercentages
else 
   return HNC(orderCount+1, 100/orderCount)
end
end

local distributeAmount = function(total, weights) 
  local leftover = 0
  local distributedTotal = HNC()
  local distributionSum = ArraySum(weights)

  for weight in weights do 
    local val = (weight * total) / distributionSum + leftover

    local weightedValue = Round(val, rnd)
    leftover = val % 1
    distributedTotal = ArrayUnshift(distributedTotal, weightedValue)
  end
    ArrayReplace(distributedTotal, Max(distributedTotal), Round(Add(Max(distributedTotal), leftover), rnd))

  return distributedTotal

end

local generateOrders = function(amount, orderCount, priceLower, priceUpper, distribution, minPercentage, maxPercentage, isLong, reva)
local weights = getAmountDistribution(distribution, orderCount, minPercentage, maxPercentage)
local orderSizes = distributeAmount(amount, weights)
local stepsPerPricePoint = Div(Max(priceUpper, priceLower)-Min(priceUpper, priceLower), orderCount)
local orderPrices = HNC()
for i=1, orderCount do 
    if i==1 then 
      orderPrices = ArrayUnshift(orderPrices, priceLower)
    elseif i==orderCount then 
      orderPrices = ArrayUnshift(orderPrices, priceUpper)
    else 
      orderPrices = ArrayUnshift(orderPrices, Round(priceLower + stepsPerPricePoint * i, rnd))
    end 
end 
    return {price= ArraySort(orderPrices, isLong), amount=ArraySort(orderSizes, reva)}
end 

local maxPercentage = minPercentage*orderCount
if useATR then 
    maxPercentage = atrspr(orderCount, atrper, atrint, isLong) 
    minPercentage = maxPercentage / orderCount
end 
local priceUpper = IfElse(isLong, priceLimit, AddPerc(priceLimit, maxPercentage))
local priceLower = IfElse(isLong, SubPerc(priceLimit, maxPercentage), priceLimit)

DefineOutput(ListDynamicType, generateOrders(amount, orderCount, priceLower, priceUpper, distribution, minPercentage, maxPercentage, isLong, reversea), "{price=orderPrice, amount=orderSizes}")
DefineOutputIndex(1, ListNumberType, 'price', 'the prices array')
DefineOutputIndex(2, ListNumberType, 'amount', 'the amount array')

0 Comments

Sign in to leave a comment.

No comments yet. Be the first!