You are on page 1of 8

// This source code is subject to the terms of the Mozilla Public License 2.

0 at
https://mozilla.org/MPL/2.0/
// © liaodinghai

//@version=5
strategy(title='饥饿者~01', overlay=true,
pyramiding=0, default_qty_type=strategy.cash,
default_qty_value=1, initial_capital=100,
currency=currency.USD, commission_value=0.05,
commission_type=strategy.commission.percent,
process_orders_on_close=true)
//对上面这段话的解释:策略标题(名字)“”,显示在图表(主图),pyramiding=0 只能在同一方向上开
单,......

//-------------- fetch user inputs ------------------


gain = input.float(title="Kalman Gain:", defval=100.0, minval=1, maxval=10000.0,
step=1)
src = input(defval=close, title='Source:')

stopPercentBase = input.float(title='Beginning Approach(%)', defval=5.0,


minval=0.1, maxval=30.0, step=0.1)
stopPercentMin = input.float(title='Final Approach(%)', defval=1.0, minval=0.1,
maxval=30.0, step=0.1)
downStep = input.float(title='Approach Decrease Step', defval=0.001, minval=0.0,
maxval = 5, step=0.001)
//stopPercentDeviation = input.float(title="Approach Deviation", defval=1.0,
minval=0.1, maxval = 5.0, step=0.1)

baseOrderQty = input.float(title="Base Order Quantity", defval=100.0, minval=0.001)


maxOrderCount = input.int(title="Max Safe Order Attemp", defval=4, minval=1)
priceDeviation = input.float(title="Safe Order Deviation", defval=3, minval=1.0,
step=0.1)
profitDeviation = input.float(title="Profit Deviation", defval=1.0, minval=1.0,
maxval=10, step=0.1)
maxTakeProfit = input.float(title="Max Take Profit(%)", defval=25.0, maxval=100,
step=0.1)
maxOrderQty = input.float(title="Max Order Quantity", defval=10000.0, minval=0.01)

baseTP1 = input.float(title="TP1(%)", defval=1.0, minval=0.0, maxval=100.0,


step=0.1, inline="0")
qt1 = input.int(title="QT1(%):", defval=40, minval=1, maxval=100, step=5,
inline="0")

baseTP2 = input.float(title="TP2(%)", defval=3.0, minval=0.0, maxval=100.0,


step=0.1, inline="1")
qt2 = input.int(title="QT2(%):", defval=30, minval=1, maxval=100, step=5,
inline="1")

baseTP3 = input.float(title="TP3(%)", defval=5.0, minval=0.0, maxval=100.0,


step=0.1, inline="2")
qt3 = input.int(title="QT3(%):", defval=30, minval=1, maxval=100, step=5,
inline="2")

initialStopLoss = input.float(title="Stop Loss(%)", defval=0.0, minval=0.0,


maxval=100.0, step=0.1)

longEntry = input.bool(defval=true, title= 'Long Entry', inline="3")


shortEntry = input.bool(defval=true, title='Short Entry', inline="3")

useSafeStop2 = input.bool(defval = true, title="Safe Stop After TP2", inline="6")


useSafeStop1 = input.bool(defval = false, title="Safe Stop After TP1", inline="6")

//---------- backtest range setup ------------


fromDay = input.int(defval = 1, title = "From Date:", minval = 1, maxval = 31,
inline="4")
fromMonth = input.int(defval = 1, title = "/", minval = 1, maxval = 12, inline="4")
fromYear = input.int(defval = 2021, title = "/", minval = 2010, inline="4")
toDay = input.int(defval = 30, title = "To__ Date:", minval = 1, maxval = 31,
inline="5")
toMonth = input.int(defval = 12, title = "/", minval = 1, maxval = 12,
inline="5")
toYear = input.int(defval = 2022, title = "/", minval = 2010, inline="5")

//------------ time interval setup -----------


start = timestamp(fromYear, fromMonth, fromDay, 00, 00) // backtest start
window
finish = timestamp(toYear, toMonth, toDay, 23, 59) // backtest finish
window
window() => time >= start and time <= finish ? true : false // create function
"within window of time"

//------- define the order comments ------


enterLongComment = ""
exitLongComment = ""

enterShortComment = ""
exitShortComment = ""

longTPSL = ""
longTP = ""
longSL = ""

shortTPSL = ""
shortTP = ""
shortSL = ""

//--------- Define global variables -----------


var bool long = true
var bool stoppedOutLong = false
var bool stoppedOutShort = false
var float kf = 0.0
var float velo = 0.0

var float orderQty = baseOrderQty


var float stopLoss = initialStopLoss
var bool isProfit = false
var int barindex = 1
var int winCounter = 0
var int winCounterBuffer = 0
var int failCounter = 0

var float tp1 = baseTP1


var float tp2 = baseTP2
var float tp3 = baseTP3
var bool isTakeTP1 = false
var bool isTakeTP2 = false
var bool isTakeTP3 = false
var bool isLastProfit = true

var float stopPercentMax = stopPercentBase


var float stopPercent = stopPercentBase
var float stopLine = 0.0

var labelColor = color.blue

//------ kalman filter calculation --------


dk = src - nz(kf[1], src)
smooth = nz(kf[1], src) + dk * math.sqrt(gain / 10000 * 2)
velo := nz(velo[1], 0) + gain / 10000 * dk
kf := smooth + velo

//--------- calculate the loft stopLoss line ---------


//stopPercentMax := isLastProfit ? stopPercentBase : (stopPercentBase *
stopPercentDeviation)

if long == true
stopLine := kf - (kf * (stopPercent / 100))

if long[1] == true and stopLine <= stopLine[1]


stopLine := stopLine[1]
else if (long[1] == true)
stopPercent := stopPercent - downStep
if(stopPercent < stopPercentMin)
stopPercent := stopPercentMin

if(kf < stopLine)


long := false
stopPercent := stopPercentMax
stopLine := kf + (kf * (stopPercent / 100))

else
stopLine := kf + (kf * (stopPercent / 100))

if long[1] == false and stopLine >= stopLine[1]


stopLine := stopLine[1]
else if(long[1] == false)
stopPercent := stopPercent - downStep
if(stopPercent < stopPercentMin)
stopPercent := stopPercentMin

if(kf > stopLine)


long := true
stopPercent := stopPercentMax
stopLine := kf - (kf * (stopPercent / 100))

//------------------- determine buy and sell points ---------------------


buySignall = window() and long and (not stoppedOutLong)
sellSignall = window() and (not long) and (not stoppedOutShort)
if longEntry and shortEntry

if buySignall and baseTP1 <= 0.0

if strategy.position_size < 0
if close < strategy.position_avg_price
isLastProfit := true
else if strategy.position_size == 0
if strategy.wintrades > winCounter //strategy.wintrades[ barindex ]
isLastProfit := true
else
isLastProfit := false

else if sellSignall and baseTP1 <= 0.0

if strategy.position_size > 0
if close > strategy.position_avg_price
isLastProfit := true
else if strategy.position_size == 0
if strategy.wintrades > winCounter //strategy.wintrades[ barindex ]
isLastProfit := true
else
isLastProfit := false

else if isTakeTP2 == true


isLastProfit := true
else
isLastProfit := false

else if longEntry
if sellSignall
winCounterBuffer := winCounter
if buySignall
if winCounter > winCounterBuffer
isLastProfit := true
else
isLastProfit := false

else if shortEntry
if buySignall
winCounterBuffer := winCounter
if sellSignall
if winCounter > winCounterBuffer
isLastProfit := true
else
isLastProfit := false

//------------- set the deviations ------------


var float maxOrderSize = (baseOrderQty * math.pow(priceDeviation, maxOrderCount -
1))

if buySignall or sellSignall

if isLastProfit == false

orderQty := orderQty * priceDeviation

tp1 := tp1 * profitDeviation


tp2 := tp2 * profitDeviation
tp3 := tp3 * profitDeviation

tp1 := math.min(tp1, maxTakeProfit)


tp2 := math.min(tp2, maxTakeProfit)
tp3 := math.min(tp3, maxTakeProfit)

if orderQty > maxOrderSize


failCounter := failCounter + 1
orderQty := baseOrderQty
tp1 := baseTP1
tp2 := baseTP2
tp3 := baseTP3

else
orderQty := baseOrderQty
tp1 := baseTP1
tp2 := baseTP2
tp3 := baseTP3

// ----------------- put debug labels -------------------


if orderQty == maxOrderSize
labelColor := color.red
else
labelColor := isLastProfit ? color.lime : color.yellow

if longEntry and shortEntry


if buySignall or sellSignall
label.new( x=bar_index, y=high, text="Qty:"+str.tostring(math.min(orderQty,
maxOrderQty))+" | Worst Case:"+str.tostring(failCounter) ,color = labelColor )
else if longEntry
if buySignall
label.new( x=bar_index, y=high, text="Qty:"+str.tostring(math.min(orderQty,
maxOrderQty))+" | Worst Case:"+str.tostring(failCounter) ,color = labelColor )
else if shortEntry
if sellSignall
label.new( x=bar_index, y=high, text="Qty:"+str.tostring(math.min(orderQty,
maxOrderQty))+" | Worst Case:"+str.tostring(failCounter) ,color = labelColor )

//---------- execute the strategy -----------------


nz(orderQty, baseOrderQty)

if longEntry and shortEntry

if long
strategy.close_all( when = buySignall, comment = exitShortComment)
strategy.entry("LONG", strategy.long, when = buySignall,
qty=math.min(orderQty, maxOrderQty), comment = enterLongComment)
stoppedOutLong := true
stoppedOutShort := false

else
strategy.close_all(when=sellSignall, comment = exitLongComment)
strategy.entry("SHORT", strategy.short, when = sellSignall,
qty=math.min(orderQty, maxOrderQty), comment = enterShortComment)
stoppedOutLong := false
stoppedOutShort := true

else if(longEntry)
strategy.entry("LONG", strategy.long, when = buySignall,
qty=math.min(orderQty, maxOrderQty), comment = enterLongComment)
strategy.close("LONG", when = sellSignall, comment = exitLongComment)
if long
stoppedOutLong := true
stoppedOutShort := false
else
stoppedOutLong := false
stoppedOutShort := true

else if(shortEntry)
strategy.entry("SHORT", strategy.short, when = sellSignall,
qty=math.min(orderQty, maxOrderQty), comment = enterShortComment)
strategy.close("SHORT", when = buySignall, comment = exitShortComment)
if not long
stoppedOutShort := true
stoppedOutLong := false
else
stoppedOutShort := false
stoppedOutLong := true

//--------- calculate the TP/SL entries -----------


longProfitPrice1 = strategy.position_avg_price * (1 + tp1 * 0.01)
longProfitPrice2 = strategy.position_avg_price * (1 + tp2 * 0.01)
longProfitPrice3 = strategy.position_avg_price * (1 + tp3 * 0.01)

shortProfitPrice1 = strategy.position_avg_price * (1 - tp1 * 0.01)


shortProfitPrice2 = strategy.position_avg_price * (1 - tp2 * 0.01)
shortProfitPrice3 = strategy.position_avg_price * (1 - tp3 * 0.01)

longStopPrice = strategy.position_avg_price * (1 - stopLoss * 0.01)


shortStopPrice = strategy.position_avg_price * (1 + stopLoss * 0.01)

shortSafeStopPrice2 = strategy.position_avg_price * (1 - 0.2 * 0.01)


longSafeStopPrice2 = strategy.position_avg_price * (1 + 0.2 * 0.01)

longSafeStopPrice1 = stopLine
shortSafeStopPrice1 = stopLine

//----------- calculate TP quantity values -----------


takeQty1 = math.min(orderQty, maxOrderQty) * qt1 / 100
takeQty2 = math.min(orderQty, maxOrderQty) * qt2 / 100
takeQty3 = math.min(orderQty, maxOrderQty) * qt3 / 100

//----------------- take profit and stop loss processes -----------------


if strategy.position_size > 0

if close > longProfitPrice1 and tp1 > 0 and isTakeTP1 == false


strategy.close(id="LONG", qty=takeQty1, comment = "longTP 1")
isTakeTP1 := true

if close > longProfitPrice2 and tp2 > 0 and isTakeTP2 == false


strategy.close(id="LONG", qty=takeQty2, comment = "longTP 2")
isTakeTP2 := true

if close > longProfitPrice3 and tp3 > 0 and isTakeTP3 == false


strategy.close(id="LONG", qty=takeQty3, comment = "longTP 3")
isTakeTP3 := true

if isTakeTP2 == true and useSafeStop2


strategy.exit(id="LONG", stop=longSafeStopPrice2, comment = "Long Safe
Stop2")
if isTakeTP1 == true and useSafeStop1
strategy.exit(id="LONG", stop=longSafeStopPrice1, comment = "Long Safe
Stop1")

if strategy.position_size < 0

if close < shortProfitPrice1 and tp1 > 0 and isTakeTP1 == false


strategy.close(id="SHORT", qty=takeQty1, comment = "Short TP 1")
isTakeTP1 := true

if close < shortProfitPrice2 and tp2 > 0 and isTakeTP2 == false


strategy.close(id="SHORT", qty=takeQty2, comment = "Short TP 2")
isTakeTP2 := true

if close < shortProfitPrice3 and tp3 > 0 and isTakeTP3 == false


strategy.close(id="SHORT", qty=takeQty3, comment = "Short TP 3")
isTakeTP3 := true

if isTakeTP2 == true and useSafeStop2


strategy.exit(id="SHORT", stop=shortSafeStopPrice2, comment = "Short Safe
Stop2")
if isTakeTP1 == true and useSafeStop1
strategy.exit(id="SHORT", stop=shortSafeStopPrice1, comment = "Short Safe
Stop1")

if(initialStopLoss>0.0)
if ( strategy.position_size > 0 )
strategy.exit(id="LONG", stop=longStopPrice, comment = "Long Stop Loss")

else if ( strategy.position_size < 0 )


strategy.exit(id="SHORT", stop=shortStopPrice, comment = "Short Stop
Loss")

if buySignall or sellSignall

isTakeTP1 := false
isTakeTP2 := false
isTakeTP3 := false

winCounter := strategy.wintrades

//------------- plot charts ---------------------


lineColor1 = long ? color.green : color.red
lineColor2 = long ? color.aqua : color.fuchsia

kalmanPlot = plot(kf, color=lineColor1, linewidth=3, title = "Kalman Filter")


stopPlot = plot(stopLine, color=lineColor2, linewidth=2, title = "Stop Loss Line")

You might also like