[Python] Verification of Golden cross and Death cross 3

Previous article: 美しい研究室の私: Verification of Golden Cross and Dead Cross 2(ゴールデンクロスとデッドクロスの検証2)

Verification of Golden cross and Death cross 3

It is often said to buy at golden cross and sell at death cross. I tested if it is worth to believe or not.

Method

I collected Japanese stock markets data during 2014/1/1 until 2015/1/23. I run below scripts. stocks.db has historical stock markets data ([Python] jsm使って株式市場のデータをスクレイピングしSQLに保存する). 


# -*- coding: utf8 -*- 
#!\usr\local\bin\python3

import pandas as pd
import sqlite3
import datetime
import matplotlib
import matplotlib.pyplot as plt
import pickle

conn = sqlite3.connect('stocks.db')
c = conn.cursor()

def check_trends_test():
    ccodes = [i[0] for i in c.execute('SELECT ccode FROM brand_data ORDER BY ccode').fetchall()]
    index = get_df(1332).index
    new_df=pd.DataFrame()
    for ccode in ccodes:
        df = get_df(ccode)
        if len(df)<201:
            continue
        mvavg50 = pd.rolling_mean(df['close'], 50)
        mvavg200 = pd.rolling_mean(df['close'], 200)
        trend = [1 if i-j>0 else -1 for i, j in zip(mvavg50, mvavg200)]
        new_trend = [0 for i in trend]
        for i in range(len(trend)):
            if trend[i]>0 and trend[i-1]<0:
                new_trend[i] = 'BUY {0}'.format(df.iloc[i]['close'])
            elif trend[i]<0 and trend[i-1]>0:
                new_trend[i] = 'SELL {0}'.format(df.iloc[i]['close'])
            else:
                pass
        try:
            sum(new_trend[200:])
        except TypeError:
            new_df[ccode] = pd.Series(new_trend, index=df.index)
    pickle.dump(new_df[200:], open('test_trend.pickle', 'wb'))    
    print(new_df.shape)
    print(new_df.iloc[200:])

def golden_vs_death(short_term=50, long_term=200):
    ccodes = pickle.load(open('test_trend.pickle', 'rb')).columns
    all = 0
    nice = 0
    for ccode in ccodes:
        df = get_df(ccode)
        if len(df)<=long_term:
            return None
        mavg_short = pd.rolling_mean(df['close'], short_term)
        mavg_long = pd.rolling_mean(df['close'], long_term)
        df['mavg_short'] = pd.Series(mavg_short, index=df.index)
        df['mavg_long'] = pd.Series(mavg_long, index=df.index)
        df['fluctuation'] =df['mavg_short']-df['mavg_long']
        df=df[long_term:]
        signal = {}
        # signal stocks date and golden cross (BUY) or death cross (SELL)
        for i,j in enumerate(df['fluctuation']):
            cond1_long = df['mavg_long'].iloc[i]-df['mavg_long'].iloc[i-1]>0
            cond2_long = df['mavg_long'].iloc[i-1]-df['mavg_long'].iloc[i-2]>0
            if i==0:
                continue
            #elif df['fluctuation'].iloc[i]>0 and df['fluctuation'].iloc[i-1]<0:
            #    signal[df.index[i]]='BUY'
            #elif df['fluctuation'].iloc[i]<0 and df['fluctuation'].iloc[i-1]>0:
            #    signal[df.index[i]]='SELL'
             
            # also watch long term moving averages go up or down    
            elif df['fluctuation'].iloc[i]>0 and df['fluctuation'].iloc[i-1]<0:
                signal[df.index[i]]='BUY'
            elif df['fluctuation'].iloc[i]<0 and df['fluctuation'].iloc[i-1]>0:
                signal[df.index[i]]='SELL'
            else:
                continue
        if len(signal)>1:

            kys=sorted(signal)
            for i,j in enumerate(kys):
                prev_day = kys[i-1]
                the_day = j
                if i==0:
                    pass
                elif signal[prev_day]=='SELL' and signal[the_day]=='BUY':
                    all+=1
                    if df['close'].loc[prev_day] > df['close'].loc[the_day]:
                        print(ccode, prev_day.date(), df['close'].loc[prev_day], 'SELL', '->', j.date(), df['close'].loc[the_day],'BUY RIGHT')
                        nice+=1
                    else:
                        print(ccode, prev_day.date(),df['close'].loc[prev_day], 'SELL', '->', j.date(), df['close'].loc[the_day],'BUY')
                elif signal[prev_day]=='BUY' and signal[the_day]=='SELL':
                    all+=1
                    if df['close'].loc[prev_day] < df['close'].loc[the_day]:
                        print(ccode, prev_day.date(), df['close'].loc[prev_day], 'BUY', '->', j.date(), df['close'].loc[the_day],'SELL RIGHT')
                        nice+=1
                    else:
                        print(ccode, prev_day.date(), df['close'].loc[prev_day], 'BUY', '->',j.date(), df['close'].loc[the_day],'SELL')
                else:
                    pass
    print('{0}/{1} = {2}%'.format(nice, all, round(100*nice/all,1)))# I changed these arguments.


At first, I made a pickle file which has pandas.DataFrame including just historical data with golden/death cross. Then I counted if that cross makes profits.

Result


A short term is 5 days and a long term is 24 days

1301 2014-02-14 263 BUY -> 2014-02-19 267 SELL RIGHT
1301 2014-02-19 267 SELL -> 2014-02-21 271 BUY
1301 2014-02-21 271 BUY -> 2014-03-17 265 SELL
1301 2014-03-17 265 SELL -> 2014-04-23 263 BUY RIGHT
...
8350 2014-07-29 218.0 SELL -> 2014-09-02 212.0 BUY RIGHT
8350 2014-09-02 212.0 BUY -> 2014-10-03 209.0 SELL
8350 2014-10-03 209.0 SELL -> 2014-10-31 213.0 BUY
8350 2014-10-31 213.0 BUY -> 2014-12-12 220.0 SELL RIGHT
8350 2014-12-12 220.0 SELL -> 2015-01-21 220.0 BUY
2464/8625 = 28.6%

A short term is 5 days and a long term is 100 days

1301 2014-07-23 266 BUY -> 2014-07-31 258 SELL
1301 2014-07-31 258 SELL -> 2014-09-29 263 BUY
1301 2014-09-29 263 BUY -> 2014-10-08 256 SELL
1301 2014-10-08 256 SELL -> 2014-10-31 260 BUY
...
8350 2014-09-24 211.0 SELL -> 2014-09-25 213.0 BUY
8350 2014-09-25 213.0 BUY -> 2014-10-02 210.0 SELL
8350 2014-10-02 210.0 SELL -> 2014-11-06 213.0 BUY
176/2581 = 6.8%

A short term is 5 days and a long term is 200 days

1379 2014-10-28 2035.0 BUY -> 2014-12-01 1989.0 SELL
1379 2014-12-01 1989.0 SELL -> 2014-12-03 1991.0 BUY
1379 2014-12-03 1991.0 BUY -> 2014-12-10 1987.0 SELL
1379 2014-12-10 1987.0 SELL -> 2014-12-30 2001.0 BUY
...
8316 2014-11-05 4538.5 BUY -> 2014-12-17 4121.0 SELL
8316 2014-12-17 4121.0 SELL -> 2014-12-24 4358.5 BUY
8316 2014-12-24 4358.5 BUY -> 2015-01-08 4159.5 SELL
23/805 = 2.9%

A short term is 10 days and a long term is 100 days

1301 2014-07-28 260 BUY -> 2014-08-05 255 SELL
1301 2014-08-05 255 SELL -> 2014-09-30 260 BUY
1301 2014-09-30 260 BUY -> 2014-10-10 251 SELL
1301 2014-10-10 251 SELL -> 2014-11-07 261 BUY
...
8350 2014-09-26 212.0 SELL -> 2014-09-30 213.0 BUY
8350 2014-09-30 213.0 BUY -> 2014-10-03 209.0 SELL
8350 2014-10-03 209.0 SELL -> 2014-11-11 222.0 BUY
114/1762 = 6.5%

A short term is 10 days and a long term is 200 days

1379 2014-10-31 2038.0 BUY -> 2014-12-09 1983.0 SELL
1379 2014-12-09 1983.0 SELL -> 2015-01-08 2000.0 BUY
1383 2014-11-20 1551.0 BUY -> 2014-12-18 1452.0 SELL
1413 2014-11-05 1410.0 BUY -> 2014-11-26 1339.0 SELL
...
8289 2014-11-05 994.0 BUY -> 2014-12-03 935.0 SELL
8309 2014-11-11 473.4 BUY -> 2015-01-14 424.0 SELL
8316 2014-11-11 4483.5 BUY -> 2015-01-14 4007.5 SELL
21/472 = 4.4%

A short term is 25 days and a long term is 200 days

1379 2014-11-21 2005.0 BUY -> 2014-12-15 1944.0 SELL
1379 2014-12-15 1944.0 SELL -> 2015-01-21 2075.0 BUY
1383 2014-11-27 1572.0 BUY -> 2014-12-30 1439.0 SELL
...
8217 2014-10-28 870.0 SELL -> 2014-11-25 963.0 BUY
8217 2014-11-25 963.0 BUY -> 2014-12-26 927.0 SELL
8282 2014-12-04 2935.0 SELL -> 2014-12-30 3170.0 BUY
8309 2014-11-26 490.6 BUY -> 2015-01-21 420.5 SELL
8316 2014-11-25 4528.0 BUY -> 2015-01-20 4090.0 SELL
10/175 = 5.7%

Conclusion

The results were terrible. Though most of beginner books say, "You should buy at golden cross and sell at death cross", but you don't get profit. The best ratio you make profit is 29% when a short term is 5 days and a long term is 24 days. Most of time you loose. That's why many people lost their money buy trading.

Discussion

In many cases, there are cross which caused just by market's fluctuation. I want to get rid of them. One of the solutions is to see if long term averages go up or fall down at a cross. I'll consider it next time.

コメント