Data/python

[골든크로스] python을 활용한 벡테스팅

노는토요일 2022. 6. 18. 17:57

기술직 지표를 활용한 트레이딩 

골든크로스(5,20) 매수 ,데드크로스 (5,20) 매도

5이평선(이동평균선)이 20이평선을 상향 돌파시 매수, 5이평선이 20이평선을 하향 돌파시 매도 

 

3월 10일 윤석열 정부 취임부터 위와같은 전략을 활용해 가장 높은 수익률을 기록하는 개별 종목은?

 

모듈 임포트 

import yfinance as yf 
import pandas as pd 
import os 
import matplotlib.pyplot as plt
import talib
import numpy as np 
import FinanceDataReader as fdr
import warnings
warnings.filterwarnings('ignore')

 

골든 크로스 함수정의 

# 콜든 크로스 매수 
def goldencross(short_term_MA, long_term_MA):
    result = [False]
    for i in range(1, len(short_term_MA)):
        if (short_term_MA.iloc[i] >= long_term_MA.iloc[i]) and (short_term_MA.iloc[i-1] < long_term_MA.iloc[i-1]):
            result.append(True)
        else:
            result.append(False)
    
    return result

데드 크로스 함수정의 

##데드 크로스 매도 
def deadcross(short_term_MA, long_term_MA):
    result = [False]
    for i in range(1, len(short_term_MA)):
        if (short_term_MA.iloc[i] <= long_term_MA.iloc[i]) and (short_term_MA.iloc[i-1] > long_term_MA.iloc[i-1]):
            result.append(True)
        else:
            result.append(False)
    
    return result

 

트레이딩 횟수, 이익 합계, 수익 횟수, 수익률 산출 함수 정의 

수익률 = 수익/ 매수 평단가

def get_profit(df):
    final_df = df[df['action'].isin(['buy','sell'])]
    final_df = final_df.reset_index(drop=True)
    trading_cnt = final_df.shape[0]
    
    profit = []
    buy_lst = []
    for idx in range(len(final_df)):
        # 매수 action이 들어올 경우 매수 
        if final_df.action[idx] =='buy':
            buy_price = final_df.Close[idx]
            buy_lst.append(buy_price)
        # 첫 action이 매도인 경우
        elif idx == 0 and final_df.action[idx] =='sell':
            continue
        #그 외의 경우 정상 매도 
        else:
            sell_price = final_df.Close[idx]
            profit.append(-(buy_price) + sell_price) # 음수가 되어야함. 
            # 1 buy_pirce > sell_preice 인경우 비싸게 싸서 싸게 판경우 즉 손실 
            # 2 buy_pirce < sell_preice 인 경우 싸게사서 비싸게 판경우 그래서 이득 
       
    profit_sum = np.sum(profit)
    average_buying = np.mean(buy_lst) # 매수 평단가 
    profit_percentage = round(profit_sum/average_buying,2)
    profit_num = len(profit)
    
    return trading_cnt,profit_sum,profit_num,profit_percentage

주식 코드(symbol) , 원하는 기간 기입 하는 함수 정의 

def get_profit_2(symbol,year):
    raw_df=fdr.DataReader(symbol,year).reset_index()
    
    raw_df['ma_5'] = raw_df['Close'].rolling(window=5).mean()
    ma_5 = raw_df['ma_5']
    raw_df['ma_20'] = raw_df['Close'].rolling(window=20).mean()
    ma_20 = raw_df['ma_20']
    
    buy_idx = np.where(goldencross(ma_5,ma_20))[0]
    sell_idx =np.where(deadcross(ma_5,ma_20))[0]
    
    for k in range(len(raw_df)):
        if k in buy_idx:
            raw_df.loc[k,'action'] = 'buy'
        elif k in sell_idx:
            raw_df.loc[k,'action'] = 'sell'
        else:
            raw_df.loc[k,'action'] = ''

    rst_df = raw_df.copy()
    
    rst = get_profit(rst_df)
    return rst

krx 기준 상장사 정보 리스트 

df_krx = fdr.StockListing('KRX')
df_krx = df_krx.dropna()

# symbol를 구하고 , 개별 주식의 데이터 ma 5 + ma_20 구하고 ,
sym_name_lst=df_krx[['Symbol','Name','Sector','Industry']]
sym_name_lst.head()

2022년 3월 10일 부터 트레이딩 기법을 적용힌  모든 종목의 수익률 산출

# lst_value =
lst = []
lst_2 = []
lst_per =[]
lst_sector =[]
lst_industry =[]
percent = []
for idx, idx_Name,idx_sector,idx_industry in zip(sym_name_lst.Symbol,sym_name_lst.Name,sym_name_lst.Sector,sym_name_lst.Industry):
    rst = get_profit_2(idx,'2022-03-10')[1]
    rst_2 = get_profit_2(idx,'2022-03-10')[3]
    lst_per.append(rst_2)
    
    lst.append(rst)
    name =idx_Name
    lst_2.append(name)
    lst_sector.append(idx_sector)
    lst_industry.append(idx_industry)

ouput

수익률 기준 내림차순

name profit percnet sector industry
HLB제약 1300 0.1 자연과학 및 공학 연구개발업
씨트리시메티딘정, 로자틴정
AP위성 950 0.06 통신 및 방송 장비 제조업 위성통신 단말기
HSD엔진 580 0.06 일반 목적용 기계 제조업
대형선박용엔진,내연발전엔진
ISC 1900 0.05 전자부품 제조업
반도체테스트소켓
DSR제강 230 0.04 1차 철강 제조업
와이어로프,각종 경강선,철선제품,PC강선,아연도 강연선 제조
HLB 1350 0.04 선박 및 보트 건조업
구명정, GRP/GRE PIPPE
HMM 950 0.03 해상 운송업
정기,부정기,전용선,콘테이너선,자동차선,LNG선 해운
KB오토시스 210 0.03 자동차 신품 부품 제조업 브레이크패드
E1 900 0.02 기타 전문 도매업
LPG(프로판,부탄가스),가스기기판매
KBI메탈 25 0.01 1차 비철금속 제조업
동ROD, 모터코어
KT&G 1200 0.01 담배 제조업
잎담배,제조담배,홍삼,홍삼제품 제조,판매
AJ네트웍스 0 0 산업용 기계 및 장비 임대업
렌탈(파렛트, OA장비, 건설장비)
APS홀딩스 0 0 기타 금융업
인터넷 트래픽 솔루션
DI동일 100 0 상품 중개업
면사,화섬사,면포,혼방포,스포츠웨어용 신합섬 제조,도매,수출
HD현대 0 0 석유 정제품 제조업 지주회사

 

JW중외제약 -3650 -0.13 의약품 제조업
수액제,소화기궤양치료제,항생제,항암제 제조,도매
AK홀딩스 -2850 -0.14 기타 금융업 지주사업
GS리테일 -4000 -0.14 종합 소매업
체인화 편의점,슈퍼마켓,마트,전자상거래/부동산(빌딩) 임대
HB테크놀러지 -335 -0.14 특수 목적용 기계 제조업
TFT-LCD검사장비
KPX생명과학 -875 -0.15 기초 의약물질 및 생물학적 제제 제조업
의약품 중간체 등
HK이노엔 -7500 -0.16 의약품 제조업
전문의약품, 숙취해소음료
LG생활건강 -128000 -0.16 기타 화학제품 제조업
화장품,생활용품 제조,도매
CJ대한통운 -22000 -0.17 도로 화물 운송업
Contract Logistics, 포워딩, 항만하역, 해운, 택배국제특송, SCM Consulting
KD -225 -0.17 건물 건설업
건설사업(완성건물)
JTC -720 -0.2 종합 소매업
식품류, 생활용품류, 화장품류 (사후면세업)
CS -690 -0.21 통신 및 방송 장비 제조업
이동통신중계기, 위성방송(DMB)중계기(Gap-Filler)
KG ETS -4550 -0.23 폐기물 처리업
집단에너지(스팀), 산화동, 폐기물 소각
DSR -1610 -0.24 1차 비철금속 제조업 합섬섬유로프
HLB사이언스 -7350 -0.76 의료용품 및 기타 의약 관련제품 제조업
패혈증 치료제, 면역항암제 전달기술 등

결론 

해당전략으로 매매전략 가져가다가 골로 갈  수 있다. 기간을 더 넓혀보면 모르겠지만, 해당 기점으로는 좋은 전략은 아니다. 

트레이딩 전략을 통해 단기적인 성과를 원하니 단기에 수익률에 강건한 알고리즘을 찾아봐야 할 것 같다.

반등을 잘 잡아내는 알고리즘이 있다면, 단기적인 성과를 늘릴 수 있을 것 같다.