Smokybot
stableDescription
Hi guys!
After years of learning and testing and coping with lockdown and other IRL stuff, here i am back with a new bot script for the community.
Smokybot is a trend following bot that using MA and Oscillators. It also has budget management just like my version of Phsai's SMM. It also has stop loss so relatively "safe" to leave it run forever...hopefully lol.
Hopefully the tool tips could explain what is what and what is for. If not, please find me in Haasonline DIscord and i would be grateful if the others could help explore and support other users.
Last but not least, thank you Phsai for teaching and guiding me in using Haasscript.
Little bit details
1. You need to have these installed https://www.haasscripts.com/t/pshaicmd-sqzmom-extended/ and https://www.haasscripts.com/t/haasbot-utilities-vpm3-create_adjust_close-virtual-position-management-for-running-haasbots/
2. Compatible with Hedge and One-Way market. If you are not trading in hedge market or in one-way market, tick Not Hedge
3. Trading Balance is in profit currency. USDT/BUSD in those market and crypto in Inverse.
4. Suggested time interval is 15 minutes.
5. Always start with ALL Trade Settings options UN-TICKED to let the bot preparing values.
6. Test with default values before changing anything to understand the bot. If the default value result is not satisfying, find the best one using HaasLab. 8 weeks backtest is highly recommended.
7. Because of the dynamic part of the slot size you need to use custom wallet amount in HaasLab.
8. PAY ATTENTION to the log warning if you feel something is off before screaming the bot is not working.
May the Profits be with you!
*Backtest was Bybit USDT Futures BIT/USDT 4 Weeks on Feb 2 22
Version:
2022.1.25
HaasScript
Log('Tip wallet ERC20/BSC: 0xaa28dE4372CA0a8BC36722886E9749f70DF32382')
EnableHighSpeedUpdates(true)
HideOrderSettings()
HideTradeAmountSettings()
-- Suggested time interval is 15 minutes.
-- 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 screeaming the bot is not working.
-- Check Market
local getMarket = PriceMarket()
-- inputs
InputGroupHeader('Trade Settings')
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, 'Selec this if the market is NOT HEDGE mode')
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.')
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 slotSizeD = Input('02. Slot Size ', 0, 'Minimum slot size if Dynamic Slot Size activated. Static amount if Dynamic Slot Size disabled.')
local autoSlot = Input('03A. Dynamic Slot Size', true, 'DSSize - Dynamically change slot size. Calculated IF there is no position or Recalculate Slot Size ticked.')
local slotBudget = Input('03B. Balance Divider', 50, 'DSSize - Trading Balance divider to calculate slot size')
local slotSizeM = Input('04. Slot Size Multiplier', 2, 'Multiplier for slot size value. Active at a certain condition w/wo DSS')
local slotSpreadD = Input('05. Slot Spread %', 0.5, '% based spread value between entry orders')
local priceDistance = Input('06. Price Distance %', 2, '% price movement for: modifying spread % if slot count > 1 and price movement range.')
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 %', 2, '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()
-- Current Interval
local mainInterval = CurrentInterval()
local h, l, c, pivot = OptimizedForInterval(0, function()
local h = HighPrices(0)
local l = LowPrices(0)
local c = ClosePrices(0)
local pivot = (h + l + c) / 3
return h, l, c, pivot
end)
local fastOSCI = RSI(c, 13)
local slowOSCI = RSI(c, 55)
local sqz = CC_SQZMOM_LB_Ext(c, 20, 2, 20, 1.5)
local sqz1 = ArrayGet(sqz, 2)
local mAVG = EMA(pivot, 21)
local atr = ATR(h, l, c, 21)
local osciUP = fastOSCI > slowOSCI
local osciTOP = fastOSCI / slowOSCI > 1.236
local osciDOWN = slowOSCI > fastOSCI
local osciBTM = slowOSCI / fastOSCI > 1.236
local sqzUP = sqz > sqz1
local sqzDOWN = sqz < sqz1
--Log('sqz '..sqz..' sqz1 '..sqz1)
-- 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
-- counters
local highestP = Load('highestP', 0)
local lowestP = Load('lowestP', 0)
local SRCounter = Load('SRCounter', 0)
-- 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
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
---------------------
-- DYNAMICS
local LLP = LastLongPrice()
local firstL = Load('firstL', 0)
local longDeriskM = Load('longDerisk', 1)
local LSP = LastShortPrice()
local firstS = Load('firstS', 0)
local shortDeriskM = Load('shortDerisk', 1)
--Log('firstL '..firstL..' firstS '..firstS)
-- entry exit price
local longPrice = c - ((h - c) * 0.275)
local shortPrice = c + ((h - c) * 0.275)
local exitPriceL = aep_l + (3 * atr)
local exitPriceS = aep_s - (3 * atr)
--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 - (botProfit * profitOut / 100)
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 * 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 multiplying
if osciUP and sqzUP then
slotSizeL = slotSizeL * slotSizeM
TPL = targetProfit
else
slotSizeL = slotSizeL
TPL = minProfit
end
if osciDOWN and sqzDOWN then
slotSizeS = slotSizeS * slotSizeM
TPS = targetProfit
else
slotSizeS = slotSizeS
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 cp.close > longPrice
and c > longPrice
and IfElse(oneWay, pamt_s == 0, true)
local longOpen = mustLong
and not osciTOP
and longPrice >= mAVG
and longPrice <= AddPerc(mAVG, priceDistance)
local okLongDerisk = okDerisk
and pamt_l > 0
and c < SubPerc(mAVG, priceDistance)
local longExit = okProfitL
and pamt_l > 0
and exitPriceL > AddPerc(aep_l, TPL)
and cp.close < exitPriceL
--SHORT
local mustShort = okShort
and okBalance
and cp.close < shortPrice
and c < shortPrice
and IfElse(oneWay, pamt_l == 0, true)
local shortOpen = mustShort
and not osciBTM
and shortPrice <= mAVG
and shortPrice >= SubPerc(mAVG, priceDistance)
local okShortDerisk = okDerisk
and pamt_s > 0
and c > AddPerc(mAVG, priceDistance)
local shortExit = okProfitS
and pamt_s > 0
and exitPriceS < SubPerc(aep_s, TPS)
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, slotSpreadL) then
canPlace = false
end
if not isLong and shortPrice <= AddPerc(LSP, slotSpreadS) 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
elseif order.isFilled then
if isLong and firstL == 0 then
Save('firstL', order.price)
elseif not isLong and firstS== 0 then
Save('firstS', order.price)
end
oid = ''
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 timer = Load(prefix .. 'tp_timer', 0)
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)
Save(prefix .. 'tp_timer', timer)
end
-- variables
updateTakeProfit(true, pamt_l, longExit and delta_l > minProfit)
updateTakeProfit(false, pamt_s, shortExit and delta_s > minProfit)
-- 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 pamt_l == 0 then
Save('firstL', 0)
end
if pamt_s == 0 then
Save('firstS', 0)
end
if botProfit > highestP then
Save('highestP', botProfit)
elseif botProfit < lowestP then
Save('lowestP', botProfit)
end
---------------------
-- WTF
if wtfStop then
local longNull = pamt_l == 0
local shortNull = pamt_s == 0
if longNull and shortNull then
DeactivateBot('Deactivate on No Position is active', true)
else
LogWarning('Will deactivate on No Position, waiting...maybe next second, maybe never :)')
end
end
if wtfBal then
if balRatio > reduceTrigger then
DeactivateBot('Over Budget', true)
end
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, '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, 'Top', 60, {c=Green})
Plot(4, 'Mid', 50, {c=DarkGray})
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..' | 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 2022.1.25')
Log(' ')
10 Comments
Sign in to leave a comment.
could you recomend safe settings for deposit usdt 500 ? no liquidation and small gain 2+% day
coins? how many pairs?
Thanks for the script
do you have good results? Share please.
i stated testing it on simulated account. lets wait and see :)
ok! give me results please when u finish
Have been following this script for a while... settings need creative inputs when using on inverse accs (profit in Crypto) to get ANY backtest results... here's what I mean. Regular leverage accs profit in USDT so the custom wallet and trading balance settings are calculated in USDT and display correctly in USDT even though it uses BTC as the quantity for contract sizes, AWESOME works correctly ...whereas inverse lev accs profit in crypto so the custom wallet and trading balance are calculated as crypto and inverse trading amount as USD per contract and don't display correctly in BTC because it uses usd as the quantity for contracts (the inverse trading amount setting) and reads the custom and trading balances as BTC amounts ... It will correctly calculate BTC profit but the wallet totals will be wrong extremely wrong. If you enter actual BTC amounts instead of USD/T in the custom or trading balance settings the bot won't be able to execute orders because it states the contract size is to small (below exchange min)... and if you add USD amounts in those settings it thinks you have that many BTC in BTC. Normal lev acc $1000 in custom and trading balance settings and it works on $1000... Inverse lev acc 1000 in both custom and trading balance settings and it works on you have 1000 BTC... ok so how about I say 0.2 for custom and trading bal settings on a inverse x10 leverage acc and it won't make a trade nor backtest results because it's below min contract size (for an inverse acc). It's probably unavoidable in the code and the calculations of profit for inverse accs will be sound as long as you ignore the wallet balance figure and just look at the additional coin it added to amount you put in...the min amount for inverse accs is $10 USD (which the bot will show as 10BTC in your results). Only putting in a inverse amount in settings also yields no results. Just be sure to check your settings and play around with them until you receive realistic profit amounts... $1000 will NOT YEILD YOU 100+ BTC over a week lol.. the bot isn't magic. returns will be in decimal amounts.
got a question, does it also happen to others when your order is in good profits it does not exit the trade and let it ru all the way back again while in the logs it supassed your exit price (by a mile)
Thanks for the great contribution!
Sorry for the late reply.
so yeah, that is a coding mistake in the taking profit part. the solution would be:
1. manually close the position in the exchange then either use VPM to close the position in the bot or stop and clean the bot
2. use the later version which does not have this problem.
always a pleasure and thanks for the amazing platform!