Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //@version=3
- study("BitMEX Funding [m59]", shorttitle="BitMEX Funding", precision=4, max_bars_back=481, overlay=true)
- //----- DESCRIPTION
- // This indicator emulates BitMEX funding rates with reasonably accurate results.
- // BitMEX funding occurs every 8 hours at 4:00 UTC, 12:00 UTC and 20:00 UTC.
- // You pay the funding rate if you are in a position at funding time.
- // The funding rate is predicted from the minute funding occurs over 480 minutes (8 hours).
- // After 8 hours, which is another funding time, the predicted rate is set as the next funding rate, which will be paid 8 hours later at the next funding time.
- // For example:
- // It is 4:00 UTC and funding is paid, and there is currently a predicted rate of 0.01.
- // The predicted rate, 0.01, will be set as the next funding rate which will be paid in 8 hours at the next funding time.
- // The predicted rate resets and will become a more accurate prediction each minute.
- // Funding Rate Bar: On the bar on which funding is paid (see funding times), a column is rendered with the value of the paid funding rate.
- // Next Funding Rate: The rendered circles show the next funding rate, which will be the value of the Funding Rate Bar
- // Predicted Funding Rate: The rendered line is the predicted funding rate that resets when funding is paid.
- // Daily, Weekly, and Monthly views show the total of fundings within the bar.
- // i.e. a daily bar contains 3 funding periods, so if funding were 0.1 each of those times, the daily funding is 0.3.
- // There are 21 funding periods in a week, so a week during which the funding was 0.1 on average will have a Weekly bar with a funding value of 2.1
- // * A note on emulation accuracy
- // Funding rate emulation uses lower time frame data from TradingView which has limited history.
- // On my chart at the time of writing this, I am able to access 20 weeks of that data.
- // Beyond that point, the funding rate emulation becomes less accurate,
- // though it is still reasonably similar for the purpose of trend/sentiment analysis.
- //----- PRINTED VALUES
- // Predicted Funding Rate | Next Funding Rate | Funding Rate Bar
- //----- OPTIONS
- // - Contract: Choose the BitMEX perpetual swap contract for which to emulate funding. XBTUSD or ETHUSD
- // - Cap Funding: BitMEX funding has a cap. Disable this if you want to see what the value would be without the funding cap.
- // - Use Alternate Colors When Accuracy Reduced: Use distinct colors when accuracy is reduced. See note about accuracy in the indicator description.
- //----- INPUTS
- whenLong = input(title= "Long", type=float, defval= 0.3, step= 0.01)
- whenShort = input(title= "Short", type=float, defval= -0.3 , step= 0.01)
- whichFunding = input("Daily Funding", title="Type of Funding", options=[ "8h Funding", "Daily Funding" ] )
- contract = input("XBTUSD", title="Contract", options=[ "XBTUSD", "ETHUSD" ])
- capFunding = true
- useAlternateColorsWhenAccuracyReduced = true
- CONTRACT_XBTUSD = "XBTUSD"
- CONTRACT_ETHUSD = "ETHUSD"
- //----- HELPERS
- clamp (lowest, highest, subject) => max(lowest, min(highest, subject))
- minutesToBars (minutes) =>
- dailyMinutes = 1440
- weeklyMinutes = 10080
- monthlyMinutes = weeklyMinutes * 30
- resolutionBaseMinutes = ismonthly ? monthlyMinutes :
- isweekly ? weeklyMinutes :
- isdaily ? dailyMinutes :
- 1
- barMinutes = interval * resolutionBaseMinutes
- minutes / barMinutes
- total (src, length) =>
- result = 0.0
- for i = 0 to length - 1
- if (i < 0)
- result := na
- break
- result := result + src[i]
- result
- simpleMovingAverage (src, length) => total(src, length) / length
- // this seems to be faster than the built-in `barssince ` function, which was contributing to an error for being too slow
- barsSince (condition) =>
- bars = 0
- bars := condition ? 0 : bars[1] + 1
- twap (resetWhen, src) =>
- bars = barsSince(resetWhen) + 1
- simpleMovingAverage(src, bars)
- // Funding occurs every 8 hours at 04:00 UTC, 12:00 UTC and 20:00 UTC.
- isBitmexFundingBar = ((hour == 4 or hour == 12 or hour == 20) and (minute == 0)) or isdwm
- fundingTwap (src) => twap(isBitmexFundingBar, src)
- bitmexInterestRateTwap (asset) =>
- //----- Interest Rate Component
- // Every contract traded on BitMEX consists of two instruments: a Base currency and a Quote currency.
- // For example, on XBTUSD, the Base currency is XBT while the quote currency is USD.
- // The Interest Rate is a function of interest rates between these two currencies:
- interestBaseIndex = security("BITMEX:" + asset + "BON", period, close) // The Interest Rate for borrowing the Base currency
- interestQuoteIndex = security("BITMEX:USDBON", period, close) // The Interest Rate for borrowing the Quote currency
- fundingInterval = 3 // (Since funding occurs every 8 hours)
- interestRate = nz((interestQuoteIndex - interestBaseIndex) / fundingInterval, 0.0001)
- fundingTwap(interestRate)
- bitmexPremiumIndexTwap (asset) =>
- //----- Premium / Discount Component
- // The perpetual contract may trade at a significant premium or discount to the Mark Price.
- // In those situations, a Premium Index will be used to raise or lower the next Funding Rate to levels consistent with where the contract is trading.
- // Each contract’s Premium Index is available on the specific instrument’s Contract Specifications page and is calculated as follows:
- // Premium Index (P) = (Max(0, Impact Bid Price - Mark Price) - Max(0, Mark Price - Impact Ask Price)) / Spot Price + Fair Basis used in Mark Price
- premiumIndexTwap_fallback = security("BITMEX:" + asset + "USDPI", period, fundingTwap(ohlc4))
- premiumIndexTwap = security("BITMEX:" + asset + "USDPI", "1", fundingTwap(ohlc4))
- [ premiumIndexTwap, premiumIndexTwap_fallback ]
- bitmexPredictedFundingRate (asset, capFunding, fundingCapAmount, dampenerAmount, interestRateTwap, premiumIndexTwap) =>
- predictedBaseFundingRateRatio = premiumIndexTwap + clamp(-dampenerAmount, dampenerAmount, interestRateTwap - premiumIndexTwap)
- predictedFundingRateRatio = capFunding ? clamp(-fundingCapAmount, fundingCapAmount, predictedBaseFundingRateRatio) : predictedBaseFundingRateRatio
- predictedFundingRateRatio * 100
- bitmexNextFundingRate (predictedFundingRate) =>
- nextFundingRate = 0.01
- nextFundingRate := isBitmexFundingBar ? predictedFundingRate[1] : nextFundingRate[1]
- bitmexFundingBarValue (assetTicker, predictedFundingRate) =>
- fundingPeriodMinutes = 480
- fundingPeriodBars = max(1, floor(minutesToBars(fundingPeriodMinutes)))
- fundingOffset = fundingPeriodBars + 1
- dwmIntervalModifier = isdaily ? 3 :
- isweekly ? 3 * 7 :
- ismonthly ? 3 * 30 :
- na
- dwmModifier = interval * dwmIntervalModifier
- intradayFundingBarValue = predictedFundingRate[fundingOffset]
- // any ticker will work fine here, but simply using `ticker` (the current chart) doesn't work on special charts like spread charts that can't access `ticker`
- nonIntradayFundingBarValue = security(assetTicker, "240", intradayFundingBarValue) * dwmModifier
- (not isBitmexFundingBar) ? na : (isintraday ? intradayFundingBarValue : nonIntradayFundingBarValue)
- //----- VALUES
- asset = contract == CONTRACT_XBTUSD ? "XBT" :
- contract == CONTRACT_ETHUSD ? "ETH" :
- "XBT"
- assetTicker = asset + "USD"
- [ premiumIndexTwap_ideal, premiumIndexTwap_fallback ] = bitmexPremiumIndexTwap(asset)
- premiumIndexTwap = na(premiumIndexTwap_ideal) ? premiumIndexTwap_fallback : premiumIndexTwap_ideal
- interestRateTwap = bitmexInterestRateTwap(asset)
- predictedFundingRate = bitmexPredictedFundingRate(asset, capFunding, 0.00375, 0.0005, interestRateTwap, premiumIndexTwap)
- nextFundingRate = bitmexNextFundingRate(predictedFundingRate)
- fundingBarValue = bitmexFundingBarValue(assetTicker, predictedFundingRate)
- accuracyReduced = na(premiumIndexTwap_ideal)
- theActualUsedFunding = whichFunding == "8h Funding" ? nextFundingRate : predictedFundingRate
- //----- RENDER
- longsColor = #53B987
- shortsColor = #EB4D5C
- longsAlternateColor = #247BA0
- shortsAlternateColor = orange
- useAlternateColors = useAlternateColorsWhenAccuracyReduced and accuracyReduced
- FundingColor (rate) => rate < 0 ? (useAlternateColors ? shortsAlternateColor : shortsColor) : (useAlternateColors ? longsAlternateColor : longsColor)
- nextFundingColor = FundingColor(nextFundingRate)
- fundingBarColor = FundingColor(fundingBarValue)
- longsPay= theActualUsedFunding > whenLong
- shortsPay= theActualUsedFunding < whenShort
- bgcolor(color=(longsPay ? red : (shortsPay ? green : na)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement