본문 바로가기
프로그램

[파이썬] 주식 매수,매도 최적 조건 자동 찾기

by 오디세이99 2022. 9. 4.
728x90
반응형

우리가 일반적으로 주식 Chart를 보면서 매수시점 및 매도시점을 찾게 됩니다.

예를 들어 종가가 20일선 위로 올라가면 매수하고, 종가가 20일선 밑으로 떨어지면 매도하는 등의 조건을 찾게 되죠.

이런 조건을 찾는 것을 반복하게 됩니다.

 

기본 컨셉은 다음과 같습니다.

1. 조건 리스트를 만듭니다(Close, ma5, ma20, ma60, ma120)

2. 조건 중에 임의의 항목을 가지고 조건을 만듭니다. 크거나 작거나 같은 조건이 있습니다.(Close < ma5)

3. 2에서 만든 조건으로 일정기간의 주식 데이터로 매수, 매도를 합니다.

4. 3에서 매수,매도 한 투자금이 제일 많은 조건을 최적 조건으로 합니다.

 

 

이것을 프로그램으로 만들어서 최적의 조건을 찾게 하면 어떨까요.

Full Code는 제일 아래에 있습니다.

 

기간 및 주식 종목을 지정합니다. working_time은 최적 조건을 찾는 시간입니다. 모든 조건을 찾게 되면 시간이 올래 걸립니다. 그래서 정해진 시간 동안에만 찾는 겁니다.

약 2~3분 정도에서 조건을 찾으면 어느 정보 최적으로 조건을 찾는 것 같습니다.

import matplotlib.pyplot as plt
from pykrx import stock
import random
import numpy as np
import sys
from datetime import datetime
import time

title = 'Stock Trade'
START_DATE = '2016-01-01'
END_DATE = '2019-12-31'

STOCK_CODE = '069500'
STOCK_NAME = 'KODEX200'
WORKING_TIME = 60 * 1   # sec
CHK_CNT = 3       # 몇개의 항목으로 검사할 것인지 지정

 

수수료와 세금입니다. 수수료 비율과 세금 비율 등을 자기에 맞도록 변경하면 되겠습니다.

수수료와 세금을 적용하지 않으면 결과가 많이 다릅니다. 처음에는 간단하게 보여주기 위해 이것들을 빼려고 했는데

결과가 너무 달라서 결국 적용했습니다.

def getFees(x):
    fee = 0
    if x < 10000000:
        fee = (x * 0.00147364) + 1500
    if x >= 10000000 and x < 50000000:
        fee = (x * 0.00127364) + 3000
    if x >= 50000000 and x < 100000000:
        fee = (x * 0.00117364)
    if x >= 100000000 and x < 300000000:
        fee = (x * 0.00097364)
    if x >= 300000000:
        fee = (x * 0.00077364)
    rtn = int(fee)
    return rtn


def getTax(x):
    rtn = int(x * 0.003)
    return rtn

 

기본적인 주식 데이터를 받아서 이동평균 데이터 등을 추가합니다.

def get_data(START_DATE, END_DATE, STOCK_CODE):
    # data_tmp = web.DataReader(STOCK_CODE, data_source='yahoo', start=START_DATE, end=END_DATE)
    dataset = stock.get_market_ohlcv(START_DATE, END_DATE, STOCK_CODE)
    dataset.columns = ['Open', 'High', 'Low', 'Close', 'Volume']

    # Create 7 and 21 days Moving Average
    dataset['ma5'] = dataset['Close'].rolling(window=5).mean()
    dataset['ma20'] = dataset['Close'].rolling(window=20).mean()
    dataset['ma60'] = dataset['Close'].rolling(window=60).mean()
    dataset['ma120'] = dataset['Close'].rolling(window=120).mean()
    dataset['date'] = dataset.index.astype(str).str[0:10]

    dataset = dataset.dropna()  # Nan 가 있는 행 삭제
    dataset = dataset[dataset['Volume'] != 0]  # 휴일등 제외

    x = []
    y = []
    d = []
    for i in range(len(dataset)):
        tmp = []
        tmp.append(dataset['Close'][i])
        tmp.append(dataset['Open'][i])
        tmp.append(dataset['High'][i])
        tmp.append(dataset['Low'][i])
        tmp.append(dataset['ma5'][i])
        tmp.append(dataset['ma20'][i])
        tmp.append(dataset['ma60'][i])
        tmp.append(dataset['ma120'][i])
        x.append(tmp)

        d.append(str(dataset['date'][i]))
        y.append(dataset['Close'][i])

    data_name = ['Close','Open','High','Low','ma5','ma20','ma60','ma120']      # 데이터 항목명

    return x, y, d, dataset, data_name

 

여러 개의 데이터 항목이 있을 때 남수로 임의의 항목을 선택하고, 크거나 작거나 같거나 등도 임의로 선택해서 조건의 set를 만듭니다.

# 조건(column1 < column2)와 같이 좌측 컬럼,부등호,우측컴험으로 구성됨.
# [column1,column2,column3,column4] 일때 부등호[=,<,>]로 column수-1의 수를 가지게 됩니다.
# column1 = column2 and column2 < column3 and column3 > column4 로 만들어짐
def generatorCondi(c_cnt, chk_cnt):   # c_cnt : Column수
    buy_condi_cnt = chk_cnt
    buy_chk = []
    buy_condi = []
    for i in range(buy_condi_cnt):   # c1,c2,c3 면 c1 > c2, c2 < c3, c1 == c3 와 같이 2배의 column이 있어야 한다.
        buy_chk.append(random.randint(0, c_cnt - 1))

    for i in range(buy_condi_cnt):
        buy_condi.append(random.randint(0, 2))

    sell_condi_cnt = 3
    sell_chk = []
    sell_condi = []
    for i in range(sell_condi_cnt):   # c1,c2,c3 면 c1 > c2, c2 < c3, c1 == c3 와 같이 2배의 column이 있어야 한다.
        sell_chk.append(random.randint(0, c_cnt - 1))

    for i in range(sell_condi_cnt):
        sell_condi.append(random.randint(0, 2))

    return buy_chk, buy_condi, sell_chk, sell_condi

 

위에서 만든 조건이 실제 데이터에서 맞는지 확인합니다.

def checkCondi(data, chk, condi):    # 조건 확인
    # print('<check> Column : ',chk,' /Condition : ', condi)
    rtn = 1     # 조건이 맞으면 1, 틀리면 -1
    for i in range(1,len(chk)):    # 조건이 여러개인기 때문에 and 조건으로 한조건이라도 조건이 맞지 않으면 -1
        v1 = data[chk[i-1]]
        v2 = data[chk[i]]
        c = condi[i-1]  # 0:=, 1:<, 2:>
        # print('      -->(',i,')',v1,' ',c,' ',v2,)
        if c == 0 and v1 != v2:
            rtn = -1
            break
        if c == 1 and v1 >= v2:
            rtn = -1
            break
        elif c == 2 and v1 <= v2:
            rtn = -1
            break

    return rtn

 

조건을 Print 해줍니다. 조건을 확인할 수 있도록 합니다.

def printCondi(std_name, title, chk, condi):   # std_name : Column name list, title:print tile, chk : condition list, condi : 비교(<,>) list
    # print('>>>Column : ',chk,' /Condition : ', condi)

    v_str = ''
    for i in range(1,len(chk)):   # 조건데이터
        v1 = std_name[chk[i-1]]
        v2 = std_name[chk[i]]
        c = condi[i-1]  # 0:=, 1:<, 2:>
        ss = ''
        if len(v_str) > 0: v_str += ' / '    # /로 조건 구분
        if c == 0:
            ss = ' = '
        elif c == 1:
            ss = ' < '
        elif c == 2:
            ss = ' > '

        v_str += v1 + ss + v2

    print(title,v_str)

 

만들어진 조건으로 실제 데이터를 가지고 매수, 매도를 하면서 최적으로 조건을 찾습니다.

### Data
x, y, d_date, data, column_name = get_data(START_DATE, END_DATE, STOCK_CODE)

investment = 1000000
max_score = 0
min_score = investment
max_buy_chk = []     # max 매수 항목
max_buy_condi = []   # max 매수 부등호
max_sell_chk = []    # max 매도 항목
max_sell_condi = []  # max 매도 부등호
trade_cnt = 0       # 조건 확인 수

start_time = datetime.now()
while(True):
    print('-'*100)
    # pre_buy :매수column index, pre_buy_condi: 매수(=,<,>),
    # pre_buy, pre_buy_condi, pre_sell, pre_sell_condi, buy, buy_condi, sell, sell_condi = generatorCondi()
    buy_chk, buy_condi, sell_chk, sell_condi = generatorCondi(len(column_name), CHK_CNT)

    trade_cnt = trade_cnt + 1
    investment = 1000000
    int_balance = investment
    b_list = []
    s_cnt = 0
    bs_flag = 0             # Buy(0), Sell(1) 가능 상태
    last_balance = 0        # 이전 매도시 자산
    max_ing_score = 0       # 거래 중 가장 큰 이득
    min_ing_score = investment       # 거래 중 가장 큰 손실

    printCondi(column_name, '■■■[' + str(trade_cnt) + '] Buy조건 : ', buy_chk, buy_condi)  # 조건 출력
    printCondi(column_name, '■■■[' + str(trade_cnt) + '] Sell조건 : ', sell_chk, sell_condi)  # 조건 출력
    for i in range(len(x)):
        if bs_flag == 0:
            p = checkCondi(x[i], buy_chk, buy_condi)
            if p == 1:
                # print('p=',p)
                c = int(investment / y[i])    # 매수수량
                m = c * y[i]
                if m < investment and c > 0:
                    fee = getFees(m)
                    investment = investment - (m + fee)
                    s_cnt = c
                    bs_flag = 1
                    last_balance = investment + m
                    print('   (',i,')◆ buy [',d_date[i],'] : close=',format(x[i][0],','),' /buy cnt = ',c,' /investment = ',format(investment,','))
        elif bs_flag == 1 or i == len(x)-1:
            p = checkCondi(x[i], sell_chk, sell_condi)
            if p == 1:
                # print('p=',p)
                if s_cnt > 0:
                    m = s_cnt * y[i]
                    fee = getFees(m)
                    tax = getTax(m)
                    investment = investment +  (m - (fee + tax))
                    s_cnt = 0
                    bs_flag = 0
                    print('   (',i,')◆ sell[', d_date[i], '] : close=', format(x[i][0],','), ' /buy cnt = 0 /investment = ', format(investment,','))

    if max_score < investment:
        max_score = investment
        max_buy_chk = buy_chk
        max_buy_condi = buy_condi
        max_sell_chk = sell_chk
        max_sell_condi = sell_condi

    print('   = [',trade_cnt,'] max score = ',max_score,' / investment = ',format(int(investment),','))

    end_time = datetime.now()
    run_time = end_time - start_time  # sec
    if run_time.seconds > WORKING_TIME:
        break

 

찾은 최적 조건 가지고 Chart로 그려 봅니다. 최적 조건으로 매수, 매도를 하고 해당 시점을 가지고 Chart를 그립니다.

### MAX 투자조건 Chart
# print(max_buy_chk, max_sell_chk)
print('='*50)
investment = 1000000
int_balance = investment
b_list = []
s_cnt = 0
bs_flag = 0  # Buy(0), Sell(1) 가능 상태
last_balance = 0  # 이전 매도시 자산
max_ing_score = 0  # 거래 중 가장 큰 이득
min_ing_score = investment  # 거래 중 가장 큰 손실

buy_chk = max_buy_chk
buy_condi = max_buy_condi
sell_chk = max_sell_chk
sell_condi = max_sell_condi

printCondi(column_name, '<MAX> Buy조건 : ', buy_chk, buy_condi)  # 조건 출력
printCondi(column_name, '<MAX> Sell조건 : ', sell_chk, sell_condi)  # 조건 출력
buy = []    # 매수 시점
sell = []   # 매도 시점
for i in range(len(x)):
    buy.append(False)
    sell.append(False)
    if bs_flag == 0:
        p = checkCondi(x[i], buy_chk, buy_condi)
        if p == 1:
            c = int(investment / y[i])  # 매수수량
            m = c * y[i]
            if m < investment and c > 0:
                investment = investment - m
                s_cnt = c
                bs_flag = 1
                last_balance = investment + m
                buy[i] = True
                print('   ◆ buy [', d_date[i], '] : close=', format(x[i][0], ','), ' /buy cnt = ', c, ' /balance = ', format(investment, ','))
    elif bs_flag == 1 or i == len(x) - 1:
        p = checkCondi(x[i], sell_chk, sell_condi)
        if p == 1:
            if s_cnt > 0:
                m = s_cnt * y[i]
                investment = investment + m
                s_cnt = 0
                bs_flag = 0
                sell[i] = True
                print('   ◆ sell[', d_date[i], '] : close=', format(x[i][0], ','), ' /buy cnt = 0 /balance = ', format(investment, ','))

# print(len(data), len(x), len(buy), len(sell))

data['buy'] = buy
data['sell'] = sell
# print('>>> buy =',buy)
# print('>>> sell=',buy)
plt.rcParams['font.family'] = 'NanumGothic'
plt.figure(figsize=(10, 6), dpi=100)
plt.title('매수,매도 최고 조건 자동 찾기(investment=' + format(investment,',') + ')')
plt.plot(data['Close'],label='Close')
plt.plot(data['ma5'],label='ma5')
plt.plot(data['ma20'],label='ma20')
plt.plot(data['ma60'],label='ma60')
plt.plot(data['ma120'],label='ma120')
plt.plot(data['Close'][data.buy == True], '^', color='r')     # 매수지점 Marking
plt.plot(data['Close'][data.sell == True], 'v', color='b')    # 메도지점 Marking
plt.legend()
plt.grid(True)
plt.show()

 

1분 동안 찾은 조건들입니다. 여러 번 해보 비슷한 조건을 찾습니다.

<MAX> Buy조건 :  ma60 > ma120 / ma120 > ma5
<MAX> Sell조건 :  ma60 < Close / Close < ma120
   ◆ buy [ 2016-11-15 ] : close= 22,082  /buy cnt =  45  /balance =  6,310
   ◆ sell [ 2018-03-13 ] : close= 29,490  /buy cnt = 0 /balance =  1,333,360
   ◆ buy [ 2019-05-13 ] : close= 25,233  /buy cnt =  52  /balance =  21,244
   ◆ sell[ 2019-07-02 ] : close= 25,937  /buy cnt = 0 /balance =  1,369,968

 


<MAX> Buy조건 :  ma120 < ma20 / ma20 > High
<MAX> Sell조건 :  ma5 > High / High < Close
   ◆ buy [ 2016-06-29 ] : close= 21,451  /buy cnt =  46  /balance =  13,254
   ◆ sell[ 2016-09-01 ] : close= 22,607  /buy cnt = 0 /balance =  1,053,176
   ◆ buy [ 2016-09-12 ] : close= 22,134  /buy cnt =  47  /balance =  12,878
   ◆ sell[ 2017-04-12 ] : close= 24,872  /buy cnt = 0 /balance =  1,181,862
   ◆ buy [ 2017-04-13 ] : close= 25,106  /buy cnt =  47  /balance =  1,880
   ◆ sell[ 2017-05-18 ] : close= 26,996  /buy cnt = 0 /balance =  1,270,692
   ◆ buy [ 2017-07-31 ] : close= 28,421  /buy cnt =  44  /balance =  20,168
   ◆ sell[ 2017-08-29 ] : close= 27,901  /buy cnt = 0 /balance =  1,247,812
   ◆ buy [ 2017-08-30 ] : close= 28,005  /buy cnt =  44  /balance =  15,592
   ◆ sell[ 2018-03-06 ] : close= 28,442  /buy cnt = 0 /balance =  1,267,040
   ◆ buy [ 2019-03-05 ] : close= 26,249  /buy cnt =  48  /balance =  7,088
   ◆ sell[ 2019-07-04 ] : close= 25,820  /buy cnt = 0 /balance =  1,246,448
   ◆ buy [ 2019-10-04 ] : close= 25,178  /buy cnt =  49  /balance =  12,726
   ◆ sell[ 2019-10-21 ] : close= 25,830  /buy cnt = 0 /balance =  1,278,396
   ◆ buy [ 2019-11-22 ] : close= 26,337  /buy cnt =  48  /balance =  14,220
   ◆ sell[ 2019-12-26 ] : close= 27,742  /buy cnt = 0 /balance =  1,345,836

 


<MAX> Buy조건 :  ma60 > ma120 / ma120 > Close
<MAX> Sell조건 :  Low > ma120 / ma120 > ma5
   ◆ buy [ 2016-11-09 ] : close= 22,126  /buy cnt =  45  /balance =  4,330
   ◆ sell[ 2016-11-23 ] : close= 22,432  /buy cnt = 0 /balance =  1,013,770
   ◆ buy [ 2016-11-24 ] : close= 22,316  /buy cnt =  45  /balance =  9,550
   ◆ sell[ 2018-04-30 ] : close= 29,627  /buy cnt = 0 /balance =  1,342,765
   ◆ buy [ 2019-05-09 ] : close= 25,487  /buy cnt =  52  /balance =  17,441
   ◆ sell[ 2019-06-28 ] : close= 26,077  /buy cnt = 0 /balance =  1,373,445


<MAX> Buy조건 :  ma120 < ma60 / ma60 > ma20
<MAX> Sell조건 :  Close < ma120 / ma120 > ma60
   ◆ buy [ 2016-07-07 ] : close= 21,638  /buy cnt =  46  /balance =  4,652
   ◆ sell[ 2018-03-07 ] : close= 28,479  /buy cnt = 0 /balance =  1,314,686
   ◆ buy [ 2019-05-15 ] : close= 25,305  /buy cnt =  51  /balance =  24,131
   ◆ sell[ 2019-06-24 ] : close= 25,839  /buy cnt = 0 /balance =  1,341,920

 


<MAX> Buy조건 :  Open = High / High < ma20
<MAX> Sell조건 :  ma60 < ma20 / ma20 < ma120
   ◆ buy [ 2016-09-13 ] : close= 22,213  /buy cnt =  45  /balance =  415
   ◆ sell[ 2018-04-30 ] : close= 29,627  /buy cnt = 0 /balance =  1,333,630
   ◆ buy [ 2018-11-05 ] : close= 24,875  /buy cnt =  53  /balance =  15,255
   ◆ sell[ 2019-01-23 ] : close= 25,676  /buy cnt = 0 /balance =  1,376,083
   ◆ buy [ 2019-03-06 ] : close= 26,174  /buy cnt =  52  /balance =  15,035
   ◆ sell[ 2019-07-12 ] : close= 25,649  /buy cnt = 0 /balance =  1,348,783
   ◆ buy [ 2019-08-22 ] : close= 24,115  /buy cnt =  55  /balance =  22,458
   ◆ sell[ 2019-09-25 ] : close= 25,779  /buy cnt = 0 /balance =  1,440,303

물론 이렇게 찾은 최적 조건을 미래에 사용해서 좋은 결과를 얻을 수는 없습니다.

위 코드를 확장해서 매일, 과거의 최적 조건을 찾아서 투자를 해나가는 프로그램으로 확장해 보면 이윤이 나지는 않습니다.

매 기간마다 상화이 다르기 때문에 최적 조건이 달라지는 것 같습니다.

 

 

 

Full Code

import matplotlib.pyplot as plt
from pykrx import stock
import random
import numpy as np
import sys
from datetime import datetime
import time

title = 'Stock Trade'
START_DATE = '2016-01-01'
END_DATE = '2019-12-31'

STOCK_CODE = '069500'
STOCK_NAME = 'KODEX200'
WORKING_TIME = 60 * 1   # sec
CHK_CNT = 3       # 몇개의 항목으로 검사할 것인지 지정

def getFees(x):
    fee = 0
    if x < 10000000:
        fee = (x * 0.00147364) + 1500
    if x >= 10000000 and x < 50000000:
        fee = (x * 0.00127364) + 3000
    if x >= 50000000 and x < 100000000:
        fee = (x * 0.00117364)
    if x >= 100000000 and x < 300000000:
        fee = (x * 0.00097364)
    if x >= 300000000:
        fee = (x * 0.00077364)
    rtn = int(fee)
    return rtn


def getTax(x):
    rtn = int(x * 0.003)
    return rtn


def get_data(START_DATE, END_DATE, STOCK_CODE):
    # data_tmp = web.DataReader(STOCK_CODE, data_source='yahoo', start=START_DATE, end=END_DATE)
    dataset = stock.get_market_ohlcv(START_DATE, END_DATE, STOCK_CODE)
    dataset.columns = ['Open', 'High', 'Low', 'Close', 'Volume']

    # Create 7 and 21 days Moving Average
    dataset['ma5'] = dataset['Close'].rolling(window=5).mean()
    dataset['ma20'] = dataset['Close'].rolling(window=20).mean()
    dataset['ma60'] = dataset['Close'].rolling(window=60).mean()
    dataset['ma120'] = dataset['Close'].rolling(window=120).mean()
    dataset['date'] = dataset.index.astype(str).str[0:10]

    dataset = dataset.dropna()  # Nan 가 있는 행 삭제
    dataset = dataset[dataset['Volume'] != 0]  # 휴일등 제외

    x = []
    y = []
    d = []
    for i in range(len(dataset)):
        tmp = []
        tmp.append(dataset['Close'][i])
        tmp.append(dataset['Open'][i])
        tmp.append(dataset['High'][i])
        tmp.append(dataset['Low'][i])
        tmp.append(dataset['ma5'][i])
        tmp.append(dataset['ma20'][i])
        tmp.append(dataset['ma60'][i])
        tmp.append(dataset['ma120'][i])
        x.append(tmp)

        d.append(str(dataset['date'][i]))
        y.append(dataset['Close'][i])

    data_name = ['Close','Open','High','Low','ma5','ma20','ma60','ma120']      # 데이터 항목명

    return x, y, d, dataset, data_name


def checkCondi(data, chk, condi):    # 조건 확인
    # print('<check> Column : ',chk,' /Condition : ', condi)
    rtn = 1     # 조건이 맞으면 1, 틀리면 -1
    for i in range(1,len(chk)):    # 조건이 여러개인기 때문에 and 조건으로 한조건이라도 조건이 맞지 않으면 -1
        v1 = data[chk[i-1]]
        v2 = data[chk[i]]
        c = condi[i-1]  # 0:=, 1:<, 2:>
        # print('      -->(',i,')',v1,' ',c,' ',v2,)
        if c == 0 and v1 != v2:
            rtn = -1
            break
        if c == 1 and v1 >= v2:
            rtn = -1
            break
        elif c == 2 and v1 <= v2:
            rtn = -1
            break

    return rtn


def printCondi(std_name, title, chk, condi):   # std_name : Column name list, title:print tile, chk : condition list, condi : 비교(<,>) list
    # print('>>>Column : ',chk,' /Condition : ', condi)

    v_str = ''
    for i in range(1,len(chk)):   # 조건데이터
        v1 = std_name[chk[i-1]]
        v2 = std_name[chk[i]]
        c = condi[i-1]  # 0:=, 1:<, 2:>
        ss = ''
        if len(v_str) > 0: v_str += ' / '    # /로 조건 구분
        if c == 0:
            ss = ' = '
        elif c == 1:
            ss = ' < '
        elif c == 2:
            ss = ' > '

        v_str += v1 + ss + v2

    print(title,v_str)


# 조건(column1 < column2)와 같이 좌측 컬럼,부등호,우측컴험으로 구성됨.
# [column1,column2,column3,column4] 일때 부등호[=,<,>]로 column수-1의 수를 가지게 됩니다.
# column1 = column2 and column2 < column3 and column3 > column4 로 만들어짐
def generatorCondi(c_cnt, chk_cnt):   # c_cnt : Column수
    buy_condi_cnt = chk_cnt
    buy_chk = []
    buy_condi = []
    for i in range(buy_condi_cnt):   # c1,c2,c3 면 c1 > c2, c2 < c3, c1 == c3 와 같이 2배의 column이 있어야 한다.
        buy_chk.append(random.randint(0, c_cnt - 1))

    for i in range(buy_condi_cnt):
        buy_condi.append(random.randint(0, 2))

    sell_condi_cnt = 3
    sell_chk = []
    sell_condi = []
    for i in range(sell_condi_cnt):   # c1,c2,c3 면 c1 > c2, c2 < c3, c1 == c3 와 같이 2배의 column이 있어야 한다.
        sell_chk.append(random.randint(0, c_cnt - 1))

    for i in range(sell_condi_cnt):
        sell_condi.append(random.randint(0, 2))

    return buy_chk, buy_condi, sell_chk, sell_condi


### Data
x, y, d_date, data, column_name = get_data(START_DATE, END_DATE, STOCK_CODE)

investment = 1000000
max_score = 0
min_score = investment
max_buy_chk = []     # max 매수 항목
max_buy_condi = []   # max 매수 부등호
max_sell_chk = []    # max 매도 항목
max_sell_condi = []  # max 매도 부등호
trade_cnt = 0       # 조건 확인 수

start_time = datetime.now()
while(True):
    print('-'*100)
    # pre_buy :매수column index, pre_buy_condi: 매수(=,<,>),
    # pre_buy, pre_buy_condi, pre_sell, pre_sell_condi, buy, buy_condi, sell, sell_condi = generatorCondi()
    buy_chk, buy_condi, sell_chk, sell_condi = generatorCondi(len(column_name), CHK_CNT)

    trade_cnt = trade_cnt + 1
    investment = 1000000
    int_balance = investment
    b_list = []
    s_cnt = 0
    bs_flag = 0             # Buy(0), Sell(1) 가능 상태
    last_balance = 0        # 이전 매도시 자산
    max_ing_score = 0       # 거래 중 가장 큰 이득
    min_ing_score = investment       # 거래 중 가장 큰 손실

    printCondi(column_name, '■■■[' + str(trade_cnt) + '] Buy조건 : ', buy_chk, buy_condi)  # 조건 출력
    printCondi(column_name, '■■■[' + str(trade_cnt) + '] Sell조건 : ', sell_chk, sell_condi)  # 조건 출력
    for i in range(len(x)):
        if bs_flag == 0:
            p = checkCondi(x[i], buy_chk, buy_condi)
            if p == 1:
                # print('p=',p)
                c = int(investment / y[i])    # 매수수량
                m = c * y[i]
                if m < investment and c > 0:
                    fee = getFees(m)
                    investment = investment - (m + fee)
                    s_cnt = c
                    bs_flag = 1
                    last_balance = investment + m
                    print('   (',i,')◆ buy [',d_date[i],'] : close=',format(x[i][0],','),' /buy cnt = ',c,' /investment = ',format(investment,','))
        elif bs_flag == 1 or i == len(x)-1:
            p = checkCondi(x[i], sell_chk, sell_condi)
            if p == 1:
                # print('p=',p)
                if s_cnt > 0:
                    m = s_cnt * y[i]
                    fee = getFees(m)
                    tax = getTax(m)
                    investment = investment +  (m - (fee + tax))
                    s_cnt = 0
                    bs_flag = 0
                    print('   (',i,')◆ sell[', d_date[i], '] : close=', format(x[i][0],','), ' /buy cnt = 0 /investment = ', format(investment,','))

    if max_score < investment:
        max_score = investment
        max_buy_chk = buy_chk
        max_buy_condi = buy_condi
        max_sell_chk = sell_chk
        max_sell_condi = sell_condi

    print('   = [',trade_cnt,'] max score = ',max_score,' / investment = ',format(int(investment),','))

    end_time = datetime.now()
    run_time = end_time - start_time  # sec
    if run_time.seconds > WORKING_TIME:
        break


### MAX 투자조건 Chart
# print(max_buy_chk, max_sell_chk)
print('='*50)
investment = 1000000
int_balance = investment
b_list = []
s_cnt = 0
bs_flag = 0  # Buy(0), Sell(1) 가능 상태
last_balance = 0  # 이전 매도시 자산
max_ing_score = 0  # 거래 중 가장 큰 이득
min_ing_score = investment  # 거래 중 가장 큰 손실

buy_chk = max_buy_chk
buy_condi = max_buy_condi
sell_chk = max_sell_chk
sell_condi = max_sell_condi

printCondi(column_name, '<MAX> Buy조건 : ', buy_chk, buy_condi)  # 조건 출력
printCondi(column_name, '<MAX> Sell조건 : ', sell_chk, sell_condi)  # 조건 출력
buy = []    # 매수 시점
sell = []   # 매도 시점
for i in range(len(x)):
    buy.append(False)
    sell.append(False)
    if bs_flag == 0:
        p = checkCondi(x[i], buy_chk, buy_condi)
        if p == 1:
            c = int(investment / y[i])  # 매수수량
            m = c * y[i]
            if m < investment and c > 0:
                investment = investment - m
                s_cnt = c
                bs_flag = 1
                last_balance = investment + m
                buy[i] = True
                print('   ◆ buy [', d_date[i], '] : close=', format(x[i][0], ','), ' /buy cnt = ', c, ' /balance = ', format(investment, ','))
    elif bs_flag == 1 or i == len(x) - 1:
        p = checkCondi(x[i], sell_chk, sell_condi)
        if p == 1:
            if s_cnt > 0:
                m = s_cnt * y[i]
                investment = investment + m
                s_cnt = 0
                bs_flag = 0
                sell[i] = True
                print('   ◆ sell[', d_date[i], '] : close=', format(x[i][0], ','), ' /buy cnt = 0 /balance = ', format(investment, ','))

# print(len(data), len(x), len(buy), len(sell))

data['buy'] = buy
data['sell'] = sell
# print('>>> buy =',buy)
# print('>>> sell=',buy)
plt.rcParams['font.family'] = 'NanumGothic'
plt.figure(figsize=(10, 6), dpi=100)
plt.title('매수,매도 최고 조건 자동 찾기(investment=' + format(investment,',') + ')')
plt.plot(data['Close'],label='Close')
plt.plot(data['ma5'],label='ma5')
plt.plot(data['ma20'],label='ma20')
plt.plot(data['ma60'],label='ma60')
plt.plot(data['ma120'],label='ma120')
plt.plot(data['Close'][data.buy == True], '^', color='r')     # 매수지점 Marking
plt.plot(data['Close'][data.sell == True], 'v', color='b')    # 메도지점 Marking
plt.legend()
plt.grid(True)
plt.show()

 

728x90
반응형

댓글