Comments (10)
I gave this more thought. I can add an additional option that would be used to set both the price that the stop is checked against, along with the exit price. For example:
ctx.stop_trailing_exit_price = PriceType.OPEN
This would check whether open <= threshold, and if true, exit at the open price on the same bar that the stop is triggered. This would get around the issue of lookahead bias I mentioned, and would allow you to specify a custom fill type, similar to what you suggested. If not set, then the stop behavior would default to the existing, where low/high prices are checked and the stop is exited at the threshold price.
from pybroker.
Hi @none2003,
I've committed a change so that stops are checked before any scheduled orders are placed. It should fix your issue. Let me know!
from pybroker.
Hi @edtechre,
I tried, it works, thank you!
With that, I have a question. If I set a trailing stop at 2% (ctx.stop_trailing_pct = 2), and if the stock falls more than 2% the same day after I buy it, and opens lower the next day, and falls throughout the day, there is no way to guarantee that the stop trailing is only at 2%, right?
Because I can see in the "return_pct" column of result trades, the maximum stop loss range is -2, so I have this question.
from pybroker.
The stop will be filled at the stop threshold, which in your case would be 2% from the entry. If you want to simulate a different fill, you need to code a trailing stop yourself with a custom sell_fill_price like in #25.
from pybroker.
The stop will be filled at the stop threshold, which in your case would be 2% from the entry. If you want to simulate a different fill, you need to code a trailing stop yourself with a custom sell_fill_price like in #25.
Maybe I didn't make myself clear. If the stock price fell more than 2% on the day it was bought and continued to fall the next day, but the trade will only fill the next day, how can the "return_pct" be just -2%?
from pybroker.
The execution is as follows:
- Day 1 sets a buy signal (i.e. sets buy_shares) along with a 2% trailing stop.
- Day 2 the order is placed and a long entry is open.
- Day 3 the stops are checked on open positions. The stop is triggered on 2% from the entry price on Day 2. A sell order is placed on Day 3 and filled at the 2% value that the stop was triggered at, which is why the return percent is -2%.
If the stock price fell more than 2% on the day it was bought
The previous behavior was checking stops on Day 2, which allowed for stops to be triggered on the same bar an entry was opened. But this was your original issue.
If you need the return_pct to be less than -2% percent, you will need to code the stop rules yourself and set the desired sell_fill_price when you determine the stop to be hit.
from pybroker.
Hi @edtechre,
First, we do not consider the pool bidding scenario. Here is a case:
- Day 1 sets a buy signal (i.e. sets buy_shares) along with a 2% trailing stop.
- Day 2 the bug order is placed and a long entry is open, order filled at open price, say $100. However, price drop to $90 at close price, lower than stop price of $98, since it's in a T+1 market, the stop order can only be placed on next day.
- Day 3 the stops are checked on open positions, but the open price is $85, and keep falling throughout the day, and close at $80, OHLC is (85, 85, 75, 80). Price didn't reach $98 the whole day.
- For following days, the stock price did not reach $98.
In this case, how is the stop order filled? If the stop can't get filled on Day 3, will it place a new order in following days?
Based on my understanding, pyb stop order is filled at "MARKET" price, it's not a "LIMIT" price order.
Hence, I think it will be better if there is a setting, like "ctx.sell_fill_price = PriceType.OPEN", acting like "secondary" stop price option.
stop_price = entry_price * (1 - stop_trailing_pct)
if PriceType.OPEN:
if ctx.data.open >= stop_price:
fill stop order at stop_price
set return_pct = -stop_trailing_pct
else:
fill stop order at ctx.data.open
set return_pct = ctx.data.open/entry_price - 1
elif PriceType.CLOSE:
if ctx.data.high >= stop_price >= ctx.data.low:
fill stop order at stop_price
set return_pct = -stop_trailing_pct
else:
fill stop order at ctx.data.close
set return_pct = ctx.data.close/entry_price - 1
from pybroker.
Day 3 the stops are checked on open positions, but the open price is $85, and keep falling throughout the day, and close at $80, OHLC is (85, 85, 75, 80). Price didn't reach $98 the whole day.
The stop is triggered if the bar's low crosses below the stop threshold, which is $75 < $98. The stop is executed on the same bar it was triggered on. The order will be placed on Day 3, bound to the low-high range of that bar: min(threshold, high) = $85.
IMO it is better to be explicit and code the desired behavior yourself if you want something different than the default stop behavior. The goal of stops in Pyb is to be a simple way of approximating a lower/upper bound for losses/gains, which is the same goal of setting stops in real life. By setting a 2% stop loss, it is assumed that the stop's exit will approximate -2%. If you need a more fine tuned fill price for the stop, then you can code the desired behavior yourself using the framework's trading signals.
from pybroker.
Also, one more thing worth mentioning: I would be hesitant to support setting fill prices for stops because it may introduce lookahead bias, which can allow stops to have more favorable exits. This is because stops are executed on the same bar, while the normal trading signals set with buy/sell shares are placed at least one bar ahead.
For example, let's say the stop's fill price would be set at the open price. But the stop was only triggered given the bar's low price (or high, or close etc.), which would have occurred after the open of the bar. And let's assume the bar opened higher than the recorded low price. Then setting the fill price to open would be the equivalent of looking ahead in time, seeing that the price will drop >= 2%, and then filling an order at the more favorable open price.
It is possible to force lookahead bias into the framework, but explicitly. I would rather not introduce options that make it easier to introduce lookahead bias implicitly.
from pybroker.
Committed the change to the dev branch. Added stop_trailing_exit_price, stop_loss_exit_price, and stop_profit_exit_price options.
from pybroker.
Related Issues (20)
- Multi-timeframe? HOT 2
- Indicator might be wrong when applying filter on backtesting data HOT 2
- Add MAE (Maximum Adverse Excursion) and MFE (Maximum Favorable Excursion) metrics. HOT 1
- Add regular defined contribution to portfolio HOT 1
- Add Ruff for Python linter and code formatter HOT 3
- Real-time question HOT 1
- The feature names should match those that were passed during fit HOT 6
- [Feature] Add support for Schwab HOT 2
- 设置了ctx.score的值后,买入的具体原则是怎样的,这个ctx.score具体作用和影响是什么呢 HOT 1
- How to set a different ctx.sell_fill_price HOT 1
- Error: Fill price 0 for prices below 0.005$ (like many cryptocurrencies) HOT 3
- fees and account amount HOT 5
- __init__() got an unexpected keyword argument 'adjust' HOT 1
- Data caching issue HOT 4
- 有考虑接入okx biance的数据么 HOT 1
- Add config option to save stop values in TestResult HOT 1
- caching data bug in month or week frequence HOT 2
- AKShare got an unexpected keyword argument 'timeframe' HOT 3
- Rotational Trading not working when using start_of_month HOT 1
- [Question] symbol for indicator but not for trading HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pybroker.