Write a semi-automatic trading tool by using the Pine language

in trading •  last year 

Although there are more and more traders who write programs for fully automated trading, the larger group of traders is still manual traders. In fact, manual subjective traders can also write small tools to assist them in their subjective trading. For example, sometimes you find a good entry position and plan to set a fixed stop loss and trailing profit on the initial position. Then dispense with the more energy-intensive things like subsequent market monitoring, follow your own established stop-loss and take-profit plan exactly, and let the program do the market monitoring for you. Stop loss for losing bets, trailing profit for winning bets to assist manual trading.

Parameter design

The strategy for designing such requirements by using the Pine language is very simple. The following parameters need to be designed to achieve the function according to the requirements:

  1. offset: When a trailing stop profit is triggered, the offset distance for offset the highest price and lowest price to delimit the stop profit line.
  2. limit: Parameters used to control - A. Initial base position to buy directly, B. Specified price to wait to buy, C. Do nothing.
  3. amount: The amount of orders placed when the base position is opened.
  4. loss: Stop loss points.
  5. targetOffset: The price difference that offsets the opening price when a trailing stop profit is triggered.
  6. minTick: The minimum unit of price fluctuation.
  7. direction: The direction of opening the base position.

Strategy design

/*backtest
start: 2022-09-24 00:00:00
end: 2022-09-27 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
args: [["v_input_1",20],["v_input_2",0],["v_input_4",50],["v_input_5",20],["RunMode",1,358374],["ZPrecision",0,358374],["XPrecision",3,358374]]
*/

strategy("Tracking loss and profit stopping entrustment", overlay = true)

varip targetPrice = na
varip high_lowPrice = na
varip isTrade = false 
varip isAlert = false
varip isAlertMinTick = false
varip isAlertFinished = false 

varip offset = input(30, "offset", "Tracking stop loss and stop profit offset")
varip limit = input(-1, "limit", "Initial opening price: - 1 means no opening, 0 means immediate opening, and other specific values are price limits")
varip amount = input(1, "amount", "amount of opening positions")
varip loss = input(30, "loss", "stop loss")
varip targetOffset = input(30, "targetOffset", "trigger tracking profit and loss stop offset")
varip minTick = input(1, "minTick", "the minimum unit of price fluctuation")
tradeType = input.string("long", "direction", tooltip="order direction, long: go long, short: go short", options=["long", "short"])

if not barstate.ishistory and not isAlertMinTick
    runtime.log("check whether syminfo.mintick is correct! syminfo.mintick:", syminfo.mintick, "#FF0000")
    if syminfo.mintick < minTick 
        runtime.error("system syminfo.mintick < minTick parameter", "#FF0000")
    isAlertMinTick := true 

if not barstate.ishistory and limit == -1 and not isAlert
    runtime.log("No open price is set, current limit is -1 (to prevent false openings, initial default limit is -1), openings are prohibited", "#FF0000")
    isAlert := true 

if isTrade and strategy.position_size == 0 and not isAlertFinished
    runtime.log("All order processes executed, position is 0", "#FF0000")
    isAlertFinished := true 

if not barstate.ishistory and not isTrade and limit != -1
    if limit == 0 
        strategy.entry("open", tradeType == "long" ? strategy.long : strategy.short, amount)
    else if limit > 0 
        strategy.entry("open", tradeType == "long" ? strategy.long : strategy.short, amount, limit=limit)
    
    if tradeType == "long"
        targetPrice := (limit == 0 ? close : limit) + targetOffset
    else 
        targetPrice := (limit == 0 ? close : limit) - targetOffset
    strategy.exit("exit", "open", amount, loss=loss, trail_price=targetPrice, trail_offset=offset)
    runtime.log("The price per point is:", syminfo.mintick, ", current close:", close)
    isTrade := true 

if ((close > targetPrice and strategy.position_size > 0) or (close < targetPrice and strategy.position_size < 0)) and not barstate.ishistory
    high_lowPrice := na(high_lowPrice) ? close : high_lowPrice
    if strategy.position_size > 0 
        high_lowPrice := close > high_lowPrice ? close : high_lowPrice
    else 
        high_lowPrice := close < high_lowPrice ? close : high_lowPrice

plot(targetPrice, "trail_price trigger line")    
plot(strategy.position_size!=0 ? high_lowPrice : na, "current highest/lowest price")
plot(strategy.position_size!=0 ? (strategy.position_size > 0 ? high_lowPrice-syminfo.mintick*offset : high_lowPrice+syminfo.mintick*offset) : na, "moving stop loss trigger line")

The design of the strategy is not complicated, but it needs to be set up as a "real-time price model", because the price should be monitored every moment.

5.png

Note that the stop loss is expressed in points (minTick) and the offset is also expressed in points (minTick). The offset of the targetOffset trailing stop profit trigger line is expressed in terms of price distance (for example, set to 30, which is RMB30 for distance). When the minTick is 1, 30 means RMB30 for distance.

This commission strategy is designed to allow not only initial base positions to go long, but also initial base positions to go short. Then the stop loss and trailing profit is handled in the short direction.

Let's demonstrate the design implementation as follows:

1. When the strategy is running, the base position will be opened and entered immediately, and then the stop loss and tracking stop profit will be set according to the parameters.

6.png

direction is set to long, limit parameter is set to 0, that is, let the strategy enter and go long immediately when it's running, amount is set to 1, that is, the strategy open a position of 1 contract.

7.png

2. Specify the limit parameter, specify the price of entry

Other parameter settings remain unchanged, except that the specified limit parameter price is: 1276

8.png

3. The default limit parameter is -1, which does not operate anything and prevents accidental opening of positions

9.png

THE END

When using the Pine language strategy, it is important to pay special attention to the minTick data. The exact number of price minTick in the system is related to the "pricing currency precision" in the parameter.

10.png

The parameter "Pricing Currency Accuracy" is set to 0, which means that the price data value is accurate to a single digit (i.e., 0 decimal places). Then the minimum price change unit is 1. Since some parameters are related to the exact number of minTicks, this needs extra attention.

OK, the above is the entire design of this semi-automatic commission strategy, although I also use it for real-bot trading. But such tools must also be used according to your own trading habits to understand, specific modifications, optimization can be carried out by your own. Here the strategy code is only for public sharing, exchange learning design and logic.

As we can see, the Pine language is very easy to use, and it's convenient and easy to learn. We can use the Pine language to design the tools we want quickly, without having to worry about complicated programming, and use the Pine language to make quantitative trading easier on FMZ Quantitative Trading Platform.

From: https://blog.mathquant.com/2022/10/24/write-a-semi-automatic-trading-tool-by-using-the-pine-language.html

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!