1

Homework Question need help to solve: strategy: buy whenever the price goes above the 50-day moving average, and then sell after 3 trading sessions. How much profit (in %) would we make on average? On trading day x, we say that the price "goes above" the 50-day moving average if (1) the price was below the moving average on trading day x-1 and (2) the price is above the moving average on trading day x.

How do I incorporate condition [1] and [2] into my current code with the 50-day moving average:

rol=stock.rolling(50).mean()

profitMade=((stock.shift(-3)-stock)/stock)

stock>rol

profitMade[stock>rol].mean()

Sample Data Set: Stocks and corresponding date:

Date
2002-05-23      1.196429
2002-05-24      1.210000
2002-05-28      1.157143
2002-05-29      1.103571
2002-05-30      1.071429
2002-05-31      1.076429
2002-06-03      1.128571
2002-06-04      1.117857
2002-06-05      1.147143
2002-06-06      1.182143
2002-06-07      1.118571
2002-06-10      1.156429
2002-06-11      1.153571
2002-06-12      1.092857
2002-06-13      1.082857
2002-06-14      0.986429
2002-06-17      0.922143
2002-06-18      0.910714
2002-06-19      0.951429
Jondiedoop
  • 3,303
  • 9
  • 24
none
  • 33
  • 1
  • 7
  • 2
    I'm afraid the presentation of your question doesn't make it easy for us to visualize the dataset and the constraints. Would be helpful if you can post a sample code and maybe a mock dataset – kerwei Jan 28 '19 at 05:43
  • above I have included the sample code. I will add the sample data set now. – none Jan 28 '19 at 17:06

1 Answers1

0

Okay, here's what I have. Not elegant but I think it gets the job done.

import datetime
import pandas as pd
import random

# Sample dataset
df = pd.DataFrame({'Date':sorted([datetime.date.today() - datetime.timedelta(days=i) for i in range(80)]), 'Price':[i for i in range(80)]})
df['Price'] = df['Price'].apply(lambda x: random.uniform(80,100))

>>>df
          Date      Price
0   2018-11-11  83.894664
1   2018-11-12  86.472656
2   2018-11-13  92.566676
3   2018-11-14  94.145586
..         ...        ...
77  2019-01-27  86.338076
78  2019-01-28  95.374173
79  2019-01-29  98.829077

[80 rows x 2 columns]

# MA calculation - borrowing from @jezrael's solution at https://stackoverflow.com/questions/54176642/how-do-i-perform-a-moving-average-in-panda-with-a-column-that-needs-to-be-unique/54195910#54195910
seq = df.set_index('Date')['Price'].rolling(50).mean().rename('MA')
df = df.join(seq, on='Date')

# Set buy signals if current price is higher than 50-day MA
df['Buy'] = df['Price'] - df['MA'] > 0
# Lookbehind check to see that it was below MA at T-1
df['BelowMA'] = df['Price'] - df['MA'] <= 0
# Profit calculations
df['Profit'] = (df['Price'] - df['Price'].shift(-3))/df['Price']

And finally, the rows that meet the given constraints

>>> df.loc[(df['BelowMA'].shift(1)==True) & (df['Buy'] == True)]
          Date      Price         MA   Buy    Profit  BelowMA
54  2019-01-04  91.356371  89.634529  True  0.000697    False
56  2019-01-06  94.116616  89.623909  True  0.114375    False
60  2019-01-10  89.383369  89.254519  True -0.082870    False
63  2019-01-13  96.790575  88.977660  True  0.029314    False
69  2019-01-19  92.193939  89.052057  True  0.071259    False
74  2019-01-24  91.392465  89.302293  True  0.020673    False
76  2019-01-26  95.369195  89.292715  True  0.158250    False
kerwei
  • 1,822
  • 1
  • 13
  • 22
  • Thank you so mich for all your help! I appreciate, Im using it now and came across a quick question: my data set has 4,195 rows. For this part of your code: random.uniform(80,100)) what does the 100 refer to? – none Jan 29 '19 at 06:02
  • @none I used it to just help me populate the 'Price' column and set its range to between 80 and 100. It can be any numbers but a narrower range would probably be closer to price movements in real life – kerwei Jan 29 '19 at 06:11
  • Thank you for the clarification, I appreciate it! I have an issue with another homework problem perhaps if you know what the issue can be, you can help? When I type the code: profitMade[profitMade.pct_change()].mean() I get: 'nan' – none Jan 29 '19 at 06:24
  • You really saved me, thank you so much I couldnt thank you more. It worked too! – none Jan 29 '19 at 06:26
  • @none For proper problem tracking, could you create a new thread for the question regarding pct_change? (Though I think you're getting nan because of the first points in the time series where the change cannot be computed). There could be answers already available out there too. I'd suggest you to search a bit and see if you can find anything before creating a new question – kerwei Jan 29 '19 at 06:30
  • I have opened a new post because I wasnt able to find it online: https://stackoverflow.com/review/suggested-edits/22056510 – none Jan 29 '19 at 06:43