Smokybot MK2
stableDescription
-- This bot is optimized for HEDGE mode.
-- Suggested main interval is 15 minutes and 1 hour for momentum or ratio 1:4 or 1:6.
-- Using 1:1 time interval also works. Who knows might give your better profit.
-- Always start with ALL Trade Settings options UN-TICKED to let the bot preparing values.
-- Test with default values before changing anything to understand the bot.
-- PAY ATTENTION to the log warning if you feel something is off before screaming the bot is not working.
-- Do your own test. Testing is time consuming but also rewarding.
Short descriptions:
1. Net Balance = Trading balance entry + realized bot PNL + unrealized bot positions PNL
2. Stop at loss = Stop the bot when Net Balance at certain % loss value.
3. Stop at profit = Stop the bot when Net Balance at certain % profit value.
4. Derisking = Reducing the size of position. Kind of stop loss.
5. Trading Balance = Part of total wallet balance allocated for bot to trade.
There are 2 ways to use this bot.
1. Not using derisking feature.
For this you will never have a realized loss. Bot will keep counter trade while also trading the trend if you do HEDGE mode. You need large value in Balance Divider to hold the position from Balance Ratio reduction.
2. Using derisking feature.
Counter trade position will be reduce to the extend being closed depends on your Size Reduction setting and price movement. Bot will have realized loss.
TIPS:
Every trading pair needs different setting. Even if you find a good setting there is a chance that setting is not working in long term. This is why i put loss limit and profit limit.
Here is a tip if you are using derisking:
1. Have a profit limit in mind. For example 10%. Then you
2. Do 4 weeks backtest with profit limit 10% and derisking ON and find a setting that can achieve it in the shortest time.
Then run it. When bot reach the profit limit, it will stop. Clean the bot, then start again. Repeat.
With this you set aside the profit from each run. If you want to compound you can add some of it to Trading balance. In other word, manual compounding.
Hope this bot helps.
May the profits be with you!
HaasScript
Log('Tip wallet ERC20/BSC: 0xaa28dE4372CA0a8BC36722886E9749f70DF32382')
EnableHighSpeedUpdates(true)
HideOrderSettings()
HideTradeAmountSettings()
-- This bot is optimized for HEDGE mode.
-- Suggested main interval is 15 minutes and 1 hour for momentum or ratio 1:4 or 1:6.
-- Using 1:1 time interval also works. Who knows might give your better profit.
-- Always start with ALL Trade Settings options UN-TICKED to let the bot preparing values.
-- Test with default values before changing anything to understand the bot.
-- PAY ATTENTION to the log warning if you feel something is off before screaming the bot is not working.
-- Check Market
local getMarket = PriceMarket()
-- inputs
InputGroupHeader('Trade Settings')
local customInterval = InputInterval('00. Momentum Interval', 60, 'Interval for Squeeze Momentum')
local okLong = Input('01A. Long Entry', false, 'Allow bot to open Long')
local okProfitL = Input('01B. Long Exit', false, 'Allow bot to exit Long')
local okShort = Input('02A. Short Entry', false, 'Allow bot to open Short')
local okProfitS = Input('02B. Short Exit', false, 'Allow bot to exit Short')
local okReduce = Input('03. BalRatio Reduction', false, 'Allow Bal Ratio based size reduction')
local okDerisk = Input('04. Risk Reduction', false, 'Allow Signal based size reduction')
local oneWay = Input('05. Not Hedge', false, 'Select this if the market is NOT HEDGE mode')
local onlyWeekdays = Input('06. Only Weekdays', false, 'Bot will close any position and not trading during weekend')
InputGroupHeader('Bot Settings')
local wtfStop = Input('01. Stop at no position', false, 'Deactivate bot when there is no open position.')
local clearSlot = Input('02. Recalculate Slot Size', false, 'If activated will ALWAYS calculating slot size. If not activatated slot size will only calculated when there is no open position.')
local FEL = Input('03. Force Exit Long', false, 'Force exit LONG position')
local FES = Input('04. Force Exit Short', false, 'Force exit SHORT position')
local wtfLoss = Input('05. Stop at % LOSS', 0, 'Exit and cancel orders when Net Balance LOSS % below this. 0 is disalbe.')
local wtfProfit = Input('06. Stop at % PROFIT', 0, 'Stop and exit and cancel orders when Net Balance PROFIT % above this. 0 is disable.')
InputGroupHeader('Backtest Settings')
local wtfBal = Input('01. Deactivate on Over Budget', false, 'ONLY FOR BACKTEST. Disable bot when Bal. Ratio hit trigger')
InputGroupHeader('Custom Wallet')
local testWallet = Input('01. Activate Custom Wallet', false, 'Use custom wallet amount. A must in Haaslab')
local compound = Input('02. Add profit into balance', false, 'Add bot profit into custom wallet balance')
local testBal = Input('03. Custom Wallet Balance', 0, 'Amount of custom wallet')
InputGroupHeader('Budget')
local maxCostD = Input('01. Trading Balance ', 0, 'Maximum COST to limit working balance (margin cost + unrealised loss)')
local leverage = Input('02. Leverage', 50, 'MUST be filled and same as in exchange setting. Important for trading budget')
local contVal = Input('03. Inverse Contract Value', 10, 'ONLY if bot trading on INVERSE Futures then enter the Contract Value. Ignore if not')
InputGroupHeader('Safety')
local reduceTrigger = Input('01. Bal Ratio Trigger', 0.8, 'Ratio between working balance and trading balance to trigger size reduction')
local reduceSize = Input('02. Size Reduction %', 25, 'SHOULD BE factors of 100. In risk reduction: 1st reduction 25%, 2nd reduction 50% and so on. In balance ratio reduction: balRatio > Bal. Ratio Trigger then fixed 25% reduction')
local reduceOrderType = InputOrderType('03. Reduction Order Type', MakerOrCancelOrderType, 'The order type for size reduction')
local profitOut = Input('04. Profit Hodl %', 50, '% of the bot profit taken out or not compounded into trading balance calculation')
InputGroupHeader('Slot Settings')
local slotCount = Input('01. Slot Count', 1, 'How many orders are constantly kept open on both long and short side')
local slotSpreadD = Input('02. Slot Spread %', 3, '% based spread value between entry orders if Slot Count > 1')
local slotSizeD = Input('03. Slot Size ', 0, 'Minimum slot size if Dynamic Slot Size activated. Static amount if Dynamic Slot Size disabled.')
local autoSlot = Input('04A. Dynamic Slot Size', true, 'DSSize - Dynamically change slot size. Calculated IF there is no position or Recalculate Slot Size ticked.')
local slotBudget = Input('04B. Balance Divider', 100, 'DSSize - Trading Balance divider to calculate slot size')
local slotSizeM = Input('05. Slot Size Multiplier', 1, 'Multiplier for slot size value. Active at a certain condition w/wo DSS')
local priceDistance = Input('06. Price Distance %', 3, 'Minimum % price distance from filled order to the next. Also % unrealised loss for slot spread modifier if Slot Count > 1.')
InputGroupHeader('Profit Settings')
local minProfit = Input('01. Minimum Profit %', 0.5, 'Minimum price change % when price movement counter trending position. ')
local targetProfit = Input('02. Target Profit %', 3, 'Minimum price change % when price movement trending position. ')
local tpOrderType = InputOrderType('02. TP Order Type', MakerOrCancelOrderType, 'The order type for take-profit')
---------------------
-- DATA
local cp = CurrentPrice()
local today = CurrentDay()
local mainInterval = CurrentInterval()
-- counters
local highestP = Load('highestP', 0)
local lowestP = Load('lowestP', 0)
local SRCounter = Load('SRCounter', 0)
-- Current Interval
local h, l, c, pivot = OptimizedForInterval(mainInterval, function()
local h = HighPrices(mainInterval)
local l = LowPrices(mainInterval)
local c = ClosePrices(mainInterval)
local pivot = (h + l + c) / 3
return h, l, c, pivot
end)
local fastOSCI = ArrayGet(RSI(pivot, 13), 1)
local slowOSCI = ArrayGet(RSI(pivot, 55), 1)
local mAVG = ArrayGet(EMA(pivot, 21), 1)
local atr = ArrayGet(ATR(h, l, c, 21), 1)
-- Custom Interval
local cCustom = ClosePrices(customInterval)
local sqz = CC_SQZMOM_LB_Ext(cCustom, 20, 2, 20, 1.5)
local sqz1 = ArrayGet(sqz, 1)
local sqz2 = ArrayGet(sqz, 2)
local osciUP = fastOSCI > slowOSCI
local osciTOP = fastOSCI / slowOSCI > 1.236
local osciDOWN = slowOSCI > fastOSCI
local osciBTM = slowOSCI / fastOSCI > 1.236
local sqzUP = sqz1 > sqz2
local sqzDOWN = sqz1 < sqz2
---------------------
-- POSITIONS
local hedge_longPosId = Load('hedge_longPosId', NewGuid())
local hedge_shortPosId = Load('hedge_shortPosId', NewGuid())
local dir_l = GetPositionDirection(hedge_longPosId)
local aep_l = GetPositionEnterPrice(hedge_longPosId)
local pamt_l = GetPositionAmount(hedge_longPosId)
local delta_l = pamt_l > 0 and (cp.close - aep_l) / aep_l * 100 or 0
local proi_l = delta_l * leverage
local dir_s = GetPositionDirection(hedge_shortPosId)
local aep_s = GetPositionEnterPrice(hedge_shortPosId)
local pamt_s = GetPositionAmount(hedge_shortPosId)
local delta_s = pamt_s > 0 and (aep_s - cp.close) / aep_s * 100 or 0
local proi_s = delta_s * leverage
-- manage position ids
if pamt_l == 0 and IsPositionClosed(hedge_longPosId) then
if IsAnyOrderOpen(hedge_longPosId) then
CancelAllOrders(hedge_longPosId)
else
hedge_longPosId = NewGuid()
dir_l = GetPositionDirection(hedge_longPosId)
aep_l = GetPositionEnterPrice(hedge_longPosId)
pamt_l = GetPositionAmount(hedge_longPosId)
proi_l = delta_l * leverage
end
end
if pamt_s == 0 and IsPositionClosed(hedge_shortPosId) then
if IsAnyOrderOpen(hedge_shortPosId) then
CancelAllOrders(hedge_shortPosId)
else
hedge_shortPosId = NewGuid()
dir_s = GetPositionDirection(hedge_shortPosId)
aep_s = GetPositionEnterPrice(hedge_shortPosId)
pamt_s = GetPositionAmount(hedge_shortPosId)
proi_s = delta_s * leverage
end
end
-- get pos id
local getPositionId = function(isLong)
return isLong and hedge_longPosId or hedge_shortPosId
end
---------------------
-- WALLET CHECK
local profitLabel = ProfitLabel()
if profitLabel == nil then profitLabel = QuoteCurrency() end
-- inverse or not
if profitLabel == 'USD' or profitLabel == 'USDT' or profitLabel == 'BUSD' then
isInverse = false
else
isInverse = true
end
-- check balance usage
if pamt_l > 0 then
usedLong = isInverse and ((pamt_l * contVal) / leverage) / cp.close or (pamt_l * aep_l) / leverage
getProfitL = isInverse and (cp.close - aep_l) * (leverage * usedLong) / cp.close or (cp.close - aep_l) * pamt_l
else
getProfitL = 0
usedLong = 0
end
if pamt_s > 0 then
usedShort = isInverse and ((pamt_s * contVal) / leverage) / cp.close or (pamt_s * aep_s) / leverage
getProfitS = isInverse and (aep_s - cp.close) * (leverage * usedShort) / cp.close or (aep_s - cp.close) * pamt_s
else
getProfitS = 0
usedShort = 0
end
local getProfit = getProfitL + getProfitS
local botProfit = GetBotProfit()
-- balance warning
local xchangeBal = testWallet and testBal or WalletAmount(AccountGuid(), profitLabel)
local walletBal = compound and (xchangeBal + botProfit) or xchangeBal
local workBal = usedLong + usedShort - getProfit
local botBalance = maxCostD + botProfit
local balRatio = maxCostD > 0 and workBal / botBalance or 0
local netBalance = maxCostD + botProfit + getProfit
if balRatio > 0.5 and balRatio < 0.8 then LogWarning('Working balance is > 50% of Budget!!!') end
if balRatio > 0.8 then LogWarning('Working balance is > 80% of Budget!!!') end
local BRCounter = Load('BRCounter', 0)
if balRatio > BRCounter then Save('BRCounter', balRatio) end
---------------------
-- WTF
if onlyWeekdays then
if today == 1 or today == 7 then
FEL = true
FES = true
Log('Not trading on weekend')
end
Log('Bot will not trading on weekend', Yellow)
end
if wtfBal then
if balRatio > reduceTrigger then
DeactivateBot('Deactivated because over budget', true)
end
Log('STOP at over budget safety activated. Is this a backtest ?', Yellow)
end
if wtfLoss > 0 then
local lossLimit = SubPerc(maxCostD, wtfLoss)
if netBalance <= lossLimit then
wtfStop = true
FEL = true
FES = true
LogWarning('Loss < Limit. Stopping soon.')
end
Log('Loss limit activated at '..wtfLoss..'% or Net Balance '..lossLimit..' '..profitLabel, DarkGreen)
end
if wtfProfit > 0 then
local profitLimit = AddPerc(maxCostD, wtfProfit)
if netBalance >= profitLimit then
wtfStop = true
FEL = true
FES = true
LogWarning('Profit > Limit. Stopping soon.')
end
Log('Profit limit activated at '..wtfProfit..'% or Net Balance '..profitLimit..' '..profitLabel, DarkGreen)
end
if wtfStop then
local longNull = pamt_l == 0
local shortNull = pamt_s == 0
if longNull and shortNull then
DeactivateBot('Deactivated by No Position', true)
else
LogWarning('Will deactivate on No Position, waiting...maybe next second, maybe never :)')
end
Log('Deactivate on No Position is active.', Yellow)
end
if FEL then
okLong = false
okProfitL = false
Log('FORCE EXIT LONG POSITION ACTIVATED', Red)
end
if FES then
okShort = false
okProfitS = false
Log('FORCE EXIT SHORT POSITION ACTIVATED', Red)
end
---------------------
-- DYNAMICS
local LLP = LastLongPrice()
local longDeriskM = IfElse(Load('longDerisk', 1) > 100 / reduceSize, 100 / reduceSize, Load('longDerisk', 1))
local LSP = LastShortPrice()
local shortDeriskM = IfElse(Load('shortDerisk', 1) > 100 / reduceSize, 100 / reduceSize, Load('shortDerisk', 1))
-- entry exit price
local longPrice = c - ((h - c) * 0.275)
local shortPrice = c + ((h - c) * 0.275)
local exitPriceL = c + ((h - c) * 0.275)
local exitPriceS = c - ((h - c) * 0.275)
--Log('Last Price Long: '..LLP..' | Short: '..LSP)
--Log('Exit Price -> Long: '..exitPriceL..' | Short: '..exitPriceS)
--Log('Enter Price -> Long: '..longPrice..' | Short: '..shortPrice)
-- trading balance
local maxCost = botProfit > 0
and botBalance - (SubPerc(botProfit, profitOut))
or botBalance
local okBalance = walletBal >= maxCost
-- slot size
if autoSlot then
local costCalc = maxCost / slotBudget
if pamt_l == 0 or clearSlot then
local slotSize = isInverse and costCalc * 0.5 * longPrice * leverage / contVal or costCalc * leverage / longPrice
slotSizeL = slotSize > slotSizeD and slotSize or slotSizeD
Save('slotSizeL', slotSizeL)
else
slotSizeL = Load('slotSizeL', 0)
end
if pamt_s == 0 or clearSlot then
local slotSize = isInverse and costCalc * shortPrice* leverage / contVal or costCalc * leverage / shortPrice
slotSizeS = slotSize > slotSizeD and slotSize or slotSizeD
Save('slotSizeS', slotSizeS)
else
slotSizeS = Load('slotSizeS', 0)
end
else
slotSizeL = slotSizeD
slotSizeS = slotSizeD
end
-- slot size modifier
if fastOSCI < 50 and slowOSCI < 50 then
slotSizeL = slotSizeL * slotSizeM
else
slotSizeL = slotSizeL
end
if fastOSCI > 50 and slowOSCI > 50 then
slotSizeS = slotSizeS * slotSizeM
else
slotSizeS = slotSizeS
end
-- TP % modifier
if osciUP and sqzUP then
TPL = targetProfit
else
TPL = minProfit
end
if osciDOWN and sqzDOWN then
TPS = targetProfit
else
TPS = minProfit
end
--Log('Slot Size -> Long: '..slotSizeL..' | Short: '..slotSizeS)
-- spread
if slotCount > 1 then
-- long spread
if delta_l < (-priceDistance) then
slotSpreadL = slotSpreadD * 2
else
slotSpreadL = slotSpreadD
end
--short spread
if delta_s < (-priceDistance) then
slotSpreadS = slotSpreadD * 2
else
slotSpreadS = slotSpreadD
end
--Log('Slot Spread Long: '..Round(slotSpreadL, 2)..'% | Short: '..Round(slotSpreadS, 2)..'%')
else
slotSpreadL = slotSpreadD
slotSpreadS = slotSpreadD
end
---------------------
-- EXECUTION
--LONG
local mustLong = okLong
and okBalance
and sqzUP
and osciUP
and IfElse(oneWay, pamt_s == 0, true)
local longOpen = mustLong
and cp.close > longPrice
and c > longPrice
local okLongDerisk = okDerisk
and pamt_l > 0
and sqzDOWN
local longExit = okProfitL
and pamt_l > 0
and exitPriceL >= AddPerc(aep_l, TPL)
and exitPriceL >= aep_l + atr
and cp.close < exitPriceL
--SHORT
local mustShort = okShort
and okBalance
and sqzDOWN
and osciDOWN
and IfElse(oneWay, pamt_l == 0, true)
local shortOpen = mustShort
and cp.close < shortPrice
and c < shortPrice
local okShortDerisk = okDerisk
and pamt_s > 0
and sqzUP
local shortExit = okProfitS
and pamt_s > 0
and exitPriceS <= SubPerc(aep_s, TPS)
and exitPriceS <= aep_s - atr
and cp.close > exitPriceS
---------------------
-- CORE LOGIC HEDGE MODE
-- ENTRY
local slot = function(isLong, index, amount, spread, canPlace)
local prefix = isLong and 'L' or 'S'
local name = prefix .. index
local cmd = isLong and PlaceGoLongOrder or PlaceGoShortOrder
local price = isLong
and longPrice
or shortPrice
local spr = spread * (index - 1)
local posId = getPositionId(isLong)
local aep = isLong and aep_l or aep_s
local TOPB = TradeOncePerBar(mainInterval, posId)
-- get price
if aep > 0 then
if isLong and longPrice >= SubPerc(LLP, priceDistance) then
canPlace = false
end
if not isLong and shortPrice <= AddPerc(LSP, priceDistance) then
canPlace = false
end
end
if index != 1 then
price = isLong
and SubPerc(price, spr)
or AddPerc(price, spr)
end
local oid = Load(name..'oid', '') -- order id
if oid != '' then
local order = OrderContainer(oid)
if order.isOpen then
if not canPlace then
CancelOrder(oid)
LogWarning('Not allowed right now '..name)
end
else
oid = ''
end
else
if canPlace and TOPB then
SetFee(MakersFee())
oid = cmd(price, amount, {type = MakerOrCancelOrderType, note = name, timeout = mainInterval * 60, positionId = posId})
end
end
Save(name..'oid', oid)
end
-- variables
for i = 1, slotCount do
slot(true, i, slotSizeL, slotSpreadL, longOpen) -- long slot
end
for i = 1, slotCount do
slot(false, i, slotSizeS, slotSpreadS, shortOpen) -- short slot
end
-- EXIT
local updateTakeProfit = function(isLong, currentSize, canExit)
local prefix = isLong and 'Long' or 'Short'
local name = prefix .. ' Exit'
local oid = Load(prefix .. 'tp_oid', '')
local posId = getPositionId(isLong)
if oid != '' then
local order = OrderContainer(oid)
if order.isOpen then
if not canExit then
CancelOrder(oid)
LogWarning('Exit cancelled '..name)
end
else
oid = ''
end
else
if isLong and canExit then
SetFee(tpOrderType == MarketOrderType and TakersFee() or MakersFee())
oid = PlaceExitPositionOrder({price = exitPriceL, type = tpOrderType, note = name, timeout = mainInterval * 60, positionId = hedge_longPosId})
end
if not isLong and canExit then
SetFee(tpOrderType == MarketOrderType and TakersFee() or MakersFee())
oid = PlaceExitPositionOrder({price = exitPriceS, type = tpOrderType, note = name, timeout = mainInterval * 60, positionId = hedge_shortPosId})
end
end
Save(prefix .. 'tp_oid', oid)
end
-- variables
updateTakeProfit(true, pamt_l, longExit or FEL)
updateTakeProfit(false, pamt_s, shortExit or FES)
-- Balance Ratio REDUCTION
local updatePositionManagement = function(isLong, currentSize, sizeLimit, canReduce)
local prefix = isLong and 'Long' or 'Short'
local name = prefix .. ' Size Reduction'
local oid = Load(prefix .. 'pos_oid', '')
local posId = getPositionId(isLong)
local amount = SubPerc(currentSize, 100 - reduceSize) -- take X% of position
local price = isLong
and cp.ask
or cp.bid
local cmd = isLong
and PlaceExitLongOrder
or PlaceExitShortOrder
local timer = Load(prefix .. 'pos_timer', Time())
if oid != '' then
local order = OrderContainer(oid)
if order.isOpen then
if not canReduce then
CancelOrder(oid)
LogWarning('Reduction cancelled '..name)
end
else
sizeRed = 1
Save('SRCounter', SRCounter + sizeRed)
oid = ''
end
else
if canReduce and Time() >= timer then
CancelAllOrders()
SetFee(reduceOrderType == MarketOrderType and TakersFee() or MakersFee())
oid = cmd(price, amount, {type = reduceOrderType, note = name, timeout = 6000, positionId = posId})
timer = Time() + 60 -- 1min
end
end
Save(prefix .. 'pos_oid', oid)
Save(prefix .. 'pos_timer', timer)
end
-- variables
updatePositionManagement(true, pamt_l, maxCost, okReduce and pamt_l > 0 and balRatio > reduceTrigger and delta_l < delta_s)
updatePositionManagement(false, pamt_s, maxCost, okReduce and pamt_s > 0 and balRatio > reduceTrigger and delta_s < delta_l)
-- Derisking REDUCTION
local derisking = function(isLong, currentSize, reduceM, prevLP, canReduce)
local prefix = isLong and 'Long '..longDeriskM or 'Short '..shortDeriskM
local name = prefix .. ' Size Derisking'
local oid = Load(prefix .. 'derisk_oid', '')
local posId = getPositionId(isLong)
local amount = SubPerc(currentSize, 100 - (reduceM * reduceSize)) -- take X% of position
local price = isLong
and cp.ask
or cp.bid
local cmd = isLong
and PlaceExitLongOrder
or PlaceExitShortOrder
local TOPB = TradeOncePerBar(mainInterval, posId)
-- amount check
if amount < MinimumTradeAmount(getMarket, cp.close) then
canReduce = false
end
if oid != '' then
local order = OrderContainer(oid)
if order.isOpen then
if not canReduce then
CancelOrder(oid)
LogWarning('Reduction cancelled '..name)
end
else
if isLong then
Save('longDerisk', longDeriskM + 1)
else
Save('shortDerisk', shortDeriskM + 1)
end
oid = ''
end
else
if canReduce and TOPB then
CancelAllOrders()
SetFee(reduceOrderType == MarketOrderType and TakersFee() or MakersFee())
if isLong then
oid = cmd(price, amount, {type = reduceOrderType, note = name, timeout = mainInterval * 60, positionId = hedge_longPosId})
elseif not isLong then
oid = cmd(price, amount, {type = reduceOrderType, note = name, timeout = mainInterval * 60, positionId = hedge_shortPosId})
end
end
end
if currentSize == 0 then
if isLong then
Save('longDerisk', 1)
else
Save('shortDerisk', 1)
end
end
Save(prefix .. 'derisk_oid', oid)
end
-- variables
derisking(true, pamt_l, longDeriskM, LLP, okLongDerisk)
derisking(false, pamt_s, shortDeriskM, LSP, okShortDerisk)
-- Positions Data
if pamt_l > 0 then
Log('LONG Data > ROI: '..Round(GetPositionROI(hedge_longPosId, exitPriceL), 2)..'% | Entry: '..aep_l..' | Exit: '..exitPriceL)
end
if pamt_s > 0 then
Log('SHORT Data > ROI: '..Round(GetPositionROI(hedge_shortPosId, exitPriceS), 2)..'% | Entry: '..aep_s..' | Exit: '..exitPriceS)
end
---------------------
-- DATA SAVING
Save('hedge_longPosId', hedge_longPosId)
Save('hedge_shortPosId', hedge_shortPosId)
if botProfit > highestP then
Save('highestP', botProfit)
elseif botProfit < lowestP then
Save('lowestP', botProfit)
end
---------------------
-- PLOT
-- AEP Plot
if aep_l > 0 then
local posId = getPositionId(true)
Plot(0, 'AvgEP Long', aep_l, {c=Teal, id=posId, w=2})
end
if aep_s > 0 then
local posId = getPositionId(false)
Plot(0, 'AvgEP Short', aep_s, {c=Purple, id=posId, w=2})
end
Plot(0, 'mAVG', mAVG, {c=White})
Plot(0, 'Long', SubPerc(mAVG, priceDistance), {c=DarkGray})
Plot(0, 'Short', AddPerc(mAVG, priceDistance), {c=DarkGray})
ChartSetOptions(1, 'Exposure')
local lineLong = IfElse(pamt_l > 0, pamt_l, 0)
local lineShort = IfElse(pamt_s > 0, -pamt_s, 0)
Plot(1, 'Longs', lineLong, {c=Green, s=Step})
Plot(1, 'Shorts', lineShort, {c=Red, s=Step})
ChartSetOptions(2, 'Balance Monitor')
Plot(2, 'Net Balance', netBalance, {c=Orange, s=Step})
Plot(2, 'Trading Balance', maxCost, {c=White, s=Step})
Plot(2, 'WorkBal', workBal, {c=Red, s=Step})
Plot(2, 'Bot Profit', botProfit, {c=DarkGreen, s=Step})
Plot(2, 'Bot Balance', botBalance, {c=Yellow, s=Step})
--Plot(2, 'Exchange Balance', walletBal, {c=Orange, s=Step})
ChartSetOptions(4, 'Oscillator')
Plot(4, 'Fast', fastOSCI, {c=White})
Plot(4, 'Slow', slowOSCI, {c=Red})
Plot(4, 'Mid', 50, {c=DarkGray})
ChartSetOptions(5, 'Squeeze Momentum')
PlotHistogram(Plot(5, 'SQZ', sqz, Green), Red)
Log('Size Reduction: '..SRCounter..' times')
---------------------
-- FINAL REPORT
Finalize(function()
CustomReport('Current Balance Ratio', Round(100 * balRatio, 2)..'%')
CustomReport('Highest Balance Ratio', Round(100 * BRCounter, 2)..'%')
CustomReport('Size Reduction', SRCounter..' times')
CustomReport('Final Wallet Balance', Round(walletBal, 5)..' '..profitLabel)
CustomReport('Highest Profit', Round(highestP, 5)..' '..profitLabel)
CustomReport('Lowest Profit', Round(lowestP, 5)..' '..profitLabel)
if testWallet then
local profitPercent = Round(PercentageChange(maxCostD, botBalance), 2)
CustomReport('Profit %: ', profitPercent..'%')
CustomReport('Profit to Highest Bal Ratio', Round(profitPercent / (100 * BRCounter), 2))
end
end)
---------------------
Log('Profit Monitor -> Current: '..Round(botProfit, 5)..' '..profitLabel..' | Highest: '..Round(highestP, 5)..' '..profitLabel..' | Lowest: '..Round(lowestP, 5)..' '..profitLabel)
Log('Balance Monitor -> Wallet: '..Round(walletBal, 5)..' '..profitLabel..' | Net: '..Round(netBalance, 5)..' '..profitLabel..' | Trading: '..Round(maxCost, 5)..' '..profitLabel..' | Working: '..Round(workBal, 5)..' '..profitLabel..' | Ratio: '..Round(balRatio, 3))
-- BALANCE WARNING
if not okBalance then
LogWarning('TRADING BALANCE < EXCHANGE BALANCE')
end
if maxCostD == 0 then
LogWarning('Please enter trading balance')
end
--local VPM = CC_VPM3()
Log('SMOKYBOT MK2')
Log(' ')
3 Comments
Sign in to leave a comment.
Hi
"Then run it. When bot reach the profit limit, it will stop. Clean the bot, then start again. Repeat."
Is there any command to add make it clean and start and repeat again ?
Hello,
thank you for using my bot1
Yes the clean after profit should be automatic but it is not because unfortunately there is no command to clean the bot. I am already have something in mind as work around but still testing other things. I will add this into the next version.
Edit: solved