英文:
How to reset correctly my trades account in Pine Script DCA strategy?
问题
我正在探索在Pine Script V5中基于DCA(定投策略)模型创建回测的可能性。我已经尝试了几天,试图找到解决这个看似简单的问题的方法。
在这个测试策略中,使用了5个安全订单和1个基础订单(主订单)。进入条件是CLOSE > EMA(200)。订单被放置在市场上,计算平均入场价格,并根据平均入场价格计算止损。问题出现在订单关闭后。实际上,关闭仓位后,算法应该返回到一个新的入场条件,并从基础订单重新开始。但实际情况是,如果,例如,3个订单或4个订单已关闭,算法会继续开立新的安全订单,即使在关闭后(实际上应该停止并等待新的入场条件,从基础订单重新开始)。
有人知道解决方法吗?谢谢社区。
//@version=5
strategy("StackOverflow Issue",
overlay = true,
default_qty_type = strategy.percent_of_equity,
default_qty_value = 100,
currency = currency.EUR,
initial_capital = 1000,
pyramiding = 5,
commission_type = strategy.commission.percent,
commission_value = 0.07,
process_orders_on_close = true
)
ema = ta.ema(close, 200)
condition_open_long = close > ema
SAFETYORDERS = 5
drop = 1
SL = 1.00
TP = 5.00
LONG_CONDITION = condition_open_long==true and strategy.opentrades==0
var float mainorder = 0
var float dca1 = 0
var float dca2 = 0
var float dca3 = 0
var float dca4 = 0
var float dca5 = 0
var float pe = 0
var float dcasl = 0
var float baseorder = 0
var float safetyorder = 0
var float averageprice = 0
if (LONG_CONDITION==true and SAFETYORDERS == 5)
// 基础多单订单
mainorder := close
lot_base = strategy.equity/mainorder
strategy.order(id = "BASE-ORDER", direction = strategy.long, qty = lot_base, limit = mainorder)
// DCA 1 订单
dca1 := mainorder - (mainorder * drop / 100)
lot_dca = strategy.equity / dca1
strategy.order(id="L1", direction = strategy.long, qty = lot_dca, limit = dca1)
// DCA 2 订单
dca2 := dca1 - (dca1 * drop / 100)
lot_dca2 = strategy.equity / dca2
strategy.order(id="L2", direction = strategy.long, qty = lot_dca2, limit = dca2)
// DCA 3 订单
dca3 := dca2 - (dca2 * drop / 100)
lot_dca3 = strategy.equity / dca3
strategy.order(id="L3", direction = strategy.long, qty = lot_dca3, limit = dca3)
// DCA 4 订单
dca4 := dca3 - (dca3 * drop / 100)
lot_dca4 = strategy.equity / dca4
strategy.order(id="L4", direction = strategy.long, qty = lot_dca4, limit = dca4)
// DCA 5 订单
dca5 := dca4 - (dca4 * drop / 100)
lot_dca5 = strategy.equity / dca5
strategy.order(id="L5", direction = strategy.long, qty = lot_dca5, limit = dca5)
averageprice := (mainorder + dca1 + dca2 + dca3 + dca4 + dca5) / 6
dcasl := averageprice - (averageprice * SL / 100)
if (dcasl)
strategy.exit(id="CL1", from_entry = "BASE-ORDER", stop = dcasl)
strategy.exit(id="CL2", from_entry = "L1", stop = dcasl)
strategy.exit(id="CL3", from_entry = "L2", stop = dcasl)
strategy.exit(id="CL4", from_entry = "L3", stop = dcasl)
strategy.exit(id="CL5", from_entry = "L4", stop = dcasl)
strategy.exit(id="CL6", from_entry = "L5", stop = dcasl)
以上是你提供的Pine Script代码的翻译部分。
英文:
I am exploring the possibility of creating a backtesting based on a DCA (Dollar Cost Average) model in Pine Script V5. I have been trying for days to find a solution to this seemingly easy problem.
In this test strategy, 5 safety orders + 1 base order (main order) are used. The entry condition is CLOSE > EMA (200). The orders are placed on the market, the average entry price is calculated and the stop loss is calculate on the average entry price. What happens is really strange. The algorithm executes the orders and closes them correctly, the problem arises after the orders are closed. In fact, having closed the positions the algorithm should return to a new entry condition and restart from the Base Order. What happens instead is that if, for example, 3 orders or 4 orders are closed, the algorithm continues to open new safety orders even after closing (when instead it should stop and wait for a new entry condition, restarting from the BASE order).
Does anyone know of a solution? Thanks community.
//@version=5
strategy("StackOverflow Issue",
overlay = true,
default_qty_type = strategy.percent_of_equity,
default_qty_value = 100,
currency = currency.EUR,
initial_capital = 1000,
pyramiding = 5,
commission_type = strategy.commission.percent,
commission_value = 0.07,
process_orders_on_close = true
)
ema = ta.ema(close, 200)
condition_open_long = close > ema
SAFETYORDERS = 5
drop = 1
SL = 1.00
TP = 5.00
LONG_CONDITION = condition_open_long==true and strategy.opentrades==0
var float mainorder = 0
var float dca1 = 0
var float dca2 = 0
var float dca3 = 0
var float dca4 = 0
var float dca5 = 0
var float pe = 0
var float dcasl = 0
var float baseorder = 0
var float safetyorder = 0
var float averageprice = 0
if (LONG_CONDITION==true and SAFETYORDERS == 5)
// BASE LONG ORDER
mainorder := close
lot_base = strategy.equity/mainorder
strategy.order(id = "BASE-ORDER", direction = strategy.long, qty = lot_base, limit = mainorder)
// DCA 1 ORDER
dca1 := mainorder - (mainorder * drop / 100)
lot_dca = strategy.equity / dca1
strategy.order(id="L1", direction = strategy.long, qty = lot_dca, limit = dca1)
// DCA 2 ORDER
dca2 := dca1 - (dca1 * drop / 100)
lot_dca2 = strategy.equity / dca2
strategy.order(id="L2", direction = strategy.long, qty = lot_dca2, limit = dca2)
// DCA 3 ORDER
dca3 := dca2 - (dca2 * drop / 100)
lot_dca3 = strategy.equity / dca3
strategy.order(id="L3", direction = strategy.long, qty = lot_dca3, limit = dca3)
// DCA 4 ORDER
dca4 := dca3 - (dca3 * drop / 100)
lot_dca4 = strategy.equity / dca4
strategy.order(id="L4", direction = strategy.long, qty = lot_dca4, limit = dca4)
// DCA 5 ORDER
dca5 := dca4 - (dca4 * drop / 100)
lot_dca5 = strategy.equity / dca5
strategy.order(id="L5", direction = strategy.long, qty = lot_dca5, limit = dca5)
averageprice := (mainorder + dca1 + dca2 + dca3 + dca4 + dca5) / 6
dcasl := averageprice - (averageprice * SL / 100)
if (dcasl)
strategy.exit(id="CL1", from_entry = "BASE-ORDER", stop = dcasl)
strategy.exit(id="CL2", from_entry = "L1", stop = dcasl)
strategy.exit(id="CL3", from_entry = "L2", stop = dcasl)
strategy.exit(id="CL4", from_entry = "L3", stop = dcasl)
strategy.exit(id="CL5", from_entry = "L4", stop = dcasl)
strategy.exit(id="CL6", from_entry = "L5", stop = dcasl)
答案1
得分: 1
当执行限价订单命令时,它们会保留在图表上,直到被执行或您使用strategy.cancel(id required)
/ strategy.cancel_all()
命令明确取消它们。在您的截图中,您可以看到策略在第一个柱上放置了5个安全订单(用绿色箭头标记),但价格已经达到了限价水平,其中2个订单只在2个柱后执行(红色箭头)。
您的意图是什么?如果您想取消在以前的蜡烛上放置在图表上的待处理安全订单,可以使用以下代码:
if myCancelCondition // 仅取消限价订单,以保留限价退出
strategy.cancel("L1")
strategy.cancel("L2")
strategy.cancel("L3")
strategy.cancel("L4")
strategy.cancel("L5")
另外,默认的close_entries_rule=
参数情况下,您的退出命令不会匹配给定的进场订单,而是关闭最早开放的订单。如果qty=
进场和退出不匹配,您可能会看到相同进场订单的多次退出,或一个退出命令关闭多个进场订单。要以任意顺序关闭订单并匹配ID,请使用strategy()
函数的close_entries_rule = "ANY"
参数:
strategy(..., close_entries_rule = "ANY")
英文:
When you execute limit order commands, they remain on the chart until they are filled or you explicitly cancel them with the strategy.cancel(id required)
/ strategy.cancel_all()
commands. In your screenshot, you can see that the strategy has placed 5 safety orders on the first bar (marked with a green arrow), but the price has reached the limit levels and 2 of them were executed only 2 bars later (red arrow).
What's your intention here? If you would like to cancel pending safety orders that were placed on the chart on previous candles, use:
if myCancelCondition // Cancel only limit entries, so limit exits remain
strategy.cancel("L1")
strategy.cancel("L2")
strategy.cancel("L3")
strategy.cancel("L4")
strategy.cancel("L5")
Also, with the default close_entries_rule=
parameter, your exit commands will not match the given entry, but will close the earliest open order. In case qty=
entry and exit do not match, you may see multiple exits of the same entry order or one exit closing multiple entry orders. To close orders in any order and match the id, use the close_entries_rule = "ANY"
parameter of the strategy()
function:
strategy(..., close_entries_rule = "ANY")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论