0

I didnt really know how to title this, but my question is as follows, I am making a trading algo, with a basic SMA crossover. The code is as follows:

import pandas as pd
import pandas_datareader as data
import datetime as dt
import numpy as np
start = dt.datetime(2017, 1, 1)
end = dt.datetime(2020, 1, 20)
d = data.get_data_yahoo('URI', start, end) 

d['sma50'] = np.round(d['Close'].rolling(window=2).mean())
d['sma200'] = np.round(d['Close'].rolling(window=14).mean(), decimals = 2)
d['200-50'] = d['sma200'] - d['sma50']
_buy = -2
d['Crossover_Long'] = np.where(d['200-50'] < _buy, 1, 0)
d['buy'] = np.where(d['Crossover_Long']==1, 'buy', 'sell')
pd.set_option('display.max_rows', 400)
d.drop(['High', 'Low', 'Volume', 'Adj Close', 'Open'], axis=1, inplace=True)
d.dropna(inplace=True)
d.head()

正规365体育投注So the first 5 rows are:

    Close   sma50   sma200  200-50  Crossover_Long  buy
Date                        
2017-01-23  110.110001  111.0   109.04  -1.96   0   sell
2017-01-24  113.610001  112.0   109.35  -2.65   1   buy
2017-01-25  114.260002  114.0   109.67  -4.33   1   buy
2017-01-26  127.059998  121.0   110.87  -10.13  1   buy
2017-01-27  128.259995  128.0   112.22  -15.78  1   buy

if there is a 1, then it should buy and if there is a 0 then it should sell. Now the problem is what would be a way so that instead of continuing to write 1 when the sma2 if above the sma14, it only prints 1 when there is a crossover. Then 0 inbetween untill the next crossover. Any ideas? thanks!

New contributor
Bentio cano is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
  • Don't assume your readers know or will want to study up on the details of crossovers before diving in. Explain it relevant to your data, and illustrate what you hope for it to look like. I think you are asking for a way to have JUST the first transition row show up as 1, otherwise 0, until Crossover_Long presumably heads below 2 again. – ako May 24 at 0:41
  • Thank you for this advice @ako and thank you again for answering my question :) – Bentio cano May 25 at 11:49
0

You could use a diff() method on your Crossover_Long series - since it is already coded as just 0 or 1, when it changes state, you will get a diff of 1 or -1 one row only. Then just look for the non-0 rows and flag accordingly.

d['Crossover_Long_Change']=d.Crossover_Long.diff()

# code it as 1 where the value is not 0 (i.e. there is a change)
d['Crossover_Long_Change']=d['Crossover_Long_Change'].fillna(0).map(lambda x: 1 if x!=0 else 0)
d.head()


    Close   sma50   sma200  200-50  Crossover_Long  buy     Crossover_Long_Change
Date                            
2017-01-23  110.110001  111.0   109.04  -1.96   0   sell    0
2017-01-24  113.610001  112.0   109.35  -2.65   1   buy     1
2017-01-25  114.260002  114.0   109.67  -4.33   1   buy     0
2017-01-26  127.059998  121.0   110.87  -10.13  1   buy     0
2017-01-27  128.259995  128.0   112.22  -15.78  1   buy     0
| improve this answer | |
  • Did this work, @Bentiocano ? – ako May 25 at 4:26
  • Yeah sorry I thought I had commented before but it seems as though I hadn't. This was amazing and was exactly what I was looking for. Thank you so much! – Bentio cano May 25 at 11:41
  • Great, @Bentiocano. Could you accept the answer to close out then? – ako May 26 at 4:40
  • I just did, again thank you so much for responding! – Bentio cano May 26 at 17:04

Your Answer

Bentio cano is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.