[Python] Verification of Golden cross and Death cross - t-test before GC - ゴールデンクロスとデスクロスの検証 - t検定を用いる -

[Python] Verification of Golden cross and Death cross 

Many Golden cross are actually fakes. They just represent fluctuations. What is the difference between true one and fake one. It can be supposed before a true golden cross, short term moving average and long term moving average are very similar. it has been going on quietly and suddenly something makes stock price go up.

短期の移動平均、長期の移動平均がほぼ横ばいのときに起きるゴールデンクロスは高く伸びることが多いという仮説を検証した。

Method

I found golden crosses some days before which  short moving average and long moving average are the same in Student's T-Test at the significance level 10% or 5%. Also I found death crosses. I compared two closing prices at a golden cross and successive death cross.
ゴールデンクロス前の短期移動平均と長期移動平均の数十日間のt検定を行った。有意水準は5%または10% (平均値の差から算出したt値が0に近いほど対応する確率は大きくなる。確率が5%または10%以上で平均値に差がないと考えた。)



Source Code

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

import numpy as np
import pandas as pd
import sqlite3
import datetime
import matplotlib
import matplotlib.pyplot as plt
import pickle
from scipy import stats

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

def get_df(ccode):
    df = pd.read_sql('SELECT * FROM stocks{0} ORDER BY date'.format(ccode), conn, index_col = 'date')
    df.index = [datetime.datetime.strptime(i, '%Y-%m-%d %H:%M:%S') for i in df.index]
    df.index.name = 'date'
    return df

def golden_vs_death(short_term=50, long_term=200):
    ccodes = [i[0] for i in c.execute('SELECT ccode FROM brand_data ORDER BY ccode').fetchall()]
    all = 0
    nice = 0
    for ccode in ccodes:
        df = get_df(ccode)
        if len(df)<=short_term:
            continue
        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
            cond3 = abs(df.ix[i-30:i, 'mavg_short'].mean()-df.ix[i-30:i,'mavg_long'].mean())0.05 # no difference between short and long mavg before GC
            if i==0:
                continue             
            # also watch long term moving averages go up or down    
            elif df['fluctuation'].iloc[i]>0 and df['fluctuation'].iloc[i-1]<0 data-blogger-escaped-and="" data-blogger-escaped-cond_t:="" data-blogger-escaped-df.index="" data-blogger-escaped-df="" data-blogger-escaped-elif="" data-blogger-escaped-fluctuation="" data-blogger-escaped-i-1="" data-blogger-escaped-i="" data-blogger-escaped-iloc="" data-blogger-escaped-signal="">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)))

golden_vs_death(short_term=5, long_term=25)
aaa

aaa

Result

short = 5 days and long = 25 days t-test =10 days 

1332 2014-06-30 313.0 SELL -> 2014-07-09 325.0 BUY
1332 2014-07-09 325.0 BUY -> 2014-07-22 318.0 SELL
1377 2014-03-18 1308.0 SELL -> 2014-03-27 1379.0 BUY
1377 2014-03-27 1379.0 BUY -> 2014-05-15 1403.0 SELL RIGHT
1377 2014-08-06 1382.0 SELL -> 2014-08-15 1398.0 BUY
1377 2014-08-15 1398.0 BUY -> 2014-09-01 1385.0 SELL
1377 2014-10-07 1396.0 SELL -> 2014-10-15 1457.0 BUY
1377 2014-10-15 1457.0 BUY -> 2015-01-27 1990.0 SELL RIGHT
1378 2014-03-04 234.0 SELL -> 2014-03-05 238.0 BUY
1378 2014-03-05 238.0 BUY -> 2014-03-12 231.0 SELL
1379 2014-07-16 1975.0 SELL -> 2014-07-28 1994.0 BUY
1379 2014-07-28 1994.0 BUY -> 2014-07-31 1962.0 SELL
1381 2014-03-14 770.0 SELL -> 2014-04-21 790.0 BUY
1381 2014-04-21 790.0 BUY -> 2014-04-28 785.0 SELL
...
9982 2014-05-27 408.0 BUY -> 2014-08-07 420.0 SELL RIGHT
9982 2015-01-13 405.0 SELL -> 2015-01-19 407.0 BUY
9983 2014-03-18 35590.0 SELL -> 2014-03-28 37885.0 BUY
9983 2014-03-28 37885.0 BUY -> 2014-04-11 33820.0 SELL
9983 2014-10-27 36905.0 SELL -> 2014-10-31 40365.0 BUY
9983 2014-10-31 40365.0 BUY -> 2014-12-11 41910.0 SELL RIGHT
9983 2014-12-11 41910.0 SELL -> 2014-12-22 44525.0 BUY
9983 2014-12-22 44525.0 BUY -> 2015-01-14 41940.0 SELL
9984 2014-03-31 7800.0 SELL -> 2014-04-04 7921.0 BUY
9984 2014-04-04 7921.0 BUY -> 2014-04-07 7556.0 SELL
9987 2014-03-17 3615.0 SELL -> 2014-03-27 3975.0 BUY
9987 2014-03-27 3975.0 BUY -> 2014-04-09 3730.0 SELL
9987 2014-12-11 3015.0 SELL -> 2014-12-18 3180.0 BUY
9989 2014-03-18 4050.0 SELL -> 2014-03-24 4440.0 BUY
9989 2014-03-24 4440.0 BUY -> 2014-04-11 4135.0 SELL
9989 2014-12-18 4670.0 SELL -> 2014-12-29 5010.0 BUY
9989 2014-12-29 5010.0 BUY -> 2015-01-06 4730.0 SELL
9993 2014-07-18 1649.0 SELL -> 2014-07-30 1678.0 BUY
9993 2014-07-30 1678.0 BUY -> 2014-08-06 1630.0 SELL
9995 2014-10-21 720.0 SELL -> 2014-10-30 857.0 BUY
9995 2014-10-30 857.0 BUY -> 2014-11-11 795.0 SELL
9997 2014-04-11 474.0 SELL -> 2014-04-21 499.0 BUY
9997 2014-04-21 499.0 BUY -> 2014-05-12 489.0 SELL
9997 2014-09-17 476.0 SELL -> 2014-09-22 488.0 BUY
9997 2014-09-22 488.0 BUY -> 2014-10-03 479.0 SELL
1241/8239 = 15.1%

Good








BAD


short = 5 days, long = 25 days, t-test = 30 days, signivicance level = 10% 

1301 2014-06-20 256 SELL -> 2014-06-30 260 BUY
1301 2014-06-30 260 BUY -> 2014-07-01 259 SELL
1301 2014-07-01 259 SELL -> 2014-07-04 259 BUY
...
3275 2014-11-04 1005.0 BUY -> 2015-01-13 1138.0 SELL RIGHT
3276 2014-03-13 501.0 SELL -> 2014-04-02 516.0 BUY
3276 2014-04-02 516.0 BUY -> 2014-04-11 496.5 SELL
3276 2014-04-30 503.0 SELL -> 2014-05-09 508.5 BUY
3276 2014-05-09 508.5 BUY -> 2014-06-27 602.5 SELL RIGHT
3276 2014-07-31 610.0 SELL -> 2014-08-14 619.5 BUY
3276 2014-08-14 619.5 BUY -> 2014-10-03 814.5 SELL RIGHT
3280 2014-03-25 744.0 SELL -> 2014-04-01 810.0 BUY
3280 2014-04-01 810.0 BUY -> 2014-04-10 770.0 SELL
3280 2014-08-20 675.0 SELL -> 2014-09-12 706.0 BUY
...
6639 2014-05-14 726.5 BUY -> 2014-06-26 903.5 SELL RIGHT
6639 2014-06-26 903.5 SELL -> 2014-07-29 911.5 BUY
6639 2014-07-29 911.5 BUY -> 2014-08-05 890.0 SELL
6639 2014-10-07 804.5 SELL -> 2014-10-22 820.5 BUY
6639 2014-10-22 820.5 BUY -> 2015-01-20 1107.0 SELL RIGHT
6640 2014-08-01 1756.0 SELL -> 2014-08-22 1838.0 BUY
6640 2014-08-22 1838.0 BUY -> 2014-10-17 1902.0 SELL RIGHT
6640 2014-11-13 2001.0 SELL -> 2014-11-20 2037.0 BUY
6640 2014-11-20 2037.0 BUY -> 2014-12-25 2488.0 SELL RIGHT
...
9996 2014-08-26 980.0 SELL -> 2014-09-11 988.0 BUY
9996 2014-09-11 988.0 BUY -> 2014-09-30 977.0 SELL
9996 2014-09-30 977.0 SELL -> 2014-10-29 980.0 BUY
9996 2014-10-29 980.0 BUY -> 2014-10-30 965.0 SELL
9997 2014-04-11 474.0 SELL -> 2014-04-21 499.0 BUY
9997 2014-04-21 499.0 BUY -> 2014-05-12 489.0 SELL
9997 2014-07-10 501.0 SELL -> 2014-07-31 503.0 BUY
9997 2014-07-31 503.0 BUY -> 2014-08-01 474.0 SELL
1600/8034 = 19.9%

GOOD




BAD


Discussion

Even when two moving averages are close, it is difficult to judge a cross is good  or bad.
2本の移動平均が近い場合でも、クロスが正しいクロスなのかそうでないのかを見極めるのは難しい。

BIBLIOGRAPHY




コメント