'''
1. 전략base gma 11
가. 16년만에 천만원이 25억이 되는 소형주 퀀트 20 이평선 전략! (연복리 40%) - 복잡한 젠포트 안쓰고 자동매매 하기!
https://[Log in to view URL]
나. 도는 시간 : 24 6 * * 1-5 python3 /var/autobot/My_Small_Quant20.py
; 24분 / 6시(gmt기준임+9시간해서 15시) / 모든일 / 모든월 / 월~금
; https://[Log in to view URL]
2. 수정 할 사항들
가. myStockInfo.yaml : 내 계좌에 맞게 변경
나. 아래 계좌선택에서 : virturl / real 선택
다. import 바로 아래 토근발급하는 라인 추가
라. line_alert : 해당하는 디스코드 주소로 변경
마. investrate : 비율 지정해주기
바. 파일저장위치 : var로 시작 → 현재폴더로 다 바꾸기
ㅇ. 시간 바꿔라
time_info = time.localtime() #한국시간 사용 ; 근데 이렇게 바꾸면 아래 time_info 쓰는거 다바꿔야 함. 그냥 내비두자
time_info = time.gmttime()
사. 작동시간 선택하기 : make token 아래부터
while True:
t_now = dt.datetime.now()
t_0900 = t_now.replace(hour=9, minute=0, second=0, microsecond=0)
t_1500 = t_now.replace(hour=15, minute=0, second=0, microsecond=0)
t_1517 = t_now.replace(hour=15, minute=17, second=0, microsecond=0)
t_1520 = t_now.replace(hour=15, minute=20, second=0, microsecond=0)
t_1530 = t_now.replace(hour=15, minute=30, second=0, microsecond=0)
today = dt.datetime.today().weekday()
###
if t_0900 < t_now < t_1517:
여기에 원래 코드 넣기
if t_1500 < t_now :
exit(0)
[변경내용]
(23.11.07)
마켓타이밍 소형주지수 이동평균을 지수이동평균으로 변경
(23.11.14)
기본 보유목록이 있는데 JSON파일에 없다고 매도시점에 매도를 안함
최초도 매도하도록 바꿈
남은금액은 kofr 사도록 바꿈
'''
#######################################################################################
#######################################################################################
# 장이 열리는날이 아니면 프로그램 종료 ###############################################################
import exchange_calendars as ecals
import datetime as dt
import line_alert
XKRX = ecals.get_calendar("XKRX") # 한국 코드
ismarketopen= XKRX.is_session(dt.date.today().strftime("%Y-%m-%d")) # 오늘은 개장일인지 확인
if ismarketopen == False :
exit(0)
else :
line_alert.SendMessage(f'[전략명 : 소형주_per&pbr 20선] 시작합니다.')
#################################################################################################
#################################################################################################
# import ###############################################################
import KIS_Common as Common
import KIS_API_Helper_KR as KisKR
import json, requests, time, atexit, pprint
import pandas as pd
from pykrx import stock
import datetime as dt
import KIS_Make_StockCodeList as stockcode
import KIS_Make_StockData_KR as stockdata
import Util_Analysis_V3_devel_231114 as anal
import Util_Hankook_KR_V3_devel_231114 as hk
from Util_discord_message import send_message
from Util_get_access_token import get_access_token_daily
#################################################################################################
#################################################################################################
# 토큰 발급 & 클래스 선언 ##############################################################
#효종용
access_token = get_access_token_daily()
anal_ma = anal.Ma()
acc = hk.Account_Info()
buy = hk.Order_buy()
sell = hk.Order_sell()
hk_cm = hk.Common_util()
#게만아용
Common.MakeToken("REAL")
# Common.MakeToken("VIRTUAL")
Common.SetChangeMode("REAL") # REAL or VIRTUAL
#################################################################################################
#################################################################################################
### 종목코드, 종목데이터 생성 ####################################################
stockcode.make()
time.sleep(30)
stockdata.make()
time.sleep(3600)
#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
# 프로그램 시작시 1회 ###################################################################
now = dt.datetime.now()
atexit.register(line_alert.SendMessage, f"[{now}]=프로그램 종료됨=")
# 보유계좌 조회
Balance = KisKR.GetBalance()
print(Balance)
send_message(f'{Balance}')
acc.account_info_to_msg()
#################################################################################################
#################################################################################################
# 프로그램 시작 #################################################################################
while True:
try:
t_now = dt.datetime.now()
t_0900 = t_now.replace(hour=9, minute=0, second=0, microsecond=0)
t_1000 = t_now.replace(hour=9, minute=0, second=0, microsecond=0)
t_1500 = t_now.replace(hour=15, minute=0, second=0, microsecond=0)
t_1517 = t_now.replace(hour=15, minute=17, second=0, microsecond=0)
t_1520 = t_now.replace(hour=15, minute=20, second=0, microsecond=0)
t_1530 = t_now.replace(hour=15, minute=30, second=0, microsecond=0)
today = dt.datetime.today().weekday()
print(f'{t_now}_Gen_05')
if t_0900 < t_now < t_1500:
time.sleep(60)
if t_1500 < t_now <t_1520:
# 계좌 선택.. "VIRTUAL" 는 모의 계좌!
# Common.SetChangeMode("REAL") # REAL or VIRTUAL #위에서 사용함
BOT_NAME = Common.GetNowDist() + "_MyQuant20BotV"
# 포트폴리오 이름
PortfolioName = "소형주퀀트_전략_20일선"
# 시간 정보를 읽는다
time_info = time.gmtime()
#####################################################################################################################################
#####################################################################################################################################
#####################################################################################################################################
# 전제는 크롭탭 적절한 시간대에 등록하셔서 활용하세요!
# https://[Log in to view URL]
# 젠포트 테스트가 종가 기준이어서 거의 장 마감인 3시 24분에 리밸런싱!!!
# 24 6 * * 1-5 python3 /var/autobot/My_ISA_Quant20.py
# 마켓이 열렸는지 여부~!
IsMarketOpen = KisKR.IsMarketOpen()
if IsMarketOpen == True:
print("Market Is Open!!!!!!!!!!!")
else:
print("Market Is Close!!!!!!!!!!!")
#####################################################################################################################################
#####################################################################################################################################
#####################################################################################################################################
#####################################################################################################################################
# 계좌 잔고를 가지고 온다!
Balance = KisKR.GetBalance()
#####################################################################################################################################
'''-------통합 증거금 사용자는 아래 코드도 사용할 수 있습니다! -----------'''
# 통합증거금 계좌 사용자 분들중 만약 미국계좌랑 통합해서 총자산을 계산 하고 포트폴리오 비중에도 반영하고 싶으시다면 아래 코드를 사용하시면 되고 나머지는 동일합니다!!!
# Balance = Common.GetBalanceKrwTotal()
'''-----------------------------------------------------------'''
#####################################################################################################################################
print("--------------내 보유 잔고---------------------")
pprint.pprint(Balance)
print("--------------------------------------------")
# 총 평가금액에서 해당 봇에게 할당할 총 금액비율 1.0 = 100% 0.5 = 50%
InvestRate = 0.99
# 기준이 되는 내 총 평가금액에서 투자비중을 곱해서 나온 포트폴리오에 할당된 돈!!
TotalMoney = float(Balance['TotalMoney']) * InvestRate
print("총 포트폴리오에 할당된 투자 가능 금액 : ", format(round(TotalMoney), ','))
# 3백만원으로 최소 종목금액 정했을 때.. 매수가능한 종목 개수!
MininumCnt = (TotalMoney / 1000000)
print(" MininumCnt: ", MininumCnt)
# 우리가 전략으로 매수할 종목 개수 20개..
TargetCnt = 20
# 그런데 미니멈 개수보다 작다면... 미니멈 개수로 맞춰준다!!
if TargetCnt < MininumCnt:
TargetCnt = MininumCnt
# 상태 코드!
StatusCode = "NONE"
MaCheck = dict()
# 파일 경로입니다.
ma_file_path = "KrSmallStock" + BOT_NAME + "MaCheck.json"
try:
# 이 부분이 파일을 읽어서 리스트에 넣어주는 로직입니다.
with open(ma_file_path, 'r') as json_file:
MaCheck = json.load(json_file)
except Exception as e:
StatusCode = "ST_FIRST" # 파일자체가 없다면 맨 처음 상태!
print("Exception by First")
# 이전에 이평선 위에 있었는지 아래있었는지 여부~!
IsPrevMaUp = False
# 키가 없다면 아직 한번도 이 전략을 통해 매수된 바가 없다!
if MaCheck.get("ma20") == None:
StatusCode = "ST_FIRST" # 키가 없다면 맨 처음 상태!
else:
IsPrevMaUp = MaCheck['ma20']
# 아래 2줄로 활용가능한 지수를 체크할 수 있다!!
# for index_v in stock.get_index_ticker_list(market='KOSDAQ'): #KOSPI 지수도 확인 가능!
# # print(index_v, stock.get_index_ticker_name(index_v))
# 20일 이동평균선 위에 있는지 아래에 있는지 여부
IsNowMaUp = True ###초기값
try:
IndexID = "2004" # 코스닥 소형지수
df = Common.GetIndexOhlcvPyKrx(IndexID)
# pprint.pprint(df)
#원본 : ma20 = Common.GetMA(df, 20, -1)
ma20 = anal_ma.get_ema_value("2004", 20) # 지수 ma로 변경
IndexNow = df['close'][-1]
print(stock.get_index_ticker_name(IndexID))
print("MA 20 : ", ma20)
print("Now ", IndexNow)
if ma20 < IndexNow:
IsNowMaUp = True
else:
IsNowMaUp = False
except Exception as e:
print("Exception", e)
# 리밸런싱을 진행해야 되는지 여부
NeedRebalance = False
# SR_FIRST 상태가 아니라면!
if StatusCode != "ST_FIRST":
if IsPrevMaUp == True and IsNowMaUp == False:
StatusCode = "ST_DOWN"
NeedRebalance = True
status_mst = "20일선 아래로 지수가 떨어졌습니다. 전략으로 매수한 모든 종목 매도 합니다!"
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
print(status_mst)
line_alert.SendMessage(status_mst)
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
if IsPrevMaUp == False and IsNowMaUp == True:
StatusCode = "ST_UP"
NeedRebalance = True
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
status_mst = "20일선 위로 지수가 올라왔습니다. 조건에 맞는 종목으로 매수 합니다!"
print(status_mst)
line_alert.SendMessage(status_mst)
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
# 상태1 ST_FIRST : 처음 매수해야 되는 경우... 20일 이평선 위에 있으면 정상 진행..20일 이평선 아래에 있으면 아무 진행도 하지 않는다. IsNowMaUp 값이 True면 진행 아니면 진행 무!
# 상태2 ST_DOWN : 이전 IsPrevMaUp 이 True인데 IsNowMaUp이 False 라면 해당 전략으로 매수한 주식 모두 팔아야 되는 상황! -
# 상태3 ST_UP : 이전 IsPrevMaUp이 False인데 IsNowMaUp이 True 라면 해당 전략으로 주식을 다시 사야 되는 상황!
# 상태4 NONE : 위 경우에 해당되지 않는 경우
print("StatusCode: ", StatusCode)
# 리밸런싱이 필요없는 평온(?)한 상황.. 현재 매수하고 있는 종목 데이터를 보여준다!
if StatusCode == "NONE":
status_mst = "평온한 상황..아무 짓도 하지 않습니다"
print(status_mst)
line_alert.SendMessage(status_mst)
KRSmallStockSTList = list()
# 파일 경로입니다.
small_stock_file_path = "KrSmallStock" + BOT_NAME + "List.json"
try:
with open(small_stock_file_path, 'r') as json_file:
KRSmallStockSTList = json.load(json_file)
except Exception as e:
print("Exception by First")
pprint.pprint(KRSmallStockSTList)
# 처음인데 이평선 아래에 있다면... 아무짓도 안해도 된다!!!!
if StatusCode == "ST_FIRST" and IsNowMaUp == False:
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
status_mst = "처음 전략을 실행해 매수해야 하지만 코스닥 소형지수 20일 선 아래여서 동작하지 않습니다!"
print(status_mst)
line_alert.SendMessage(status_mst)
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
bought_list = acc.get_holding_stock_list()
if len(bought_list) > 0 :
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
status_mst = "이평선 아래인데 보유종목이 있네요. 전량 매도 합니다. "
print(status_mst)
line_alert.SendMessage(status_mst)
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
for code in bought_list :
hold_qty,hold_amt,yield_rate,yield_amt = acc.get_one_stock_balance(code)
sell.bid_1(code,hold_qty)
else:
if StatusCode != "NONE":
###################################################################################
###################################################################################
###################################################################################
# 전략에 투자되거나 투자할 주식 리스트
MyPortfolioList = list()
# Final20List -> FinalTopList로 변수명 변경
FinalTopList = list()
# 소형주 퀀트전략으로 투자하고 있는 주식 종목코드 리스트를 저장할 파일
KRSmallStockSTList = list()
# 파일 경로입니다.
small_stock_file_path = "KrSmallStock" + BOT_NAME + "List.json"
try:
with open(small_stock_file_path, 'r') as json_file:
KRSmallStockSTList = json.load(json_file)
except Exception as e:
print("Exception by First")
# 이전에 투자했던 종목들...
print("-----Prev--------")
pprint.pprint(KRSmallStockSTList)
print("-----------------")
##########################################################
print("--------------내 보유 주식---------------------")
# 그리고 현재 이 계좌에서 보유한 주식 리스트를 가지고 옵니다!
MyStockList = KisKR.GetMyStockList()
pprint.pprint(MyStockList)
print("--------------------------------------------")
##########################################################
# 매수하고 있는데 20일 선 아래로 떨어진 경우
if StatusCode == "ST_DOWN":
# 현재 전략으로 매수된 모든 주식을 팔아야 한다!
for AlReadyHasStock in KRSmallStockSTList:
stock = dict()
stock['stock_code'] = AlReadyHasStock['StockCode'] # 종목코드
stock['stock_target_rate'] = 0 # 포트폴리오 목표 비중
stock['stock_rebalance_amt'] = 0 # 리밸런싱 해야하는 수량
print("Old Stock...", stock)
MyPortfolioList.append(stock)
# 20일선 위에 있는 경우!
else:
TargetStockList = list()
# 파일 경로입니다.
korea_file_path = "KrStockDataList.json"
try:
# 이 부분이 파일을 읽어서 리스트에 넣어주는 로직입니다.
with open(korea_file_path, 'r') as json_file:
TargetStockList = json.load(json_file)
except Exception as e:
print("Exception by First")
print("TotalStockCodeCnt: ", len(TargetStockList))
df = pd.DataFrame(TargetStockList)
df = df[df.StockMarketCap >= 50.0].copy()
df = df[df.StockDistName != "금융"].copy()
df = df[df.StockDistName != "금융업"].copy()
df = df[df.StockDistName != "외국증권"].copy()
df = df[df.StockOperProfit > 0].copy()
df = df[df.StockROE >= 5.0].copy()
df = df[df.StockEPS > 0].copy()
df = df[df.StockBPS > 0].copy()
df = df[df.StockPBR >= 0.2].copy()
df = df[df.StockPER >= 2.0].copy()
df = df.sort_values(by="StockMarketCap")
pprint.pprint(df)
print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
NowCnt = 0
for idx, row in df.iterrows():
stockcode = row['StockCode']
print(stockcode)
if NowCnt < TargetCnt:
stock_amt = 0 # 수량
# 내가 보유한 주식 리스트에서 매수된 잔고 정보를 가져온다
for my_stock in MyStockList:
if my_stock['StockCode'] == stockcode:
stock_amt = int(my_stock['StockAmt'])
break
if stock_amt == 0:
print("---------------------------------------------------")
FinalTopList.append(row.to_dict())
NowCnt += 1
else:
break
pprint.pprint(FinalTopList)
###################################################################################
###################################################################################
###################################################################################
# 종목 개수 20개.
StockCnt = len(FinalTopList)
# 오늘 뽑은 조건에 맞는 주식들.. 비중이 20%이다!!!
for PickStock in FinalTopList:
stock = dict()
stock['stock_code'] = PickStock['StockCode'] # 종목코드
stock['stock_target_rate'] = 100.0 / float(StockCnt) # 포트폴리오 목표 비중
stock['stock_rebalance_amt'] = 0 # 리밸런싱 해야하는 수량
MyPortfolioList.append(stock)
# 이전에 뽑아서 저장된 주식들....오늘 뽑은 것과 중복되지 않는 것을 뽑아낸다. 이는 시총 하위 순에서 밀려난 것으로 비중 0으로 모두 팔아줘야 한다!
for AlReadyHasStock in KRSmallStockSTList:
# 오늘 뽑은 주식과 비교해서..
Is_Duple = False
for exist_stock in MyPortfolioList:
if exist_stock["stock_code"] == AlReadyHasStock['StockCode']:
Is_Duple = True
break
# 중복되지 않은 것만 넣어둔다. 비중은 0%이다!!!!
if Is_Duple == False:
stock = dict()
stock['stock_code'] = AlReadyHasStock['StockCode'] # 종목코드
stock['stock_target_rate'] = 0 # 포트폴리오 목표 비중
stock['stock_rebalance_amt'] = 0 # 리밸런싱 해야하는 수량
print("Old Stock...", stock)
MyPortfolioList.append(stock)
# 현재 체크해야할 투자 종목들..
pprint.pprint(MyPortfolioList)
print("--------------리밸런싱 수량 계산 ---------------------")
strResult = "-- 현재 포트폴리오 상황 --\n"
# 매수된 자산의 총합!
total_stock_money = 0
# 현재 평가금액 기준으로 각 자산이 몇 주씩 매수해야 되는지 계산한다 (포트폴리오 비중에 따라) 이게 바로 리밸런싱 목표치가 됩니다.
for stock_info in MyPortfolioList:
# 내주식 코드
stock_code = stock_info['stock_code']
stock_target_rate = float(stock_info['stock_target_rate']) / 100.0
# 현재가!
CurrentPrice = KisKR.GetCurrentPrice(stock_code)
stock_name = ""
stock_amt = 0 # 수량
stock_avg_price = 0 # 평단
stock_eval_totalmoney = 0 # 총평가금액!
stock_revenue_rate = 0 # 종목 수익률
stock_revenue_money = 0 # 종목 수익금
# 내가 보유한 주식 리스트에서 매수된 잔고 정보를 가져온다
for my_stock in MyStockList:
if my_stock['StockCode'] == stock_code:
stock_name = my_stock['StockName']
stock_amt = int(my_stock['StockAmt'])
stock_avg_price = float(my_stock['StockAvgPrice'])
stock_eval_totalmoney = float(my_stock['StockNowMoney'])
stock_revenue_rate = float(my_stock['StockRevenueRate'])
stock_revenue_money = float(my_stock['StockRevenueMoney'])
break
print("#####", KisKR.GetStockName(stock_code), " stock_code: ", stock_code)
print("---> TargetRate:", round(stock_target_rate * 100.0, 2), "%")
# 주식의 총 평가금액을 더해준다
total_stock_money += stock_eval_totalmoney
# 현재 비중
stock_now_rate = 0
# 잔고에 있는 경우 즉 이미 매수된 주식의 경우
if stock_amt > 0:
stock_now_rate = round((stock_eval_totalmoney / TotalMoney), 3)
print("---> NowRate:", round(stock_now_rate * 100.0, 2), "%")
if stock_target_rate == 0:
stock_info['stock_rebalance_amt'] = -stock_amt
print("!!!!!!!!! SELL")
else:
# 목표한 비중가 다르다면!!
if stock_now_rate != stock_target_rate:
# 갭을 구한다!!!
GapRate = stock_target_rate - stock_now_rate
# 그래서 그 갭만큼의 금액을 구한다
GapMoney = TotalMoney * abs(GapRate)
# 현재가로 나눠서 몇주를 매매해야 되는지 계산한다
GapAmt = GapMoney / CurrentPrice
# 수량이 1보다 커야 리밸러싱을 할 수 있다!! 즉 그 전에는 리밸런싱 불가
if GapAmt >= 1.0:
GapAmt = int(GapAmt)
# 갭이 음수라면! 비중이 더 많으니 팔아야 되는 상황!!!
if GapRate < 0:
# 팔아야 되는 상황에서는 현재 주식수량에서 매도할 수량을 뺀 값이 1주는 남아 있어야 한다
# 그래야 포트폴리오 상에서 아예 사라지는 걸 막는다!
if stock_amt - GapAmt >= 1:
stock_info['stock_rebalance_amt'] = -GapAmt
# 갭이 양수라면 비중이 더 적으니 사야되는 상황!
else:
stock_info['stock_rebalance_amt'] = GapAmt
# 잔고에 없는 경우
else:
if stock_target_rate != 0:
print("---> NowRate: 0%")
# 잔고가 없다면 첫 매수다! 비중대로 매수할 총 금액을 계산한다
BuyMoney = TotalMoney * stock_target_rate
# 매수할 수량을 계산한다!
BuyAmt = int(BuyMoney / CurrentPrice)
# 포트폴리오에 들어간건 일단 무조건 1주를 사주자... 아니라면 아래 2줄 주석처리
# if BuyAmt <= 0:
# BuyAmt = 1
stock_info['stock_rebalance_amt'] = BuyAmt
# 라인 메시지랑 로그를 만들기 위한 문자열
line_data = (">> " + KisKR.GetStockName(stock_code) + "(" + stock_code + ") << \n비중: " + str(
round(stock_now_rate * 100.0, 2)) + "/" + str(round(stock_target_rate * 100.0, 2))
+ "% \n수익: " + str(format(round(stock_revenue_money), ',')) + "(" + str(
round(stock_revenue_rate, 2))
+ "%) \n총평가금액: " + str(format(round(stock_eval_totalmoney), ','))
+ "\n리밸런싱수량: " + str(stock_info['stock_rebalance_amt']) + "\n----------------------\n")
# 만약 아래 한번에 보내는 라인메시지가 짤린다면 아래 주석을 해제하여 개별로 보내면 됩니다
if NeedRebalance == True:
line_alert.SendMessage(line_data)
strResult += line_data
##########################################################
print("--------------리밸런싱 해야 되는 수량-------------")
data_str = "\n" + PortfolioName + "\n" + strResult + "\n포트폴리오할당금액: " + str(
format(round(TotalMoney), ',')) + "\n매수한자산총액: " + str(format(round(total_stock_money), ','))
# 결과를 출력해 줍니다!
print(data_str)
# 영상엔 없지만 리밸런싱이 가능할때만 내게 메시지를 보내자!
# if Is_Rebalance_Go == True:
# line_alert.SendMessage(data_str)
# 만약 위의 한번에 보내는 라인메시지가 짤린다면 아래 주석을 해제하여 개별로 보내면 됩니다
if NeedRebalance == True:
line_alert.SendMessage("\n포트폴리오할당금액: " + str(format(round(TotalMoney), ',')) + "\n매수한자산총액: " + str(
format(round(total_stock_money), ',')))
print("--------------------------------------------")
##########################################################
# 리밸런싱을 진행해야 되거나 맨 처음일 경우인데.. 장이 열렸을 때!!!
if (NeedRebalance == True or StatusCode == "ST_FIRST") and IsMarketOpen == True:
line_alert.SendMessage(PortfolioName + " 리밸런싱 시작!!")
print("------------------리밸런싱 시작 ---------------------")
print("--------------매도 (리밸런싱 수량이 마이너스인거)---------------------")
for stock_info in MyPortfolioList:
# 내주식 코드
stock_code = stock_info['stock_code']
rebalance_amt = stock_info['stock_rebalance_amt']
# 리밸런싱 수량이 마이너스인 것을 찾아 매도 한다!
if rebalance_amt < 0:
CurrentPrice = KisKR.GetCurrentPrice(stock_code)
# 일반계좌 개인연금(저축)계좌에서는 이 함수를 사용합니다
pprint.pprint(KisKR.MakeSellMarketOrder(stock_code, abs(rebalance_amt)))
print("--------------------------------------------")
# 3초 정도 쉬어준다
time.sleep(3.0)
print("--------------매수 ---------------------")
for stock_info in MyPortfolioList:
current_cash = acc.get_possible_order_cash()
# 내주식 코드
stock_code = stock_info['stock_code']
rebalance_amt = stock_info['stock_rebalance_amt']
# 리밸런싱 수량이 플러스인 것을 찾아 매수 한다!
if rebalance_amt > 0:
CurrentPrice = KisKR.GetCurrentPrice(stock_code)
if (CurrentPrice*rebalance_amt) > current_cash:
hk_cm.make_money_using_kofr(CurrentPrice*rebalance_amt)
pprint.pprint(KisKR.MakeBuyMarketOrder(stock_code, rebalance_amt))
else:
pprint.pprint(KisKR.MakeBuyMarketOrder(stock_code, rebalance_amt))
print("--------------------------------------------")
line_alert.SendMessage(PortfolioName + " 리밸런싱 완료!!")
#########################################################################################################################
if IsNowMaUp == True:
# 이전에 확정된 종목 이번에 선정된 것으로 바꿔치기!
KRSmallStockSTList = FinalTopList
else:
if StatusCode == "ST_DOWN":
KRSmallStockSTList = list()
print("-----Now--------")
pprint.pprint(KRSmallStockSTList)
# 파일에 저장!!
with open(small_stock_file_path, 'w') as outfile:
json.dump(KRSmallStockSTList, outfile)
print("-----------------")
#########################################################################################################################
# 현재 20일 이평선 위에 있는지 아래에 있는지 여부를 파일에 저장해 줍니다!!!
MaCheck['ma20'] = IsNowMaUp
# 파일에 저장!!
with open(ma_file_path, 'w') as outfile:
json.dump(MaCheck, outfile)
print("------------------리밸런싱 끝---------------------")
#장마감 전 kofr 사기
line_alert.SendMessage(f'마감 전 kofr 매수합니다.')
hk_cm.buy_kofr()
line_alert.SendMessage(f'리밸런싱 이후로 종료합니다')
exit(0)
if t_now.minute == 00 and t_now.second <= 15: # 매30분마다 알림주기
line_alert.SendMessage(f"[주기적 상태 알림] : 정상동작중")
time.sleep(10)
# maxretry
except requests.packages.urllib3.exceptions.MaxRetryError:
send_message(f'Max Retry Error 60초 대기 후 재실행')
time.sleep(60)
except requests.packages.urllib3.exceptions.ConnectionError:
send_message(f'Connection 에러발생 60초 대기 후 재실행')
time.sleep(60)
# 위에거랑 차이가 뭐지
except requests.exceptions.ConnectionError:
send_message(f'Connection 에러 2번째 발생 60초 대기 후 재실행')
time.sleep(60)
# 최상위 에러는 마지막에 놔둬야한다. 그리고 위 에러말고는 종료하게 만든다.
except Exception as e:
send_message(f"[오류 발생] : {e}")
exit(0)
To embed this project on your website, copy the following code and paste it into your website's HTML: