-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What is ctx.stop_trailing for? #24
Comments
Hi @none2003, The field stop_trailing will behave just like stop_trailing_pct, except the units are set in absolute price points. The reason the code isn't working is that the stop is created when the entry is created (i.e., ctx.buy_shares) and cannot be updated afterwards because each stop only applies to its associated entry. To support your case of dynamically updating the stop, I can add support for setting a Callable that would return the points amount based on the current context (e.g., ATR). In the meantime, you can determine if a stop is hit by checking ctx.long_pos() and ctx.high. Additionally, you can then update and save the stop threshold in ctx.session to achieve the trailing behavior. |
After considering this further, I have come to the conclusion that introducing support for dynamic stop values using Callables would make the API confusing. The desired behavior can already be achieved using the execution function. Because stop thresholds are intended to be static, I have implemented checks to prevent your example from failing silently. Instead, it will now throw an error. To achieve what you are after, you can reference this code:
Let me know if you need anything else! |
Hi @edtechre I tried your code, but it still doesn't work, no trade happens.
|
Whether a trade is made is going to depend on the data you're using for the backtest. My example uses the daily high price instead of close for updating the stop, and it placed trades for my dataset. But glad you have something working, thanks for sharing! |
I have a question about the timing of the trailing stop trigger in pyb. If ctx.buy_shares is executed along with ctx.stop_trailing_pct. My understanding is that pyb calculates a stop loss level for each bar, so question 1, this stop loss level is calculated based on what price minus stop_trailing_pct? high[-1]? Once the price of a bar falls below this stop level, then the stop loss will be triggered, so question 2, which of the ohlc specifically falls below the stop level and triggers the stop loss? Question 3, after the stop is triggered, is the timing for the order to be fulfilled at the moment it is triggered, or at the next bar? This is related to the code you provided above, in your code, the trailing stop order will be fulfilled at the next bar, rather than at the moment stop loss was trigged. Question 4, if it is at the next bar, which of the ohlc will be the price to fulfill tailing stop order? |
Hi @none2003,
Yes, high for long positions, and low for short positions.
Stop losses on long positions will check if the stop has fallen below the current bar's low price, high for short positions.
Using the built-in stops, the stop will be filled on the current bar when it is triggered, and will be filled at the stop value. See the _trigger_stop method in portfolio.py: https://github.com/edtechre/pybroker/blob/master/src/pybroker/portfolio.py#L1171 You could simulate the same fill price by setting ctx.sell_fill_price. |
Hi Ed,
After trying the Trailing Stop function in example (https://www.pybroker.com/en/latest/notebooks/8.%20Applying%20Stops.html), it was natural for me to want to implement an ATR Trailing Stop.
I saw an attribute "stop_trailing" in the ExecContext, and the documentation describes it as "Sets a trailing stop loss on a new pybroker.portfolio.Entry, where value is measured in points from entry price.", I'm a little confused here, in the case of long, will it stop when it is below the "highest market price" by a certain margin (percent/amount), like "stop_trailing_pct", or when it is below the "entry price/buy price" by a certain margin (percent/amount)?
I tried stop_trailing in following code, however, it seems it doesn't work, there is no trade been created, am I missing anything here?
the result.metrics_df:
name value
0 trade_count 0.00
1 initial_market_value 100000000.00
2 end_market_value 385076252.89
3 total_pnl 0.00
4 unrealized_pnl 285076252.89
5 total_return_pct 0.00
6 total_profit 0.00
7 total_loss 0.00
8 total_fees 0.00
9 max_drawdown -429843907.78
10 max_drawdown_pct -72.30
11 win_rate 0.00
12 loss_rate 0.00
13 winning_trades 0.00
14 losing_trades 0.00
15 avg_pnl 0.00
16 avg_return_pct 0.00
17 avg_trade_bars 0.00
18 avg_profit 0.00
19 avg_profit_pct 0.00
20 avg_winning_trade_bars 0.00
21 avg_loss 0.00
22 avg_loss_pct 0.00
23 avg_losing_trade_bars 0.00
24 largest_win 0.00
25 largest_win_pct 0.00
26 largest_win_bars 0.00
27 largest_loss 0.00
28 largest_loss_pct 0.00
29 largest_loss_bars 0.00
30 max_wins 0.00
31 max_losses 0.00
32 sharpe 0.01
33 profit_factor 1.03
34 ulcer_index 4.87
35 upi 0.01
36 equity_r2 0.44
37 std_error 112812652.60
The text was updated successfully, but these errors were encountered: