[CMD] Weighted Slot Spread - Price and Amount
stableDescription
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!