Xu hướng sau chiến lược giao dịch chéo trung bình động

Tác giả:ChaoZhang, Ngày: 2023-11-06 16:01:30
Tags:

img

Tổng quan

Đây là một chiến lược giao dịch theo xu hướng dựa trên các đường trung bình động. Nó sử dụng ba đường trung bình động Hull với các thiết lập tham số khác nhau để xác định hướng xu hướng giá và kết hợp bộ lọc ATR nhanh để phát hiện sự đảo ngược xu hướng tiềm năng trước. Khi các đường trung bình động nhanh, trung bình và chậm vượt lên hoặc xuống, các tín hiệu mua hoặc bán được tạo ra. Chiến lược cũng có các chức năng dừng lỗ và lấy lợi nhuận để kiểm soát rủi ro một cách hiệu quả.

Chiến lược logic

Chiến lược sử dụng ba trung bình động Hull để đánh giá xu hướng giá, bao gồm một Hull MA nhanh hơn, một Hull MA trung bình và một Hull MA chậm hơn.

  1. Khi đường nhanh vượt qua đường trung bình, nó cho thấy giá đang bước vào xu hướng tăng và một tín hiệu mua được tạo ra.

  2. Khi đường nhanh vượt qua dưới đường trung bình, nó cho thấy giá đang đi xuống và một tín hiệu bán được tạo ra.

Để tăng độ nhạy trong việc xác định sự đảo ngược xu hướng, chiến lược giới thiệu một bộ lọc ATR nhanh dựa trên RSI. Bộ lọc này có thể đo biến động của mức giá. Khi xu hướng giá thay đổi, giá trị của nó sẽ thay đổi đáng kể. Do đó, chúng ta có thể đánh giá sự đảo ngược xu hướng giá trước dựa trên sự đột phá của bộ lọc ATR.

Cụ thể, chức năng lọc thực hiện logic tính toán của bộ lọc ATR nhanh này. Nó tính toán kích thước ATR dựa trên các giá trị RSI. Khi giá trị ATR phá vỡ trên hoặc dưới đường cong RSI, nó có thể chỉ ra sự thay đổi trong xu hướng giá.

Ngoài ra, chiến lược đặt ra các điều kiện dừng lỗ và lấy lợi nhuận để thực hiện quản lý rủi ro tự động theo tỷ lệ dừng lỗ và lấy lợi nhuận.

Phân tích lợi thế

  • Sử dụng ba đường MA Hull để xác định hướng xu hướng có thể lọc hiệu quả tiếng ồn thị trường và xác định xu hướng trung bình đến dài hạn

  • Ứng dụng bộ lọc ATR nhanh có thể cải thiện khả năng đánh giá sớm sự đảo ngược xu hướng

  • Tự động nắm bắt các cơ hội đảo ngược xu hướng và điều chỉnh đúng thời điểm các vị trí mà không bỏ lỡ mua hoặc bán

  • Việc thiết lập dừng lỗ và lấy lợi nhuận di chuyển đạt được sự cân bằng năng động giữa rủi ro và phần thưởng

  • Các thông số tùy chỉnh làm cho nó phù hợp với các thị trường và công cụ giao dịch khác nhau

Phân tích rủi ro

  • Các chiến lược chéo MA có xu hướng tạo ra tín hiệu mua và bán sai, đòi hỏi bộ lọc ATR để xác minh

  • Trong thị trường biến động, các MAs có thể vượt qua thường xuyên, theo dõi chặt chẽ các chuyển động đường cong ATR

  • Một điểm dừng lỗ quá nhỏ có xu hướng bị dừng lại, quá lớn không thể kiểm soát tổn thất.

  • Chiến lược này phù hợp hơn với các thị trường xu hướng, không phù hợp với các thị trường giới hạn phạm vi

  • Có thể tối ưu hóa các thông số để chọn kết hợp thời gian MA và ATR tốt nhất, giảm tín hiệu sai

Hướng dẫn tối ưu hóa

  • Hãy thử thay đổi loại MA để DEMA, TEMA vv, xem nếu nhiều tiếng ồn có thể được lọc

  • Bộ lọc ATR có thể được thay đổi thành đường MIDDLE của Keltner để cải thiện phán đoán đảo ngược xu hướng

  • Có thể thử nghiệm các kết hợp tham số MA khác nhau để tìm cặp tối ưu

  • Có thể kiểm tra tham số thời gian ATR để tìm hiệu ứng làm mịn tốt nhất

  • Có thể thêm các chỉ số khối lượng để hỗ trợ đánh giá sự đột phá đúng / sai

  • Có thể thử thêm các chỉ số khác như MACD để cải thiện độ tin cậy tín hiệu

Tóm lại

Chiến lược này tích hợp các đường trung bình động cho hướng xu hướng, bộ lọc ATR để phát hiện sớm sự đảo ngược và tự động dừng lỗ / lấy lợi nhuận để quản lý rủi ro. Nó có thể tự động theo dõi xu hướng và nắm bắt kịp thời cơ hội đảo ngược. Thông qua tối ưu hóa tham số, nó có thể được áp dụng cho các công cụ và khung thời gian khác nhau và là một xu hướng rất thực tế sau chiến lược giao dịch.


/*backtest
start: 2023-10-06 00:00:00
end: 2023-11-05 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=3

//



//*** START of COMMENT OUT [Alerts]

//strategy(title="[Backtest]QQE Cross v6.0 by JustUncleL", shorttitle="[BT]QQEX v6.0", overlay=true,

//         pyramiding=0, default_qty_value=1000, commission_value=0.1,

//         commission_type=strategy.commission.percent, initial_capital=10000)

//*** END of COMMENT OUT [Alerts]

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//



//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>//

//*** START of COMMENT OUT [BackTest]

strategy(

  title="[Alerts]QQE Cross v6.0 by JustUncleL",

  shorttitle="[AL]QQEX v6.0",

  overlay=true)





FromMonth = input(defval=1, title="From Month", minval=1, maxval=12)

FromDay = input(defval=1, title="From Day", minval=1, maxval=31)

FromYear = input(defval=2009, title="From Year")

ToMonth = input(defval=1, title="To Month", minval=1, maxval=12)

ToDay = input(defval=1, title="To Day", minval=1, maxval=31)

ToYear = input(defval=9999, title="To Year")



start = timestamp(FromYear, FromMonth, FromDay, 00, 00)  // backtest start window

finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)  // backtest finish window

window = true  // create function "within window of time"





trade_dir = input('Long Only', options=['Long Only', 'Short Only', 'Long and Short'], title='Trade Direction')

tp1_perc = input(25, step=0.25, minval=0, title='Take Profit Signal 1 Qty Percent')/100

tp2_perc = input(25, step=0.25, minval=0, title='Take Profit Signal 2 Qty Percent')/100

sl_perc = input(2, step=0.25, minval=0, title='Stop Loss Percent')/100



dir = trade_dir == 'Long Only' ? strategy.direction.long :

  trade_dir == 'Short Only' ? strategy.direction.short : strategy.direction.all



strategy.risk.allow_entry_in(dir)



//*** END of COMMENT OUT [BackTest]



//

// Author:  JustUncleL

// Date:    10-July-2016

// Version: v6, Major Release Nov-2018

//

// Description:

//  A following indicator is Trend following that uses fast QQE crosses with Moving Averages

//  for trend direction filtering. QQE or Qualitative Quantitative Estimation is based

//  on the relative strength index (RSI), but uses a smoothing technique as an additional

//  transformation. Three crosses can be selected (all selected by default):

//    - Smooth RSI signal crossing ZERO (XZ)

//    - Smooth RSI signal crossing Fast QQE line (XQ), this is like an early warning swing signal.

//    - Smooth RSI signal exiting the RSI Threshhold Channel (XC), this is like a confirmed swing signal.

//      An optimumal Smooth RSI threshold level is between 5% and 10% (default=10), it helps reduce

//      the false swings.

//  These signals can be selected to Open Short/Long and/or Close a trade, default is XC open

//  trade and XQ (or opposite open) to Close trade.

//

//  The (LONG/SHORT) alerts can be optionally filtered by the Moving Average Ribbons:

//    - For LONG alert the Close must be above the fast MA Ribbon and

//        fast MA Ribbon must be above the slow MA Ribbon.

//    - For SHORT alert the Close must be below the fast MA Ribbon and

//        fast MA Ribbon must be below the slow MA Ribbon.

//  and/or directional filter:

//    - For LONG alert the Close must be above the medium MA and the

//      directional of both MA ribbons must be Bullish.

//    - For SELL alert the Close must be below the medium MA and the

//      directional of both MA ribbons must be Bearish.

//

//  This indicator is designed to be used as a Signal to Signal trading BOT

//  in automatic or semi-automatic way (start and stop when conditions are suitable).

//  - For LONG and SHORT alerts I recommend you use "Once per Bar" alarm option

//  - For CLOSE alerts I recommend you use "Once per Bar Close" alarm option

//  (* The script has been designed so that long/short signals come at start of candles *)

//  (* and close signals  come at the end of candles                                    *)

//

// Mofidifications:

//  6.0 - Major Release Version

//      - Added second MA ribbon to help filter signals to the trend direction.

//      - Modified Alert filtering to include second MA Ribbon

//      - Change default settings to reflect Signal to Signal BOT parameters.

//      - Removed older redunant alerts.

//

//  5.0 - Development series

//

//  4.1 - Fix bug with painting Buy/Sell arrows when non-repaint shunt mode selected.

//      - Added option to alert just the first Buy/Sell alert after a trend swing

//      - Added Long and Short Alarms. When combined with the "first Buy/Sell" in trend option,

//        It is now possible to use this indicator to interface with AutoView

//        or ProfitView. I suggest using the "QQEX XZ Alert" alarm to exit Long or Short

//        trade. Use only "Once per bar Close" option for Alarms. This is not a full

//        fledged trading BOT though with TP/SL settings.

//

//      - Changed QQE defaults to be a bit smoother (14, 8, 5) instead of (6, 3, 2.618)

//        which is more suited to Forex and Crypto trading.

//

//  4.0 - Added implied GPL copyright notice.

//      - Changed defaults to use HullMAs instead of EMAs.

//  3.0 - No repaint on BUY/SELL alert, however, now trades should be taken when the BUY/SELL

//        Alert is displayed. The alarm is still generated on the previous candle so you can

//        still get a pre-warning, this enables you time to analyse the pending alert.

//      - Added option to test success of alerted trades, highlight successful and failed trade bars

//        and show simple stats: success rate and number of trades (out of 5000), this will help

//        tune the settings for timeframe and currency PAIR.

//  2.0 - Added code to use the medium moving average (EMA20) rising/falling for additional

//        trend direction filter.

//      - Remove Moving Average cross over signals and other options not used in this indicator.

//      - Added code to distinguish between the crosses, now only show Thresh Hold crosses as BUY/SELL

//        alerts.

//      - Modidied default settings to more well known MA's and slightly different QQE settings, these

//        work well at lower timeframes.

//      - Added circle plots at bottom of chart to show when actual BUY/SELL alerts occur.

//  1.0 - original

//

// References:

//  Some Code borrowed from:

//  - "Scalp Jockey - MTF MA Cross Visual Strategizer by JayRogers"

//  - "QQE MT4 by glaz"

//  Inspiration from:

//  - http://www.forexstrategiesresources.com/binary-options-strategies-ii/189-aurora-binary-trading/

//  - http://www.forexstrategiesresources.com/metatrader-4-trading-systems-v/652-qqe-smoothed-trading/

//  - http://dewinforex.com/forex-indicators/qqe-indicator-not-quite-grail-but-accurately-defines-trend-and-flat.html

//  - "Binary option trading by two previous bars" by radixvinni

//

//

// -----------------------------------------------------------------------------

// Copyright 2015 Glaz,JayRogers

//

// Copyright 2016,2017,2018 JustUncleL

//

// This program is free software: you can redistribute it and/or modify

// it under the terms of the GNU General Public License as published by

// the Free Software Foundation, either version 3 of the License, or

// any later version.

//

// This program is distributed in the hope that it will be useful,

// but WITHOUT ANY WARRANTY; without even the implied warranty of

// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

// GNU General Public License for more details.

//

// The GNU General Public License can be found here

// <http://www.gnu.org/licenses/>.

//

// -----------------------------------------------------------------------------

//



// Use Alternate Anchor TF for MAs

anchor     = input(4,minval=0,maxval=100,title="Relative TimeFrame Multiplier for Second MA Ribbon (0=none, max=100)")

//



// - INPUTS START

// Fast MA - type, source, length

showAvgs     = input(true,title="Show Moving Average Lines")

type1   = input(defval="EMA", title="Fast MA Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "HullMA", "ZEMA", "TMA", "SSMA"])

len1    = input(defval=16, title="Fast - Length", minval=1)

gamma1  = 0.33

// Medium Fast MA - type, source, length

type2   = input(defval="EMA", title="Medium MA Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "HullMA", "ZEMA", "TMA", "SSMA"])

len2    = input(defval=21, title="Medium - Length", minval=1)

gamma2  = 0.55

// Slow MA - type, source, length

type3   = input(defval="EMA", title="Slow MA Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "HullMA", "ZEMA", "TMA", "SSMA"])

len3    = input(defval=26, title="Slow Length", minval=1)

gamma3  = 0.77

//

// QQE rsi Length, Smoothing, fast ATR factor, source

RSILen  = input(14,title='RSI Length')

SF      = input(8,title='RSI Smoothing Factor')

QQEfactor  = input(5.0,type=float,title='Fast QQE Factor')

threshhold = input(10, title="RSI Threshhold")

//

sQQEx   = input(true,title="Show QQE Signal crosses")

sQQEz   = input(false,title="Show QQE Zero crosses")

sQQEc   = input(true,title="Show QQE Thresh Hold Channel Exits")

//

tradeSignal = input("XC", title="Select which QQE signal to Buy/Sell", options=["XC","XQ","XZ"])

closeSignal = input("XQ", title="Select which QQE signal to Close Order", options=["XC","XQ","XZ"])

//

xfilter = input(true, title="Filter XQ Buy/Sell Orders by Threshold" )

filter  = input(false,title="Use Moving Average Filter")

dfilter = input(true, title="Use Trend Directional Filter" )

ufirst  = input(false, title="Only Alert First Buy/Sell in a new Trend")

RSIsrc  = input(close,title="Source")



src     = RSIsrc // MA source

srcclose= RSIsrc



///////////////////////////////////////////////

//* Backtesting Period Selector | Component *//

///////////////////////////////////////////////



//* https://www.tradingview.com/script/eCC1cvxQ-Backtesting-Period-Selector-Component *//

//* https://www.tradingview.com/u/pbergden/ *//

//* Modifications made by JustUncleL*//





//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>//

//*** START of COMMENT OUT [Alerts]



//testStartYear = input(2018, "Backtest Start Year",minval=1980)

//testStartMonth = input(6, "Backtest Start Month",minval=1,maxval=12)

//testStartDay = input(12, "Backtest Start Day",minval=1,maxval=31)

//testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)



//testStopYear = 9999 //input(9999, "Backtest Stop Year",minval=1980)

//testStopMonth = 12 // input(12, "Backtest Stop Month",minval=1,maxval=12)

//testStopDay = 31 //input(31, "Backtest Stop Day",minval=1,maxval=31)

//testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0)



//testPeriod = time >= testPeriodStart and time <= testPeriodStop ? true : false



//*** END of COMMENT OUT [Alerts]

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//



// - INPUTS END





gold = #FFD700

AQUA = #00FFFFFF

BLUE = #0000FFFF

RED  = #FF0000FF

LIME = #00FF00FF

GRAY = #808080FF



// - FUNCTIONS



// - variant(type, src, len, gamma)

// Returns MA input selection variant, default to SMA if blank or typo.



// SuperSmoother filter

// © 2013  John F. Ehlers

variant_supersmoother(src,len) =>

    a1 = exp(-1.414*3.14159 / len)

    b1 = 2*a1*cos(1.414*3.14159 / len)

    c2 = b1

    c3 = (-a1)*a1

    c1 = 1 - c2 - c3

    v9 = 0.0

    v9 := c1*(src + nz(src[1])) / 2 + c2*nz(v9[1]) + c3*nz(v9[2])

    v9



variant_smoothed(src,len) =>

    v5 = 0.0

    v5 := na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len

    v5



variant_zerolagema(src,len) =>

    ema1 = ema(src, len)

    ema2 = ema(ema1, len)

    v10 = ema1+(ema1-ema2)

    v10



variant_doubleema(src,len) =>

    v2 = ema(src, len)

    v6 = 2 * v2 - ema(v2, len)

    v6



variant_tripleema(src,len) =>

    v2 = ema(src, len)

    v7 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len)               // Triple Exponential

    v7



//calc Laguerre

variant_lag(p,g) =>

    L0 = 0.0

    L1 = 0.0

    L2 = 0.0

    L3 = 0.0

    L0 := (1 - g)*p+g*nz(L0[1])

    L1 := -g*L0+nz(L0[1])+g*nz(L1[1])

    L2 := -g*L1+nz(L1[1])+g*nz(L2[1])

    L3 := -g*L2+nz(L2[1])+g*nz(L3[1])

    f = (L0 + 2*L1 + 2*L2 + L3)/6

    f



// return variant, defaults to SMA

variant(type, src, len, g) =>

    type=="EMA"     ? ema(src,len) :

      type=="WMA"   ? wma(src,len):

      type=="VWMA"  ? vwma(src,len) :

      type=="SMMA"  ? variant_smoothed(src,len) :

      type=="DEMA"  ? variant_doubleema(src,len):

      type=="TEMA"  ? variant_tripleema(src,len):

      type=="LAGMA" ? variant_lag(src,g) :

      type=="HullMA"? wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len))) :

      type=="SSMA"  ? variant_supersmoother(src,len) :

      type=="ZEMA"  ? variant_zerolagema(src,len) :

      type=="TMA"   ? sma(sma(src,len),len) :

                      sma(src,len)



// - /variant

// If have anchor specified, calculate the base multiplier, base on time in mins

//mult  = isintraday ? anchor==0 or interval<=0 or interval>=anchor or anchor>1440? 1 : round(anchor/interval) : 1

//mult := not isintraday?  1 : mult  // Only available Daily or less



// Anchor is a relative multiplier based on current TF.

mult = anchor>0 ? anchor : 1



// - FUNCTIONS END





// - Fast ATR QQE

//

Wilders_Period = RSILen * 2 - 1

//

Rsi = rsi(RSIsrc,RSILen)

RSIndex = ema(Rsi, SF)

AtrRsi = abs(RSIndex[1] - RSIndex)

MaAtrRsi = ema(AtrRsi, Wilders_Period)

DeltaFastAtrRsi = ema(MaAtrRsi,Wilders_Period) * QQEfactor

//

newshortband=  RSIndex + DeltaFastAtrRsi

newlongband= RSIndex - DeltaFastAtrRsi

longband = 0.0

shortband=0.0

trend = 0

longband:=RSIndex[1] > longband[1] and RSIndex > longband[1] ? max(longband[1],newlongband) : newlongband

shortband:=RSIndex[1] < shortband[1] and  RSIndex < shortband[1] ? min(shortband[1],newshortband) : newshortband

trend:=cross(RSIndex, shortband[1])? 1 : cross(longband[1], RSIndex) ? -1 : nz(trend[1],1)

FastAtrRsiTL = trend==1 ? longband : shortband





// - SERIES VARIABLES

// MA's

ma_fast    = variant(type1, srcclose, len1, gamma1)

ma_medium  = variant(type2, srcclose, len2, gamma2)

ma_slow    = variant(type3, srcclose, len3, gamma3)

// MA's

ma_fast_alt    = variant(type1, srcclose, len1*mult, gamma1)

ma_medium_alt  = variant(type2, srcclose, len2*mult, gamma2)

ma_slow_alt    = variant(type3, srcclose, len3*mult, gamma3)



// Get Direction From Medium Moving Average

direction = rising(ma_medium,3) ? 1 : falling(ma_medium,3) ? -1 : 0

altDirection = rising(ma_medium_alt,3) ? 1 : falling(ma_medium_alt,3) ? -1 : 0

//

// Find all the QQE Crosses

QQExlong  = 0, QQExlong := nz(QQExlong[1])

QQExshort = 0, QQExshort := nz(QQExshort[1])

QQExlong  := FastAtrRsiTL< RSIndex ? QQExlong+1 : 0

QQExshort := FastAtrRsiTL> RSIndex ? QQExshort+1 : 0

// Zero cross

QQEzlong  = 0, QQEzlong := nz(QQEzlong[1])

QQEzshort = 0, QQEzshort := nz(QQEzshort[1])

QQEzlong  := RSIndex>=50 ? QQEzlong+1 : 0

QQEzshort := RSIndex<50 ? QQEzshort+1 : 0

//

// Thresh Hold channel Crosses give the BUY/SELL alerts.

QQEclong  = 0, QQEclong := nz(QQEclong[1])

QQEcshort = 0, QQEcshort := nz(QQEcshort[1])

QQEclong  := RSIndex>(50+threshhold) ? QQEclong+1 : 0

QQEcshort := RSIndex<(50-threshhold) ? QQEcshort+1 : 0



//

// Check Filtering.

QQEflong = mult == 1 ? (not filter or (srcclose>ma_medium and ma_medium>ma_slow and ma_fast>ma_medium)) and (not dfilter or (direction>0 )) :

                       (not filter or (ma_medium>ma_medium_alt and srcclose>ma_fast and ma_fast>ma_medium)) and (not dfilter or (direction>0 and altDirection>0 and srcclose>ma_medium))

QQEfshort = mult == 1 ? (not filter or (srcclose<ma_medium and ma_medium<ma_slow and ma_fast<ma_medium)) and (not dfilter or (direction<0 )) :

                       (not filter or (ma_medium<ma_medium_alt and srcclose<ma_fast and ma_fast<ma_medium)) and (not dfilter or (direction<0 and altDirection<0 and srcclose<ma_medium))



QQExfilter = (not xfilter or  RSIndex>(50+threshhold) or RSIndex<(50-threshhold))

//

// Get final BUY / SELL alert determination

buy_ = 0, buy_ := nz(buy_[1])

sell_ = 0, sell_ := nz(sell_[1])



// Make sure Buy/Sell are non-repaint and occur after close signal.

buy_  := tradeSignal=="XC"? (QQEclong[1]==1 and QQEflong[1] ? buy_+1 : 0) :

         tradeSignal=="XQ"? (QQExlong[1]==1 and QQEflong[1] and QQExfilter[1]? buy_+1 : 0) :

         tradeSignal=="XZ"? (QQEzlong[1]==1 and QQEflong[1] ? buy_+1 : 0) :  0

sell_ := tradeSignal=="XC"? (QQEcshort[1]==1 and QQEfshort[1] ? sell_+1 : 0) :

         tradeSignal=="XQ"? (QQExshort[1]==1 and QQEfshort[1] and QQExfilter[1]? sell_+1 : 0) :

         tradeSignal=="XZ"? (QQEzshort[1]==1 and QQEfshort[1] ? sell_+1 : 0) : 0

//

// Find the first Buy/Sell in trend swing.

Buy = 0, Buy := nz(Buy[1])

Sell = 0, Sell := nz(Sell[1])

Buy := sell_>0 ? 0 : buy_==1 or Buy>0  ? Buy+1 : Buy

Sell := buy_>0 ? 0 : sell_==1 or Sell>0 ? Sell+1 : Sell



// Select First or all buy/sell alerts.

buy = ufirst ? Buy : buy_

sell = ufirst ? Sell : sell_



closeLong = 0, closeLong := nz(closeLong[1])

closeShort = 0, closeShort := nz(closeShort[1])

closeLong  := closeSignal=="XC" ? (QQEcshort==1 ? closeLong+1 : 0)  :

              closeSignal=="XQ" ? tradeSignal=="XQ" ? (QQExshort==1 ? closeLong+1 : 0) : ((QQExshort==1 or QQEzshort or QQEcshort) ? closeLong+1 : 0)  :

              closeSignal=="XZ" ? (QQEzshort==1 ? closeLong+1 : 0)  : 0

closeShort := closeSignal=="XC" ? (QQEclong==1 ? closeShort+1 : 0)  :

              closeSignal=="XQ" ? tradeSignal=="XQ" ? (QQExlong==1 ? closeShort+1 : 0) : ((QQExlong==1  or QQEzlong or QQEclong==1) ? closeShort+1 : 0)  :

              closeSignal=="XZ" ? (QQEzlong==1 ? closeShort+1 : 0)  : 0





tradestate = 0, tradestate := nz(tradestate[1])

tradestate := tradestate==0 ? (buy==1 ? 1 : sell==1 ? 2 : 0) : (tradestate==1 and closeLong==1) or (tradestate==2 and closeShort==1)? 0 : tradestate



isLong  = change(tradestate) and tradestate==1

isShort =  change(tradestate) and tradestate==2

isCloseLong =  change(tradestate) and tradestate==0 and nz(tradestate[1])==1

isCloseShort =  change(tradestate) and tradestate==0 and nz(tradestate[1])==2



// - SERIES VARIABLES END



// - PLOTTING

// Ma's

tcolor = direction<0?red:green

// ma1=plot(showAvgs?ma_fast:na, title="MA Fast", color=tcolor, linewidth=1, transp=0)

ma2=plot(showAvgs?ma_medium:na, title="MA Medium Fast", color=tcolor, linewidth=2, transp=0)

// ma3=plot(showAvgs?ma_slow:na, title="MA Slow", color=tcolor, linewidth=1, transp=0)

// fill(ma1,ma3,color=tcolor,transp=90)



// Ma's

altTcolor=altDirection<0?red:green

barcolor(altDirection<0? red:green)

ma4=plot(showAvgs and mult>1?ma_fast_alt:na, title="MA Fast", color=altTcolor, linewidth=1, transp=0)

ma5=plot(showAvgs and mult>1?ma_medium_alt:na, title="MA Medium Fast", color=altTcolor, linewidth=2, transp=0)

ma6=plot(showAvgs and mult>1?ma_slow_alt:na, title="MA Slow", color=altTcolor, linewidth=1, transp=0)

fill(ma4,ma6,color=altTcolor,transp=90)



// Color Changes

turned_aqua = altTcolor[1] == red and altTcolor == green

turned_blue = altTcolor[1] == green and altTcolor == red

take_profit_long = ma_slow > ma_fast_alt and ma_slow > ma_slow_alt and tcolor[1] == green and tcolor == red

take_profit_short = ma_slow < ma_fast_alt and ma_slow < ma_slow_alt and tcolor[1] == red and tcolor == green

// plotshape(turned_aqua, title="MA's Green Buy", style=shape.triangleup, location=location.belowbar, text="Long", color=green, transp=20, size=size.normal)

// plotshape(turned_blue, title="MA's Red Sell", style=shape.triangledown, location=location.abovebar, text="Short", color=red, transp=20, size=size.normal)

// plotshape(take_profit_long, title="Take Profit Long", style=shape.triangledown, location=location.abovebar, text="Take Profit Long", color=purple, transp=20, size=size.tiny)

// plotshape(take_profit_short, title="Take Profit Short", style=shape.triangleup, location=location.belowbar, text="Take Profit Short", color=purple, transp=20, size=size.tiny)



strategy.entry("Long", strategy.long, when=turned_aqua and window)

strategy.entry("short", strategy.short, when=turned_blue and window)



entered_long = strategy.position_size[1] <= 0 and strategy.position_size > 0

entered_short = strategy.position_size[1] >= 0 and strategy.position_size < 0

long_tp_count = 0

long_tp_count := entered_long ? 0 : take_profit_long ? long_tp_count[1] + 1 : long_tp_count[1]

short_tp_count = 0

short_tp_count := entered_short ? 0 : take_profit_short ? short_tp_count[1] + 1 : short_tp_count[1]



// take_off_long = long_tp_count == 0 ? tp1_perc : long_tp_count == 1 ? tp2_perc : na

// take_off_short = short_tp_count == 0 ? tp1_perc : short_tp_count == 1 ? tp2_perc : na



long_tp1_qty = na

long_tp2_qty = na

short_tp1_qty = na

short_tp2_qty = na



long_tp1_qty := entered_long ? strategy.position_size * tp1_perc : long_tp1_qty[1]

long_tp2_qty := entered_long ? strategy.position_size * tp2_perc : long_tp2_qty[1]



short_tp1_qty := entered_short ? -strategy.position_size * tp1_perc : short_tp1_qty[1]

short_tp2_qty := entered_short ? -strategy.position_size * tp2_perc : short_tp2_qty[1]



long_sl_level = sl_perc == 0 ? na : strategy.position_avg_price * (1 - sl_perc)

short_sl_level = sl_perc == 0 ? na : strategy.position_avg_price * (1 + sl_perc)



strategy.order("LTP1", strategy.short, qty=long_tp1_qty, when=strategy.position_size > 0 and take_profit_long and long_tp_count[1]==0 and not turned_blue)

strategy.order("LTP2", strategy.short, qty=long_tp2_qty, when=strategy.position_size > 0 and take_profit_long and long_tp_count[1]==1 and not turned_blue)



strategy.order("STP1", strategy.long, qty=short_tp1_qty, when=strategy.position_size < 0 and take_profit_short and short_tp_count[1]==0 and not turned_aqua)

strategy.order("STP2", strategy.long, qty=short_tp2_qty, when=strategy.position_size < 0 and take_profit_short and short_tp_count[1]==1 and not turned_aqua)



strategy.exit("L-SL", "Long", stop=long_sl_level)

strategy.exit("S-SL", "Short", stop=short_sl_level)



// SL PLOTS

// --------

plot(strategy.position_size > 0  ? long_sl_level : na, color=red, style=linebr, title="Long Stop")

plot(strategy.position_size < 0  ? short_sl_level : na, color=maroon, style=linebr, title="Short Stop")



// ALERTS (STUDY ONLY)

alertcondition(turned_aqua, title="Long", message="Ma's Turned Green")

alertcondition(turned_blue, title="Short", message="Ma's Turned Red")

alertcondition(take_profit_long, title="Take Profit Long", message="Take Profit Long")

alertcondition(take_profit_short, title="Take Profit Short", message="Take Profit Short")

alertcondition(isLong,  title="QQEX Long", message="QQEX LONG")  // use "Once per Bar" option

alertcondition(isShort, title="QQEX Short", message="QQEX SHORT") // use "Once per Bar" option

alertcondition(isCloseLong, title="QQEX Close Long", message="QQEX CLOSE LONG") // use "Once per Bar Close" option

alertcondition(isCloseShort, title="QQEX Close Short", message="QQEX CLOSE SHORT") // use "Once per Bar Close" option



// show only when alert condition is met and bar closed.

plotshape(isLong or isShort,title= "Cross Alert Completed", location=location.bottom, color=isShort?red:green, transp=0, style=shape.circle,size=size.auto,offset=0)

plotshape(isCloseShort[1] or isCloseLong[1],title= "Close Order", location=location.top, color=isCloseShort[1]?red:green, transp=0, style=shape.square,size=size.auto,offset=-1)





// Test Plots

// ---------

// plot(long_tp_count)

// plot(short_tp_count, color=red)

//EOF



Thêm nữa