यह रणनीति ट्रेंड को ट्रैक करने के लिए हुल और एलएसएमए (न्यूनतम वर्ग चलती औसत) संकेतकों को मिलाकर प्रवृत्ति दिशाओं और उलट बिंदुओं की पहचान करती है। यह तब लंबा हो जाता है जब हुल एक अपट्रेंड दिखाता है और एलएसएमए हुल के ऊपर पार करता है, और जब हुल एक डाउनट्रेंड दिखाता है और एलएसएमए हुल के नीचे पार करता है तो छोटा हो जाता है। यह रणनीति मध्यम-कम आवृत्ति व्यापार के लिए उपयुक्त है और इसका उपयोग 1 मिनट के समय सीमा पर किया जा सकता है।
हुल सूचक का उपयोग मूल्य की प्रवृत्ति दिशा निर्धारित करने के लिए किया जाता है। जब मध्य बैंड (MHULL) निचले बैंड (LHULL) से ऊपर होता है, तो यह एक अपट्रेंड को इंगित करता है; अन्यथा यह एक डाउनट्रेंड को इंगित करता है।
एलएसएमए संकेतक का उपयोग प्रवृत्ति के उलट बिंदुओं की पहचान करने के लिए किया जाता है। जब एलएसएमए एमएचयूएलएल से ऊपर पार करता है, तो यह एक अपट्रेंड के गठन या त्वरण का संकेत देता है; जब एलएसएमए एमएचयूएलएल से नीचे पार करता है, तो यह एक डाउनट्रेंड के गठन या त्वरण का संकेत देता है।
दोनों को मिलाकर, रणनीति लंबी जाती है जब हुल एक अपट्रेंड (MHULL > LHULL) दिखाता है और LSMA MHULL के ऊपर पार करता है, और छोटी जाती है जब हुल एक डाउनट्रेंड (MHULL < LHULL) दिखाता है और LSMA MHULL के नीचे पार करता है।
स्टॉप लॉस को नवीनतम उतार-चढ़ाव बिंदु पर सेट किया जाता है. लंबी स्थिति के लिए यह सबसे हालिया स्विंग निम्न है, और छोटी स्थिति के लिए यह सबसे हालिया स्विंग उच्च है.
इस रणनीति के मुख्य लाभ इस प्रकार हैंः
हुल संकेतक प्रवृत्ति संक्रमण को पकड़ने में संवेदनशील है, जबकि एलएसएमए रिवर्स सिग्नल की विश्वसनीयता से पहचान करने में चिकनी है। यह संयोजन प्रभावी रूप से काम करता है।
एलएसएमए क्रॉसिंग का उपयोग करके हुल इंडिकेटर से झूठे संकेतों को फ़िल्टर किया जाता है और गलत ट्रेडों को कम किया जाता है।
स्टॉप लॉस के लिए उतार-चढ़ाव के बिंदुओं का उपयोग धन को अधिकतम सीमा तक सुरक्षित करता है।
यह मध्यम-निम्न आवृत्ति व्यापार के लिए उपयुक्त है और व्यापक अनुप्रयोग के साथ 1 मिनट के रूप में कम समय सीमा पर इस्तेमाल किया जा सकता है।
इस रणनीति के साथ कुछ जोखिम भी हैंः
रेंजिंग बाजारों में, हुल और एलएसएमए के बीच अत्यधिक क्रॉसओवर हो सकते हैं जिससे ओवर-ट्रेडिंग हो सकती है। ट्रेडिंग आवृत्ति को कम करने के लिए मापदंडों को उचित रूप से समायोजित किया जाना चाहिए।
स्टॉप लॉस को उतार-चढ़ाव के बिंदुओं पर सेट किया जा सकता है, जो कि अल्पकालिक मूल्य समायोजनों के कारण हो सकता है। दूरी को उचित रूप से बढ़ाया जाना चाहिए।
एलएसएमए के पीछे रहने के कारण गलत आकलन का कुछ जोखिम हो सकता है। संकेतों की पुष्टि करने के लिए कैंडलस्टिक पैटर्न जैसे अन्य संकेतकों का उपयोग किया जाना चाहिए।
इस रणनीति को निम्नलिखित पहलुओं में अनुकूलित किया जा सकता हैः
विभिन्न उत्पादों और समय सीमाओं से मेल खाने के लिए हुल और एलएसएमए के मापदंडों को अनुकूलित करें।
विभिन्न बाजारों में गलत लेनदेन से बचने के लिए अस्थिरता, मात्रा आदि के आधार पर फ़िल्टर जोड़ें।
प्रवृत्ति प्रवृत्तियों का आकलन करने में सहायता के लिए मशीन लर्निंग मॉडल को शामिल करें।
अधिक उचित स्टॉप लॉस प्लेसमेंट के लिए डीप लर्निंग तकनीकों के साथ प्रमुख समर्थन/प्रतिरोध क्षेत्रों की पहचान करें।
हुल और एलएसएमए को मिलाकर, यह रणनीति प्रभावी रूप से ट्रेडिंग के बाद की प्रवृत्ति के लिए प्रवृत्ति दिशा में परिवर्तन का न्याय करती है। इसका लाभ यह है कि इसे लागू करना सरल, उत्तरदायी और मध्यम-कम आवृत्ति एल्गो ट्रेडिंग के लिए व्यापक रूप से लागू किया जा सकता है। फ़िल्टरिंग स्थितियों, सहायक निर्णयों और स्टॉप लॉस एल्गोरिदम में आगे के सुधार से संभावित रूप से बेहतर रणनीति प्रदर्शन हो सकता है।
/*backtest start: 2024-01-28 00:00:00 end: 2024-02-04 00:00:00 period: 3m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © myn //@version=5 strategy('Strategy Myth-Busting #9 - HullSuite+LSMA - [MYN]', max_bars_back=5000, overlay=true, pyramiding=0, initial_capital=1000, currency='USD', default_qty_type=strategy.percent_of_equity, default_qty_value=1.0, commission_value=0.075, use_bar_magnifier = false) // Hull Suite by InSilico // Least Squares Moving Average // Long // Hull Suite is red and LSMA crosses above HUll Suite while red // Stop loss latest swing low //Short // Hull Suite is green and LSMA crosses under HUll Suite while green // Stop loss latest swing high //1:4 Risk ratio // 1 minute timeframe ///////////////////////////////////// //* Put your strategy logic below *// ///////////////////////////////////// //72iE0gCVjvM // LSMA //░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ //@version=5 //indicator(title = "Least Squares Moving Average", shorttitle="LSMA", overlay=true, timeframe="", timeframe_gaps=true) length1 = input(title="Length", defval=25, group="Least Squares Moving Average (LSMA)") offset1 = input(title="Offset", defval=0) src1 = input(close, title="Source") lsma = ta.linreg(src1, length1, offset1) plot(lsma, color=color.white) // Hull Suite by InSilico //░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ //@version=5 //Basic Hull Ma Pack tinkered by InSilico //indicator('Hull Suite by InSilico', overlay=true) //INPUT src = input(close, title='Source', group="Hull Suite") modeSwitch = input.string('Hma', title='Hull Variation', options=['Hma', 'Thma', 'Ehma']) length = input(55, title='Length(180-200 for floating S/R , 55 for swing entry)') lengthMult = input(1.0, title='Length multiplier (Used to view higher timeframes with straight band)') useHtf = input(false, title='Show Hull MA from X timeframe? (good for scalping)') htf = input.timeframe('240', title='Higher timeframe') switchColor = input(true, 'Color Hull according to trend?') candleCol = input(false, title='Color candles based on Hull\'s Trend?') visualSwitch = input(false, title='Show as a Band?') thicknesSwitch = input(1, title='Line Thickness') transpSwitch = input.int(40, title='Band Transparency', step=5) //FUNCTIONS //HMA HMA(_src, _length) => ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length))) //EHMA EHMA(_src, _length) => ta.ema(2 * ta.ema(_src, _length / 2) - ta.ema(_src, _length), math.round(math.sqrt(_length))) //THMA THMA(_src, _length) => ta.wma(ta.wma(_src, _length / 3) * 3 - ta.wma(_src, _length / 2) - ta.wma(_src, _length), _length) //SWITCH Mode(modeSwitch, src, len) => modeSwitch == 'Hma' ? HMA(src, len) : modeSwitch == 'Ehma' ? EHMA(src, len) : modeSwitch == 'Thma' ? THMA(src, len / 2) : na //OUT _hull = Mode(modeSwitch, src, int(length * lengthMult)) HULL = useHtf ? request.security(syminfo.ticker, htf, _hull) : _hull MHULL = HULL[0] SHULL = HULL[2] //COLOR hullColor = switchColor ? HULL > HULL[2] ? #00ff00 : #ff0000 : #ff9800 //PLOT ///< Frame Fi1 = plot(MHULL, title='MHULL', color=hullColor, linewidth=thicknesSwitch, transp=50) Fi2 = plot(visualSwitch ? SHULL : na, title='SHULL', color=hullColor, linewidth=thicknesSwitch, transp=50) alertcondition(ta.crossover(MHULL, SHULL), title='Hull trending up.', message='Hull trending up.') alertcondition(ta.crossover(SHULL, MHULL), title='Hull trending down.', message='Hull trending down.') ///< Ending Filler fill(Fi1, Fi2, title='Band Filler', color=hullColor, transp=transpSwitch) ///BARCOLOR barcolor(color=candleCol ? switchColor ? hullColor : na : na) // Long // Hull Suite is red and LSMA crosses above HUll Suite while red // Stop loss latest swing low //Short // Hull Suite is green and LSMA crosses under HUll Suite while green // Stop loss latest swing high //1:4 Risk ratio longEntry = hullColor == #ff0000 and ta.crossover(lsma, MHULL ) shortEntry = hullColor == #00ff00 and ta.crossunder(lsma, MHULL) ////////////////////////////////////// //* Put your strategy rules below *// ///////////////////////////////////// longCondition = longEntry shortCondition = shortEntry //define as 0 if do not want to use closeLongCondition = 0 closeShortCondition = 0 // ADX //░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ adxEnabled = input.bool(defval = false , title = "Average Directional Index (ADX)", tooltip = "", group ="ADX" ) adxlen = input(14, title="ADX Smoothing", group="ADX") adxdilen = input(14, title="DI Length", group="ADX") adxabove = input(25, title="ADX Threshold", group="ADX") adxdirmov(len) => adxup = ta.change(high) adxdown = -ta.change(low) adxplusDM = na(adxup) ? na : (adxup > adxdown and adxup > 0 ? adxup : 0) adxminusDM = na(adxdown) ? na : (adxdown > adxup and adxdown > 0 ? adxdown : 0) adxtruerange = ta.rma(ta.tr, len) adxplus = fixnan(100 * ta.rma(adxplusDM, len) / adxtruerange) adxminus = fixnan(100 * ta.rma(adxminusDM, len) / adxtruerange) [adxplus, adxminus] adx(adxdilen, adxlen) => [adxplus, adxminus] = adxdirmov(adxdilen) adxsum = adxplus + adxminus adx = 100 * ta.rma(math.abs(adxplus - adxminus) / (adxsum == 0 ? 1 : adxsum), adxlen) adxsig = adxEnabled ? adx(adxdilen, adxlen) : na isADXEnabledAndAboveThreshold = adxEnabled ? (adxsig > adxabove) : true //Backtesting Time Period (Input.time not working as expected as of 03/30/2021. Giving odd start/end dates //░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ useStartPeriodTime = input.bool(true, 'Start', group='Date Range', inline='Start Period') startPeriodTime = input(timestamp('1 Jan 2019'), '', group='Date Range', inline='Start Period') useEndPeriodTime = input.bool(true, 'End', group='Date Range', inline='End Period') endPeriodTime = input(timestamp('31 Dec 2030'), '', group='Date Range', inline='End Period') start = useStartPeriodTime ? startPeriodTime >= time : false end = useEndPeriodTime ? endPeriodTime <= time : false calcPeriod = true // Trade Direction // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ tradeDirection = input.string('Long and Short', title='Trade Direction', options=['Long and Short', 'Long Only', 'Short Only'], group='Trade Direction') // Percent as Points // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ per(pcnt) => strategy.position_size != 0 ? math.round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na) // Take profit 1 // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ tp1 = input.float(title='Take Profit 1 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 1') q1 = input.int(title='% Of Position', defval=100, minval=0, group='Take Profit', inline='Take Profit 1') // Take profit 2 // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ tp2 = input.float(title='Take Profit 2 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 2') q2 = input.int(title='% Of Position', defval=100, minval=0, group='Take Profit', inline='Take Profit 2') // Take profit 3 // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ tp3 = input.float(title='Take Profit 3 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 3') q3 = input.int(title='% Of Position', defval=100, minval=0, group='Take Profit', inline='Take Profit 3') // Take profit 4 // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ tp4 = input.float(title='Take Profit 4 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit') /// Stop Loss // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ stoplossPercent = input.float(title='Stop Loss (%)', defval=999, minval=0.01, group='Stop Loss') * 0.01 slLongClose = close < strategy.position_avg_price * (1 - stoplossPercent) slShortClose = close > strategy.position_avg_price * (1 + stoplossPercent) /// Leverage // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ leverage = input.float(1, 'Leverage', step=.5, group='Leverage') contracts = math.min(math.max(.000001, strategy.equity / close * leverage), 1000000000) /// Trade State Management // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ isInLongPosition = strategy.position_size > 0 isInShortPosition = strategy.position_size < 0 /// ProfitView Alert Syntax String Generation // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ alertSyntaxPrefix = input.string(defval='CRYPTANEX_99FTX_Strategy-Name-Here', title='Alert Syntax Prefix', group='ProfitView Alert Syntax') alertSyntaxBase = alertSyntaxPrefix + '\n#' + str.tostring(open) + ',' + str.tostring(high) + ',' + str.tostring(low) + ',' + str.tostring(close) + ',' + str.tostring(volume) + ',' /// Trade Execution // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ longConditionCalc = (longCondition and isADXEnabledAndAboveThreshold) shortConditionCalc = (shortCondition and isADXEnabledAndAboveThreshold) if calcPeriod if longConditionCalc and tradeDirection != 'Short Only' and isInLongPosition == false strategy.entry('Long', strategy.long, qty=contracts) alert(message=alertSyntaxBase + 'side:long', freq=alert.freq_once_per_bar_close) if shortConditionCalc and tradeDirection != 'Long Only' and isInShortPosition == false strategy.entry('Short', strategy.short, qty=contracts) alert(message=alertSyntaxBase + 'side:short', freq=alert.freq_once_per_bar_close) //Inspired from Multiple %% profit exits example by adolgo https://www.tradingview.com/script/kHhCik9f-Multiple-profit-exits-example/ strategy.exit('TP1', qty_percent=q1, profit=per(tp1)) strategy.exit('TP2', qty_percent=q2, profit=per(tp2)) strategy.exit('TP3', qty_percent=q3, profit=per(tp3)) strategy.exit('TP4', profit=per(tp4)) strategy.close('Long', qty_percent=100, comment='SL Long', when=slLongClose) strategy.close('Short', qty_percent=100, comment='SL Short', when=slShortClose) strategy.close_all(when=closeLongCondition or closeShortCondition, comment='Close Postion') /// Dashboard // ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ // Inspired by https://www.tradingview.com/script/uWqKX6A2/ - Thanks VertMT showDashboard = input.bool(group="Dashboard", title="Show Dashboard", defval=false) f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) => _cellText = _title + "\n" + _value table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor, text_color=_txtcolor, text_size=size.auto) // Draw dashboard table if showDashboard var bgcolor = color.new(color.black,0) // Keep track of Wins/Losses streaks newWin = (strategy.wintrades > strategy.wintrades[1]) and (strategy.losstrades == strategy.losstrades[1]) and (strategy.eventrades == strategy.eventrades[1]) newLoss = (strategy.wintrades == strategy.wintrades[1]) and (strategy.losstrades > strategy.losstrades[1]) and (strategy.eventrades == strategy.eventrades[1]) varip int winRow = 0 varip int lossRow = 0 varip int maxWinRow = 0 varip int maxLossRow = 0 if newWin lossRow := 0 winRow := winRow + 1 if winRow > maxWinRow maxWinRow := winRow if newLoss winRow := 0 lossRow := lossRow + 1 if lossRow > maxLossRow maxLossRow := lossRow // Prepare stats table var table dashTable = table.new(position.bottom_right, 1, 15, border_width=1) if barstate.islastconfirmedhistory // Update table dollarReturn = strategy.netprofit f_fillCell(dashTable, 0, 0, "Start:", str.format("{0,date,long}", strategy.closedtrades.entry_time(0)) , bgcolor, color.white) // + str.format(" {0,time,HH:mm}", strategy.closedtrades.entry_time(0)) f_fillCell(dashTable, 0, 1, "End:", str.format("{0,date,long}", strategy.opentrades.entry_time(0)) , bgcolor, color.white) // + str.format(" {0,time,HH:mm}", strategy.opentrades.entry_time(0)) _profit = (strategy.netprofit / strategy.initial_capital) * 100 f_fillCell(dashTable, 0, 2, "Net Profit:", str.tostring(_profit, '##.##') + "%", _profit > 0 ? color.green : color.red, color.white) _numOfDaysInStrategy = (strategy.opentrades.entry_time(0) - strategy.closedtrades.entry_time(0)) / (1000 * 3600 * 24) f_fillCell(dashTable, 0, 3, "Percent Per Day", str.tostring(_profit / _numOfDaysInStrategy, '#########################.#####')+"%", _profit > 0 ? color.green : color.red, color.white) _winRate = ( strategy.wintrades / strategy.closedtrades ) * 100 f_fillCell(dashTable, 0, 4, "Percent Profitable:", str.tostring(_winRate, '##.##') + "%", _winRate < 50 ? color.red : _winRate < 75 ? #999900 : color.green, color.white) f_fillCell(dashTable, 0, 5, "Profit Factor:", str.tostring(strategy.grossprofit / strategy.grossloss, '##.###'), strategy.grossprofit > strategy.grossloss ? color.green : color.red, color.white) f_fillCell(dashTable, 0, 6, "Total Trades:", str.tostring(strategy.closedtrades), bgcolor, color.white) f_fillCell(dashTable, 0, 8, "Max Wins In A Row:", str.tostring(maxWinRow, '######') , bgcolor, color.white) f_fillCell(dashTable, 0, 9, "Max Losses In A Row:", str.tostring(maxLossRow, '######') , bgcolor, color.white)