Мне нужна помощь с кодом простой стратегии, который я написал. Это мой 1-й код на нем. У меня проблема с кодом mon, написанным на PineScript.
PineScript неправильно рассчитывает мой SL, TP и размер количества, и я не могу понять, почему.
Моя стратегия такова: при наличии 4 зеленых свечей подряд после 1 красной свечи открывать длинную позицию на 5-й свече (неважно, красная она или зеленая).
цена SL = (цена закрытия 4-й зеленой свечи от красной свечи + цена открытия 2-й зеленой свечи от красной свечи)/2
Diff = Разница между ценой входа и ценой SL. Это значение в цене будет использоваться для расчета цены TP.
цена TP = цена входа + (2*Diff) «2» означает, что вознаграждение за риск равно 2, я рискую 1, чтобы выиграть 2.
Также я хочу рисковать 1% в каждой сделке с баланса моего счета. Например, если баланс моего счета составляет 200 000 долларов, я хочу рискнуть 2000 долларов. Итак, если разница (разница между ценой входа и ценой SL) составляет 2 доллара, я хочу купить 1000 единиц акций за ETH по цене 2000 долларов за 2 доллара. Основываясь на моем вознаграждении за риск, все мои убыточные сделки всегда должны составлять 1% от баланса моего счета, а все мои прибыльные сделки всегда должны составлять 2%. Но когда я смотрю на сделки, проценты ни за чем не следуют.
Но PineScript не делает этого должным образом. Он обнаруживает паттерн, которым я хочу торговать, и входит на 5-й свече, но точка выхода не работает должным образом ни SL, ни TP, ни количество.
Я не знаю, неверны ли мои инструкции SL или что-то в этом роде. Есть ли у вас какие-либо идеи ?
Это мой текущий код и см. ниже некоторые изображения сделок:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=5
strategy("4 Green Candle Strategy", overlay=true,shorttitle = "4GCS")
// 1. User Input //
i_rewardmulti = input.float(2.0, "Risk Reward", minval = 1.0, step = 0.5, group = "4 Green Candle Strategy Settings")
i_risk = input.float(1.0, "Percentage to risk per trade", minval = 0.1, step = 0.05, group = "4 Green Candle Strategy Settings")
ibtstarttime = input.time(title="Start Backtest", defval=timestamp("01 Jan 2022 00:00 +0000"), group="Backtest Period")
ibtendtime = input.time(title="End Backtest", defval=timestamp("01 Jan 2099"), group="Backtest Period")
// ---------------------------------------------------- Strategy Settings -----------------------------------------------//
// 2. Conditions of a valid setup //
ValidSetup = close[4] < open[4] and close[3] > close[4] and close[2] > close[3] and close[1] > close[2] and close > close[1] and barstate.isconfirmed
// 3. Confirmation of a valid setup //
ValidLong = ValidSetup and strategy.position_size==0 and barstate.isconfirmed
// 4. Calculation of TP, SL, balance risked and position size risked //
EntryPrice = close
long_SLprice = (close + open[2])*0.5
long_diff_EntryPrice_and_StopLossExitPrice = close - long_SLprice
long_TPprice = EntryPrice + (i_rewardmulti * long_diff_EntryPrice_and_StopLossExitPrice)
balance = (strategy.initial_capital + strategy.netprofit)
balance_limited = (balance > 0 ? balance : 0)
balance_risked = (i_risk/100) * balance
position_size_risked = (balance_risked/long_diff_EntryPrice_and_StopLossExitPrice)
// 5. Save of SL, TP and position size if a valid setup is detected //
var trade_entry = 0.0
var trade_SL = 0.0
var trade_TP = 0.0
var trade_direction = 0
// 6. Detection of a valid long and trigger alerts //
trade_entry := EntryPrice
trade_SL := long_SLprice
trade_TP := long_TPprice
trade_direction := 1
// 7. Enter a trade whenever a valid setup is detected //
if ValidLong
strategy.entry("Long", strategy.long, qty=position_size_risked)
// 8. Exit a trade whenever a TP or SL is hit //
if strategy.position_size > 0
strategy.exit("Long Exit", from_entry = "Long", limit= trade_TP, stop = trade_SL)
// 9. Draw trade data and Price action setup arrow //
plot (series = strategy.position_size !=0 and ValidLong ? trade_SL : na, title = "Trade Stop Price", color=color.red, style = plot.style_linebr)
plot (series = strategy.position_size !=0 and ValidLong ? trade_TP : na, title = "Trade TP Price", color=color.green, style = plot.style_linebr)
plotshape(series = ValidLong ? 1 : na, style =shape.triangleup, location = location.belowbar, color=color.green, title = "Bullish Setup")
// ------------------------------------------------------ End of Code -------------------------------------------------//
введите здесь описание изображения
Обычно в сделке, которая началась в 22:00 (22:00) после того, как были обнаружены 4 зеленые свечи после 1 красной свечи, на основе моей стратегии TP, она должна была выйти на уровне 1212,84 $ после того, как значение TP было 1,84 $, но выход по более высокой цене, чем это должно было быть сделано. И прибыль в процентах составляет 1,57%, когда она всегда должна быть 2%, и вы можете видеть ниже в убыточной сделке, процентная потеря составляет 0,12%, когда она всегда должна быть 1%.
Есть ли у вас какие-либо идеи о том, почему это работает должным образом? Есть ли ошибка в моем коде?
Спасибо, Ульрих
Я попытался изменить номер ссылки на свечу, например, свеча [2] на свечу [1], обнаружение пошло не так.
Вы пишете:
'Например, если баланс моего счета составляет 200 000 долларов, я хочу рискнуть 2000 долларов. Итак, если разница (разница между ценой входа и ценой SL) составляет 2 доллара, я хочу купить 1000 единиц акций за ETH. как 2000$/2$.'
Но чтобы купить 1000 единиц по 2000$, вам понадобится 2 000 000$.
Поскольку Pinescript знает, что у вас есть 200 000 долларов, он купит 100 единиц.
Расчет 2% для вашей выигрышной сделки основан на 1000 единицах, а не на 100.
Когда вы запускаете функцию strategy.exit()
со стоп-лоссом или TP-ордером, такой ордер выдается эмулятору брокера. Если предыдущий заказ уже выдан, он отменяет предыдущий заказ и выдает новый.
В вашем случае вы отправляете ордер каждый бар, чем strategy.position_size
больше, чем 0
, и для каждого ордера вы заново рассчитываете цену. Это означает, что каждый раз, когда вы выставляете ордер, цена close
и цена open[2]
разные (и опять же, вы выставляете их на каждом баре внутри сделки).
Например, вот скрипт, на котором ордер выдается только один раз после совершения сделки:
//@version=5
strategy("My strategy", overlay=true, margin_long=100, margin_short=100)
tp_price = close * 1.1
sl_price = close * 0.9
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
strategy.entry("Long", strategy.long)
strategy.exit("Exit Long", "Long", limit = tp_price, stop = sl_price)
И вот результат (цена TP на 10% выше цены close
при выполнении условия длинной позиции):
но если я немного изменю сценарий и буду запускать функцию порядка strategy.exit()
каждый раз, когда strategy.position_size
больше, чем 0
, это будет выглядеть так:
//@version=5
strategy("My strategy", overlay=true, margin_long=100, margin_short=100)
tp_price = close * 1.1
sl_price = close * 0.9
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
strategy.entry("Long", strategy.long)
if strategy.position_size > 0
strategy.exit("Exit Long", "Long", limit = tp_price, stop = sl_price)
Причина разницы в том, что он вычисляет close
цену на каждом баре, где strategy.position_size
больше, чем 0
:
Это длинное объяснение чрезвычайно простого исправления — просто запустите strategy.exit()
сразу после strategy.entry()
if ValidLong
strategy.entry("Long", strategy.long, qty=position_size_risked)
strategy.exit("Long Exit", from_entry = "Long", limit= trade_TP, stop = trade_SL)
Спасибо большое !объяснение понятное и на самом деле важное, так как позволяет понять почему так происходит.
Хорошая точка зрения ! Имеет смысл. Я исправляю свой код, и я посмотрю, как он пойдет. Спасибо