앞에서 예측이란 주제로 글을 작성해 보았습니다.
https://swlock.blogspot.com/2020/09/xgboost-regsquarederror.html
앞에 작성한 데이터를 실행시켜보고 그 결과가 보도록 하겠습니다.
predict_feature_reg.py 실행
C:\Users\USER\Documents\python\stock>python predict_feature_reg.py ('64bit', 'WindowsPE') Time Price Vol SPrice ... Vol_lag10 SPrice_lag10 HPrice_lag10 LPrice_lag10 0 20200819 57800 16930719 59000 ... 19419694.0 57200.0 58100.0 57000.0 1 20200818 58400 25307825 58900 ... 21158940.0 57800.0 57900.0 56700.0 2 20200814 58000 15672548 58000 ... 21943345.0 59500.0 59600.0 57700.0 3 20200813 58700 22089460 59400 ... 19285354.0 59700.0 60100.0 59000.0 4 20200812 59000 18573934 58200 ... 36476611.0 60300.0 60400.0 58600.0 ... ... ... ... ... ... ... ... ... ... 6597 19940916 2280 27110458 2280 ... NaN NaN NaN NaN 6598 19940915 2260 56990850 2260 ... NaN NaN NaN NaN 6599 19940914 2214 5196078 2214 ... NaN NaN NaN NaN 6600 19940913 2168 3739216 2168 ... NaN NaN NaN NaN 6601 19940912 2122 19141830 2122 ... NaN NaN NaN NaN [6602 rows x 61 columns]
실행시키면 predict.csv test.csv train.csv 3가지 파일이 생성 됩니다.
predict_xgboost_reg.py 실행 내용이 길어서 마지막 부분만 표시하였습니다.
[505] eval-rmse:608.82898 train-rmse:0.00053 [506] eval-rmse:608.82898 train-rmse:0.00053 [507] eval-rmse:608.82898 train-rmse:0.00053 [508] eval-rmse:608.82898 train-rmse:0.00053 [509] eval-rmse:608.82898 train-rmse:0.00053 [510] eval-rmse:608.82898 train-rmse:0.00053 [511] eval-rmse:608.82898 train-rmse:0.00053 [512] eval-rmse:608.82898 train-rmse:0.00053 Stopping. Best iteration: [492] eval-rmse:608.82898 train-rmse:0.00053 Total rmse 370672.713558
eval-rmse 608 정도 나오는데 train-rmse비해 수치상으로 높은 값입니다. 제가볼때는 훈련된 값으로 평가를 했을때 거의 예측이 안된다고 보는게 맞습니다.
결과로는 predict_xgboost_regtest_prey.csv 이런 파일이 생성됩니다. 해당값은 마지막에 예측된 Y값인 PreY 값이 들어갑니다.
지금부터는 지난번에 소개안한 내용입니다. 현재 데이터로 시뮬레이션을 해보도록 해보겠습니다.
원하는 목표가 보다 높다면 실제 구매해보고 이익이 얼마나 발생하는지 보는것입니다.
predict_simul_reg.py
# import pandas as pd import config BASE_PATH = "./" def resultx(x): pprice = x[0]+x[0] * config.P_SELLP/100.0# Price 팔아야 하는 목표값을 계산한다 if pprice <= x[2] : return 1 # 목표값보다 예상값(PreY)이 커지면 구매표시를 한다. return 0 test_df = pd.read_csv(BASE_PATH+'predict_xgboost_regtest_prey.csv', header=0, encoding='utf8') test_df['Buy'] = test_df[['Price','Y','PreY']].apply(resultx, axis=1) test_df.to_csv("buy.csv", encoding='utf-8', index=False) # 실제 구매했을때 얼마나 손익이 날 수 있는지 시뮬레이션을 하도록한다 rowcount = test_df.shape[0] havetobuy = False price = 0 buylist=[] total = 0 for i in range(rowcount-1,0-1,-1): LPrice = test_df.iloc[i]['LPrice'] HPrice = test_df.iloc[i]['HPrice'] Time = test_df.iloc[i]['Time'] # 이미 보유 하고 있으면 if len(buylist) > 0 : # 팔 항목 있는지 살펴본다. removelist = [] for buiedprice in buylist: pprice = buiedprice+buiedprice * config.P_SELLP/100.0 mprice = buiedprice-buiedprice * config.M_SELLP/100.0 if LPrice < mprice : total=total-config.M_SELLP removelist.append(buiedprice) print(Time,"sell",i,buiedprice,"-",LPrice) elif HPrice > pprice : total=total+config.P_SELLP removelist.append(buiedprice) print(Time,"sell",i,buiedprice,"+",HPrice) if len(removelist)>0: for item in removelist: buylist.remove(item) if havetobuy == True and len(buylist) < config.MONEY_TOTAL: LPrice = test_df.iloc[i]['LPrice'] if price >= LPrice : buylist.append(price) pprice = price+price * config.P_SELLP/100.0 mprice = price-price * config.M_SELLP/100.0 print(Time,"havetobuy",i,price,"buy",mprice,pprice) else: print(Time,"havetobuy",i,price,LPrice,"dont buy") if test_df.iloc[i]['Buy'] > 0.5 : havetobuy = True price = test_df.iloc[i]['Price'] else: havetobuy = False price = test_df.iloc[i]['Price'] print(total)
동작 원리에대해서 설명
팔아야 하는 목표값보다 예측값(PreY)이 높으면 Buy 항목에 1로 표시해둡니다. buy.csv의 마지막 컬럼
마지막 날짜에서부터 Buy컬럼 값을 읽어서 구매해야한다고 판단을 하면 그 다음 날짜에 현재 날짜의 종가로 구매를 합니다.
이때 다음 날짜의 주식의 LPrice , HPrice가 있는데 이 값 범위에 들어야만 구매가 가능합니다. 만약 구매하지 못하면 "dont buy" 이런 문구가 나오게 됩니다.
보유하고 있는 주식은 매번 구매 했던 값의 목표치 값인 아래 두개 값보다 떨어지거나 올라가면 팔게 됩니다. 여기 예제에서는 6%로 잡아놨습니다. P_SELLP, M_SELLP 참고
pprice = buiedprice+buiedprice * config.P_SELLP/100.0
mprice = buiedprice-buiedprice * config.M_SELLP/100.0
MONEY_TOTAL 이 값은 구매시의 횟수를 나타냅니다. 즉 구매를 한번하고 나면 해당값이 줄어들고 0이 되면 더 이상 구매할 수 없게 됩니다. 중첩해서 구매 가능한 횟수를 나타냅니다.
config.py
X_M_PREDAYES=5 # 예측할때 과거 몇일을 가지고 학습 데이터를 만들지 결정하는 값 Y_O_POSTDAYES=5# 예측할때 앞으로의 몇일을 가지고 결과Y를 만들지 결정하는 값 #이익이 났을때 판매 가격 % P_SELLP=6 #손해가 났을태 판매 가격 % M_SELLP=6 COUNT_TEST_DATA = 600 # 테스트 검증를 위한 데이터 갯수 # simulation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MONEY_TOTAL = 2
최종 결과값입니다.
C:\Users\USER\Documents\python\stock>python predict_simul_reg.py 20180702.0 havetobuy 521 46650.0 buy 43851.0 49449.0 20180703.0 havetobuy 520 45550.0 45750.0 dont buy 20180709.0 havetobuy 516 44900.0 45200.0 dont buy 20180712.0 havetobuy 513 46000.0 buy 43240.0 48760.0 20180816.0 sell 489 46650.0 - 43700.0 20180817.0 havetobuy 488 44250.0 buy 41595.0 46905.0 20180828.0 sell 481 44250.0 + 46950.0 20180910.0 havetobuy 472 44900.0 45000.0 dont buy 20180913.0 havetobuy 469 44550.0 buy 41877.0 47223.0 20180920.0 sell 464 44550.0 + 47600.0 20181008.0 havetobuy 456 44700.0 buy 42018.0 47382.0 20181011.0 sell 454 46000.0 - 43100.0 20181011.0 havetobuy 454 45300.0 buy 42582.0 48018.0 20181023.0 sell 446 45300.0 - 42550.0 20181023.0 havetobuy 446 43550.0 buy 40937.0 46163.0 20181025.0 sell 444 44700.0 - 40550.0 20181025.0 sell 444 43550.0 - 40550.0 20181204.0 havetobuy 416 43250.0 buy 40655.0 45845.0 20181206.0 sell 414 43250.0 - 40450.0 20190305.0 havetobuy 358 44850.0 buy 42159.0 47541.0 20190306.0 havetobuy 357 44250.0 buy 41595.0 46905.0 20190322.0 sell 345 44250.0 + 47000.0 20190403.0 havetobuy 337 45750.0 45800.0 dont buy 20190405.0 sell 335 44850.0 + 47550.0 20190419.0 havetobuy 325 45600.0 buy 42864.0 48336.0 20190423.0 havetobuy 323 45350.0 buy 42629.0 48071.0 20190509.0 sell 313 45600.0 - 42450.0 20190509.0 sell 313 45350.0 - 42450.0 20190605.0 havetobuy 294 43450.0 43700.0 dont buy 20190614.0 havetobuy 288 43750.0 buy 41125.0 46375.0 20190627.0 sell 279 43750.0 + 46600.0 20190711.0 havetobuy 269 45550.0 46150.0 dont buy 20190801.0 havetobuy 254 45350.0 buy 42629.0 48071.0 20190802.0 havetobuy 253 45200.0 buy 42488.0 47912.0 20190806.0 sell 251 45350.0 - 42500.0 20190806.0 havetobuy 251 43950.0 buy 41313.0 46587.0 20190909.0 sell 228 43950.0 + 47000.0 20190919.0 sell 222 45200.0 + 49200.0 20191121.0 havetobuy 179 52000.0 buy 48880.0 55120.0 20191217.0 sell 161 52000.0 + 56700.0 -6
최종 결과가 -6은 -6% 손해라는 의미 입니다.
결론적으로 손해를 봤지만, 적용해서 사용하기엔 몇가지 문제가 있습니다. 학습 데이터가 너무 적다는것입니다. 일주일에 5개씩 10년해도 1만개도 채 되지 않는 양이라 훈련을 하기에는 무리가 있습니다.
회귀란 이전 데이터를 통해 미래를 예측하게 됩니다. 주가의 특성상 과거 데이터값만 고려하면 현재의 값과는 굉장히 많이 다릅니다. 예를들어 10년전에 100원 하던 주가가 지금은 1000원 하게 되니 당연히 과거에 데이터로는 현재의 회귀 모델에 맞지 않게 되는것 입니다.
그럼 생각해본 해결책은 비슷한 성향의 여러가지 종목을 하나의 종목처럼 추가하여 종목명을 구별하여 넣어 학습데이터를 늘려보는 방법입니다. 다른 하나는 입력데이터를 정규화 하는 방법을 생각할 수 있습니다.
댓글 없음:
댓글 쓰기