crapher / medium

Apache License 2.0
68 stars 44 forks source link

Some questions and remarks about your option backtesting work #1

Closed nickanalytics closed 5 months ago

nickanalytics commented 1 year ago

@crapher

Hello Diego,

First of all thanks for the work you have done regarding the options backtesting (11.OptionsBacktest) as explained earlier on the Medium Platform in your article called "SPY Options Trading with a Profitable 1-Minute Strategy to Multiply Returns and Limit Risk". Later on I saw you extended your work to QQQ and AAPL as well. Super cool !

I'm a data enthusiast and stock market watcher as well, and I replayed and reviewed your code, trying to understand the rules you applied to trigger a new trade or close one. The code you have written is somewhat hard to interpret as it has not been fully commented out. One example would be this line: df.loc[:,'open_point'] = np.where((df['open_point'] - df['close_point']) == (df['open_point'].shift(-1) - df['close_point'].shift(-1)), 0, df['open_point'])

It looks like the code is comparing rows in order to flag them as a possible trade (or not). But the 'why' is not clear to me. So a short explanation of the steps would be helpful.

One other thing that I could not figure out was the meaning of 'POO' (percentage over price). What is that all about?

Last remark I would make is that I am also intrigued by the posts of Michael Petryni. To me it looks like he is trading in the following manner:

If you have no problem with it I would like to use one of your option data files to code his scenario and see what it brings. Would you be oke with me using your options data file ?

Regards, Nick

crapher commented 1 year ago

Hi Nick! Thank you very much for your comments.

Let me answer your questions:

The code you have written is somewhat hard to interpret as it has not been fully commented out. One example would be this line: df.loc[:,'open_point'] = np.where((df['open_point'] - df['close_point']) == (df['open_point'].shift(-1) - df['close_point'].shift(-1)), 0, df['open_point'])

About the hard-to-understand point, I agree with you. That is because I tried to use vectorization to solve the problem in a faster way avoiding iterating row by row. Regarding the code, the intention of that particular line is to filter out consecutive occurrences of the number 1 in the "open_point" column, while retaining only the first occurrence.

One other thing that I could not figure out was the meaning of 'POO' (percentage over price). What is that all about?

Once the system determines whether to buy call or put options and selects an appropriate strike, it proceeds to execute a "buy order" when the opening value of the chosen option contract exceeds the opening price of the first bar of the option at 9:30 AM. This POO acts as a threshold over the opening price of the first bar that is applied to trigger the purchase.

To provide an illustration, let's consider a practical example. Suppose we have a predetermined threshold (POO), set at 0.05 (or 5%). Let's assume we decide to purchase the Call option with a strike of 430. Initially, the option's opening price is $1. After 15 minutes, the option price increases to $1.02. However, the system will not initiate the purchase until the price reaches $1.05, which is calculated as the opening price ($1) multiplied by (1 + POO) or 1 * (1 + 0.05).

Michael Petryni Trading System

I didn't directly replicate Michael's system; instead, I found inspiration in his approach, particularly in operating options with 0 days to expiration. While Michael employs a 2-minute bar chart and initiates positions based on a criterion similar to mine, he does so immediately after the first bar without waiting for 15 minutes. Additionally, he occasionally incorporates the direction of the $NYSI to determine position openings. In my system, I introduced parameters such as the SL and POO. These additions were made by me with the aim of maximizing earnings while simultaneously managing risk.

If you have no problem with it I would like to use one of your option data files to code his scenario and see what it brings. Would you be okay with me using your options data file ?

Go ahead and use them as needed. Check the comments on these posts about his system.

If you have any additional questions, comments, or anything let me know :) Regards Diego

nickanalytics commented 1 year ago

Hello Diego,

Thanks for your explanation ! Your code is lightning fast so I get why you have done it this way. It is harder to read but faster to execute.

The points you mention make sense and I understand it better now. POO is fine and also using a SL make sense. In one post of Michael Petryni I read that he uses a 65% SL, but not sure if he does that all the time. Lately he stated that his track record was a 100% gain in 5 out of 14 trades. So 9 out of 14 are losses. I'm not sure if this is very profitable, that's why I was excited to see you actually doing the math.

I can follow your code for the largest part, but I'm still struggling a bit about the exact rules you apply. Steps I get:

Thanks in advance for your answer and thank for letting me play around with the data examples myself. Can you tell me where you got them from and if it is a paid service ?

If I find some interesting insights myself based on your work, I will share them with you. In the meantime I'll keep following your posts on Medium.

Nick.

crapher commented 1 year ago

Hi Nick!

I’ll try to answer all the points.

You record the option opening prices You determine the trend after 15 minutes (with some precautions) You determine if you want to take a put or call and focus on the nearest ITM option.

Yes, that is correct. My approach involves observing the closing prices after 15 bars and comparing them to the opening price in order to determine the trend and the most suitable option to purchase. There is definitely room for improvement, and I'm currently exploring ways to enhance this method. Initially, I aimed to keep it as simple as possible.

You then put some rules into play that determine when to take a trade. And taking a trade may last a few hours before the right conditions are met. Or (as far as I can see) you may even take 2 or more trades a day. My problem with this is that I don't understand what your conditions exactly are. Would you be so kind to summarize those ? It would help me a lot in understanding the code and get a profound understanding of the trading rules. Because in the end I want to see if this way of buying and selling options can be put into practice.

The rules are simpler than they may appear at first glance. We utilize two trade points consistently throughout the entire backtest on a daily basis:

  1. Opening a position: We only make a purchase when the price surpasses the option's opening price plus the PPO. For example, if the option's opening price is 1 and the PPO is 1%, a new purchase is executed each time the price crosses $1.01.

  2. Closing a position: We close the position either when the price reaches the stop loss (e.g., if we have a stop loss set at 70%, we close the position when the option price reaches 0.70) or when the option expires.

Both opening and closing operations are executed as many times as the conditions are met during the day.

Can you tell me where you got them from and if it is a paid service ?

About the data I used polygon.io paying the basic plan ($29 / month)

If I find some interesting insights myself based on your work

Great! I’ll be waiting for it :)

Regards Diego

nickanalytics commented 1 year ago

Super ! Thanks Diego. This makes it a lot clearer.

I have played around with the parameters a bit and by lowering the stop loss of QQQ to 25% the profit went up from 61,000 to 75,000 (see my screenshot). Only 7 out of 24 months close at a loss. Not bad I would say, but I won't be happy until I have pushed the gains over $100,000. There are many scenarios I can think of that could make this happen. I want to see if profit taking at a certain level would make sense. Obviously raising the cash sum of 1000 to 2000 would also help. Or reinvesting gains to a certain degree. But the risk factor and number of trades have to remain manageable.

Example QQQ

Nick

crapher commented 12 months ago

Using the QQQ, the best result I found was using 9 bars (instead of 15), a stop loss of 25%, and a POO of 1%.

image

Diego

pluggedin2 commented 10 months ago

Hello Diego, I came upon your Medium article and it was very interesting and I had the same questions Nick raised and you answered, plus 2 additional.

You indicated that a purchased option can either stop out or expire (since it’s a 0 DTE). Are expired ITM options automatically sold at the end of the day by the exchange or broker?

You also indicated it can initiate more than one position per day- can these overlap or are they always serial?

Thanks for the great write up!

crapher commented 10 months ago

Hi @pluggedin2,

Thanks for your comments!

I'll copy your questions to answer them. You indicated that a purchased option can either stop out or expire (since it’s a 0 DTE). Are expired ITM options automatically sold at the end of the day by the exchange or broker?

No, they don't sell your option contracts. They exercise them, buying (calls options) or selling (puts options) the underlying asset depending on the options you purchased.

You also indicated it can initiate more than one position per day- can these overlap or are they always serial? In the case of the backtest they are always serialized. If there is an open position, it doesn't open a new one.

Regards Diego