본문 바로가기

카테고리 없음

파이썬 배우기- 이동평균선 전략 분석

Build a simple trading strategy

Build a simple trading strategy

In [60]:
from IPython.core.display import display, HTML

display(HTML("<style>.container {width:90% !important; }</style>"))
In [1]:
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

1. Munging the stock data and add two columns - MA10 and MA50

In [2]:
#import FB's stock data, add two columns - MA10 and MA50
#use dropna to remove any "Not a Number" data
fb = pd.DataFrame.from_csv('../data/facebook.csv')

#주가평균이동치 계산하기 rolling(일수)

fb['MA10'] = fb['Close'].rolling(10).mean()
fb['MA50'] = fb['Close'].rolling(50).mean()
fb = fb.dropna()
fb.head()
Out[2]:
Open High Low Close Adj Close Volume MA10 MA50
Date
2015-03-13 22.559999 22.760000 22.250000 22.700001 22.116024 8982200 22.648 21.0174
2015-03-16 22.879999 23.110001 22.730000 22.969999 22.379078 5923900 22.685 21.0758
2015-03-17 22.920000 23.260000 22.760000 23.250000 22.651876 7497500 22.792 21.1382
2015-03-18 23.250000 23.370001 22.660000 22.870001 22.281652 10337600 22.836 21.1998
2015-03-19 22.950001 23.299999 22.780001 23.219999 22.622650 7768900 22.872 21.2804
In [18]:
fb['Close'].plot(legend=True)
fb['MA10'].plot(legend=True)
fb['MA50'].plot(legend=True)
Out[18]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f056d1d93c8>

종가와 10일 이동평균선이 50일 이동평균선을 우상향 하였다. 이는 계속해서 상승세를 이어간다는 것을 보여준다.

여기서 우리의 전략은, if MA10> MA50 이라면, 주식을 사서 보유하는 것이다.

In [10]:
ms = pd.DataFrame.from_csv('../data/microsoft.csv')
ms['MA10']=ms['Close'].rolling(10).mean()
ms['MA50']=ms['Close'].rolling(50).mean()
ms=ms.dropna()
In [14]:
ms.head()
Out[14]:
Open High Low Close Adj Close Volume MA10 MA50
Date
2015-03-13 40.700001 41.470001 40.610001 41.380001 38.443489 58007700 42.495 44.0034
2015-03-16 41.470001 41.639999 41.279999 41.560001 38.610714 35273500 42.263 43.9056
2015-03-17 41.369999 41.830002 41.150002 41.700001 38.740784 31587200 42.105 43.8044
2015-03-18 41.430000 42.830002 41.330002 42.500000 39.484009 43971800 42.049 43.7278
2015-03-19 42.259998 42.590000 42.220001 42.290001 39.288918 33879100 41.967 43.6606
In [19]:
ms['Close'].plot(legend=True)
ms['MA10'].plot(legend=True)
ms['MA50'].plot(legend=True)
Out[19]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f056cfa4b38>

2. Add "Shares" column to make decisions base on the strategy

In [20]:
#Add a new column "Shares", if MA10>MA50, denote as 1 (long one share of stock), otherwise, denote as 0 (do nothing)

fb["Shares"]=[1 if fb.loc[ei,'MA10']>fb.loc[ei,'MA50'] else 0 for ei in fb.index]
In [29]:
fb.head()
Out[29]:
Open High Low Close Adj Close Volume MA10 MA50 Shares
Date
2018-01-30 241.110001 246.419998 238.410004 242.720001 242.720001 14270800 235.692003 210.030001 1
2018-01-31 245.770004 249.270004 244.449997 245.800003 245.800003 11964400 237.800003 210.713801 1
2018-02-01 238.520004 246.899994 238.059998 240.500000 240.500000 12980600 239.406003 211.296601 1
2018-02-02 237.000000 237.970001 231.169998 233.520004 233.520004 17961600 239.747003 211.685401 1
2018-02-05 227.000000 233.229996 205.000000 213.699997 213.699997 28869000 237.748003 211.638401 1
In [30]:
#Add a new column "Profit" using List Comprehension, for any rows in fb, if Shares=1, the profit is calculated as the close price of 
#tomorrow - the close price of today. Otherwise the profit is 0.

#Plot a graph to show the Profit/Loss

fb['Close1'] = fb['Close'].shift(-1)
fb['Profit']=[fb.loc[ei,'Close1']-fb.loc[ei,"Close"] if fb.loc[ei,'Shares']==1 else 0 for ei in fb.index]
In [34]:
print(fb['Profit'].head())
Date
2015-03-13    0.269998
2015-03-16    0.280001
2015-03-17   -0.379999
2015-03-18    0.349998
2015-03-19    0.250000
Name: Profit, dtype: float64
In [35]:
fb['Profit'].plot()
plt.axhline(y=0, color='red')
Out[35]:
<matplotlib.lines.Line2D at 0x7f056ced0da0>

my work: 이동평균선 전략 수익 그래프로 나타내기 feat microsoft

In [38]:
# 1) MA10>MA50인 날만 주식 샀다고 가정

ms['Share']=[1 if ms.loc[id,'MA10']> ms.loc[id,'MA50'] else 0 for id in ms.index]
ms.head()
Out[38]:
Open High Low Close Adj Close Volume MA10 MA50 Share
Date
2015-03-13 40.700001 41.470001 40.610001 41.380001 38.443489 58007700 42.495 44.0034 0
2015-03-16 41.470001 41.639999 41.279999 41.560001 38.610714 35273500 42.263 43.9056 0
2015-03-17 41.369999 41.830002 41.150002 41.700001 38.740784 31587200 42.105 43.8044 0
2015-03-18 41.430000 42.830002 41.330002 42.500000 39.484009 43971800 42.049 43.7278 0
2015-03-19 42.259998 42.590000 42.220001 42.290001 39.288918 33879100 41.967 43.6606 0
In [46]:
# 2) 주식 산 날짜에 한해서 수익 계산하기
# 'Profit' 변수를 새로 만든다음 다음날 종가와 당일 종가 비교하기

ms['Close_T']=ms['Close'].shift(-1)
ms["profit"]=[ms.loc[index,'Close_T']-ms.loc[index,'Close'] if ms.loc[index,'Share']==1 else 0 for index in ms.index]
ms=ms.dropna()
ms.tail()
Out[46]:
Open High Low Close Adj Close Volume MA10 MA50 Share Close_T profit
Date
2018-01-29 95.139999 95.449997 93.720001 93.919998 93.480873 31569900 91.423 86.3292 1 92.739998 -1.180000
2018-01-30 93.300003 93.660004 92.099998 92.739998 92.306389 38635100 91.862 86.5244 1 95.010002 2.270004
2018-01-31 93.750000 95.400002 93.510002 95.010002 94.565781 48756300 92.349 86.7606 1 94.260002 -0.750000
2018-02-01 94.790001 96.070000 93.580002 94.260002 93.819290 47227900 92.765 86.9978 1 91.779999 -2.480003
2018-02-02 93.639999 93.970001 91.500000 91.779999 91.350883 47867800 92.943 87.1828 1 88.000000 -3.779999
In [47]:
ms["profit"].plot()
plt.axhline(y=0, color='red')
Out[47]:
<matplotlib.lines.Line2D at 0x7f056cf25438>

3. Use .cumsum() to display our model's performance if we follow the strategy

In [48]:
#Use .cumsum() to calculate the accumulated wealth over the period

fb['wealth'] = fb['Profit'].cumsum()
fb.tail()
Out[48]:
Open High Low Close Adj Close Volume MA10 MA50 Shares Close1 Profit wealth
Date
2018-01-30 241.110001 246.419998 238.410004 242.720001 242.720001 14270800 235.692003 210.030001 1 245.800003 3.080002 177.820011
2018-01-31 245.770004 249.270004 244.449997 245.800003 245.800003 11964400 237.800003 210.713801 1 240.500000 -5.300003 172.520008
2018-02-01 238.520004 246.899994 238.059998 240.500000 240.500000 12980600 239.406003 211.296601 1 233.520004 -6.979996 165.540012
2018-02-02 237.000000 237.970001 231.169998 233.520004 233.520004 17961600 239.747003 211.685401 1 213.699997 -19.820007 145.720005
2018-02-05 227.000000 233.229996 205.000000 213.699997 213.699997 28869000 237.748003 211.638401 1 NaN NaN NaN
In [49]:
#plot the wealth to show the growth of profit over the period

fb['wealth'].plot()
plt.title('Total money you win is {}'.format(fb.loc[fb.index[-2], 'wealth']))
Out[49]:
<matplotlib.text.Text at 0x7f056cb066d8>
In [55]:
ms['wealth'] = ms['profit'].cumsum()
ms.tail()
/opt/conda/lib/python3.6/site-packages/ipykernel_launcher.py:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  """Entry point for launching an IPython kernel.
Out[55]:
Open High Low Close Adj Close Volume MA10 MA50 Share Close_T profit Wealth wealth
Date
2018-01-29 95.139999 95.449997 93.720001 93.919998 93.480873 31569900 91.423 86.3292 1 92.739998 -1.180000 28.270005 28.270005
2018-01-30 93.300003 93.660004 92.099998 92.739998 92.306389 38635100 91.862 86.5244 1 95.010002 2.270004 30.540009 30.540009
2018-01-31 93.750000 95.400002 93.510002 95.010002 94.565781 48756300 92.349 86.7606 1 94.260002 -0.750000 29.790009 29.790009
2018-02-01 94.790001 96.070000 93.580002 94.260002 93.819290 47227900 92.765 86.9978 1 91.779999 -2.480003 27.310006 27.310006
2018-02-02 93.639999 93.970001 91.500000 91.779999 91.350883 47867800 92.943 87.1828 1 88.000000 -3.779999 23.530007 23.530007
In [57]:
ms['wealth'] .plot()
plt.title('Total money you win is {}'.format(fb.loc[ms.index[-1], 'wealth']))
Out[57]:
<matplotlib.text.Text at 0x7f056c9c42e8>

You can create your own simple trading strategy by copying the codes above and modify the codes accordingly using the data of Microsoft (microsoft.csv).