소스파일은 github.com/galaxywiz/StockCrawler_py 에서 확인 가능합니다.

 

머신 러닝(Machine Leaning), 줄여서 ML에 대해서 기술하려고 하면, 사실 책 한권 더 내야 할 정도로 내용이 많습니다.

머신 러닝은 역사가 꽤 깊은데 최근에 주목받는 이유는 이제서야 머신 러닝을 개인 PC에서도 할 수 있을 만큼 PC속도나 구조가 개편되었고, 최근 여러 소프트웨어에서 이를 활용하다 보니 많이 체감이 되기 때문입니다.

단순히 알파고란 애가 나와서 이세돌9단 이겨서 그 이후 뭔가 나온 게 아닌 기술이죠.

 

예를 들어 구글 포토란 프로그램() 이 있는데, 이 애는 사진이 클라우드에 무료로 올라가서 저장해주는 것도 (사진 사이즈 제한이 있지만) 멋진데, 사진 속 인물은 구별해서 인물별로 따로 그룹을 묶을 수 있다던 지, 할로윈 옷이라 검색하면 할로윈 옷을 입었던 사진만 나온다던 지가 구현되어 있습니다.

 

이런 것은 기존 프로그램으로는 불가능하였습니다. 왜냐면 사진은 우리가 볼 때 사진이란 형태를 인식하지만 실제 저장 파일 내부는 01의 숫자 조합으로 되어있는 데이터 덩어리 이거든요

사진 파일

 

사진 데이터 내부 모습

 

그럼 어떻게 이런 사람이 하는 것 마냥 구분하게 프로그래밍 하냐?

말로는 간단합니다. 인간의 뇌를 모방해서 프로그래밍 하면 되는 거죠.

그리고 정말 우수한 천재들과 단체(구글)등에서 이를 일반인(?)들이 코딩하기 편하도록 라이브러리화 해주었습니다.

 

우리는 이 라이브러리를 써서 특정 분야의 일을 사람이 하는 것 마냥 코딩해주면 됩니다.

이쪽에 관련하여 더 자세히 알고 싶으시면 https://www.youtube.com/watch?v=p_RdUAOaKgM

에 있는 구글에서 내놓은 머신 러닝 강좌를 보시면 좋습니다.

 

일단 구글에서 머신 러닝을 위해 텐서플로우란 라이브러리를 내놓은 건 알겠고, 이제 나 대신 컴퓨터가 대신 주식 패턴을 찾다가 다음날 오를 거 같으면 내게 알려주면 대박이지 않을까 한 생각을 가지실 수 있을 거 같은데요.

그거에 관련해서 아래와 같은 코드를 작성했습니다.

 

stockPredic.py

# 텐서플로어를 사용해서 주식 데이터를 예측해 보자
# 과거 데이터를 기반으로 패턴을 머신러닝으로 찾아내서
# 이걸 가지고 다음날 데이터를 예측. 
# 물론 미래일은 불확실이므로 정말 맞는건 아니고
# 특별한 이슈가 없으면, 아마 60,70%로 맞을지도 정도
import tensorflow as tf
import numpy as np
import pandas as pd
import datetime
import gc
import os

from stockData import StockData

class StockPredic:
    def __init__(self, stockData):
        # 하이퍼파라미터
        self.seqLength_ = 28              # 1개 시퀀스의 길이(시계열데이터 입력 개수)
        self.epochNum_ = 50             # 에폭 횟수(학습용전체데이터를 몇 회 반복해서 학습할 것인가 입력)
        self.tenserDir_ = "tensorSave/"

        self.stockData_ = stockData
        futureConsidered = ["start", "high", "low", "close"]
        self.priceTable_ = stockData.chartData_[futureConsidered]
        self.inColumnCnt_ = len(futureConsidered)
        self.outputCnt_ = 1          # 결과데이터의 컬럼 개수

        self.priceTable_ = self.priceTable_.values[1:].astype(np.float)

    #----------------------------------------------------------#
    def __modelName(self):
        name = "model_%s" % (self.stockData_.code_)
        return name

    # 너무 작거나 너무 큰 값이 학습을 방해하는 것을 방지하고자 정규화한다
    # x가 양수라는 가정하에 최소값과 최대값을 이용하여 0~1사이의 값으로 변환
    # Min-Max scaling
    def __minMaxScaling(self, x):
        npX = np.asarray(x)
        return (npX - npX.min()) / (npX.max() - npX.min() + 1e-7) # 1e-7은 0으로 나누는 오류 예방차원
    
    # 정규화된 값을 원래의 값으로 되돌린다
    # 정규화하기 이전의 org_x값과 되돌리고 싶은 x를 입력하면 역정규화된 값을 리턴한다
    def __inverseMinMaxScaling(self, orgX, x):
        orgNpX = np.asarray(orgX)
        npX = np.asarray(x)
        return (npX * (orgNpX.max() - orgNpX.min() + 1e-7)) + orgNpX.min()
    
    #----------------------------------------------------------#
    def predic(self, refresh = False):
        try:
            price = self.priceTable_[:, :-1]
            normPrice = self.__minMaxScaling(price)

            volume = self.priceTable_[:, -1:]
            normVol = self.__minMaxScaling(volume)

            x = np.concatenate((normPrice, normVol), axis=1)
            y = x[:, [3]]      ####### close 종가가 타겟 #######

            dataX = [] # 입력으로 사용될 Sequence Data
            dataY = [] # 출력(타켓)으로 사용
    
            for i in range(0, len(y) - self.seqLength_):
                _x = x[i : i + self.seqLength_]
                _y = y[i + self.seqLength_] # 다음 나타날 주가(정답)
                dataX.append(_x) # dataX 리스트에 추가
                dataY.append(_y) # dataY 리스트에 추가

            # 학습용/테스트용 데이터 생성
            # 전체 70%를 학습용 데이터로 사용
            trainSize = int(len(dataY) * 0.7)
            
            # 데이터를 잘라 학습용 데이터 생성
            trainX = np.array(dataX[0:trainSize])
            trainY = np.array(dataY[0:trainSize])
            
            trainX = np.reshape(trainX, (trainX.shape[0], trainX.shape[1], self.inColumnCnt_))

            # 데이터를 잘라 테스트용 데이터 생성
            testX = np.array(dataX[trainSize:len(dataX)])
            testY = np.array(dataY[trainSize:len(dataY)])

            path = self.tenserDir_
            if os.path.exists(path) == False:
                os.makedirs(path)

            savePath = "%s%s.h5" % (path, self.__modelName())

            with tf.device("/cpu:0"):
                if os.path.isfile(savePath) == True:
                    model = tf.keras.models.load_model(savePath)
                    model.summary()
                    print("* %s 모델 로드 [%s] " % (self.stockData_.name_, savePath))
            
                    if refresh:
                        model.fit(trainX, trainY, validation_data=(testX, testY), batch_size=10, epochs=1)
                        model.save(savePath)
                        return 0
                else:
                    model = tf.keras.models.Sequential()
                    model.add(tf.keras.layers.LSTM(256, return_sequences=True, input_shape=(self.seqLength_, self.inColumnCnt_))) # (timestep, feature) 
                    model.add(tf.keras.layers.LSTM(256, return_sequences=False))
                    model.add(tf.keras.layers.Dense(self.outputCnt_, activation='linear'))
                    model.compile(loss='mse', optimizer=tf.keras.optimizers.RMSprop(clipvalue=1.0))
                    model.summary()
                    
                    model.fit(trainX, trainY, validation_data=(testX, testY), batch_size=10, epochs=self.epochNum_)
                    model.save(savePath)

                # sequence length만큼의 가장 최근 데이터를 슬라이싱한다
                recentData = np.array([x[(len(x) - self.seqLength_): ]])
                # 내일 종가를 예측해본다
                testPredict = model.predict(recentData)
                testPredict = self.__inverseMinMaxScaling(price, testPredict) # 금액데이터 역정규화한다
                
                recentData = self.__inverseMinMaxScaling(price, recentData)
            
                tf.keras.backend.clear_session()

            del recentData
            del model
                
            return testPredict[0]

        except:
            print("* %s 모델 예측 에러" % (self.stockData_.name_))
            return 0

50라인의 predic 함수만 사용하는 형태입니다.

이미 22라인에서 클래스 생성하면서 시가, 고가, 저가, 종가 데이터만 사용해서 24라인처럼 priceTable을 만들고, 이걸 이용해서 53 라인에서 정규화 하는데, 왜냐면 주식의 가격은 컴퓨터가 보기엔 어지러운 숫자들이라 컴퓨터가 알기 쉽도록 이를 01사이의 숫자로 변환해 주는 겁니다.

 

이후 74라인처럼 전체 데이터 70%를 학습용으로 쓰고 나머지 최근 30%를 해답용으로 분리하는 작업을 합니다.

이렇게 만들어진 데이터를 텐서플로우 + 케라스 인터페이스를 사용해서 98라인처럼 모델을 만듭니다.

 

99라인 이후는 신경망 블록을 쌓는 단계이고 이렇게 만들어진 인공두뇌 모델(이하 모델)105라인에서 훈련시켜 줍니다. 그리고 저장하는데, 이는 훈련시키는 시간 비용이 많아서 추후 사용시를 위함 입니다. (93라인 보시면 모델이 있으면 로딩해서 바로 처리하죠)

이후 111라인에서 현제 데이터 넣어 예측하고, 이를 결과값으로 리턴 해줍니다.

 

즉 그러니까 이 코드는 10년치 주식 데이터가 있다면, 2010~2017년까지 데이터를 훈련용으로 입력하고, 컴퓨터가 자체적으로 패턴이 있는지 이것 저것 시도해 보고

2017~2020년 주식 데이터로 맞춰보면서 패턴을 검증하는 프로그램입니다.

증권플러스 앱의 차트 예측 화면

 

몇몇 앱에서 이런 비슷한 유형을 찾는 게 같은데,

아마 내부적으로 저런 프로그램을 돌려서 예측 값을 주는 걸로 보입니다.

'재테크 > 주식 알람 시스템 만들기' 카테고리의 다른 글

11. 조립 제작  (0) 2020.11.08
10. Bot  (0) 2020.11.08
9. 머신 러닝에 대해서  (0) 2020.11.08
8-3. 단기 변동성 돌파 전략  (0) 2020.11.08
8-2. MACD 전략  (0) 2020.11.08
8-1. 골든 크로스 전략  (0) 2020.11.08

소스파일은 github.com/galaxywiz/StockCrawler_py 에서 확인 가능합니다.

 

단기 변동성 돌파는 레리 윌리엄 (Larry R Williams) 라는 기술 투자의 대가로 유명 하신 분이 만드신 매매 방법인데, 일일 단위로 보고 있다가, 오늘 시작가가 전날 range (고가-저가) * 노이즈 이상을 돌파 시, 매수 신호라고 판단하여 진입. 다음날 시가에 정리하는 매매 방법입니다.

 

보통 노이즈 값은 0.7, 0.8 값을 사용하는 편이며,

몇몇 방법들 보니 20, 30일치 분봉들의 평균을 내서 노이즈를 계산하는 등 여러 방법으로 조절 할 수 있습니다

 

[2020-10-31][LG화학]

[LarryRTradeStrategy] short(매도) 신호 잡혔을 때 차트입니다

 

#//---------------------------------------------------//
class LarryRTradeStrategy(TradeStrategy):
    RANGE = 20

    def noice(self, timeIdx):
        return 0.7

    def __buySignal(self, timeIdx):
        chartData = self.stockData_.chartData_
        noice = self.noice(timeIdx)
        candle = chartData.iloc[timeIdx]
        startPrice = candle["start"]
        closePrice = candle["close"]
        stand = startPrice + ((candle["high"] - candle["low"]) * noice)

        if closePrice > stand:
            return True
        return False

    def __sellSignal(self, timeIdx):
        chartData = self.stockData_.chartData_
        noice = self.noice(timeIdx)
        candle = chartData.iloc[timeIdx]
        startPrice = candle["start"]
        closePrice = candle["close"]
        stand = startPrice - ((candle["high"] - candle["low"]) * noice)

        if closePrice < stand:
            return True
        return False

    def buy(self, timeIdx):
        chartData = self.stockData_.chartData_
        if len(chartData) <= self.RANGE:
            return False

        if self.stockData_.position_ == BuyState.STAY:
            if self.__buySignal(timeIdx):
                return True
        return False

    def sell(self, timeIdx):
        chartData = self.stockData_.chartData_
        if len(chartData) <= self.RANGE:
            return False

        if self.stockData_.position_ == BuyState.STAY:
            if self.__sellSignal(timeIdx):
                return True
        return False

    def buyList(self):
        signalList = []
        for i in range(0, self.RANGE):
            signalList.append(np.nan)
        
        chartData = self.stockData_.chartData_

        for i in range(self.RANGE, len(chartData)):
            nowCandle = chartData.iloc[i]
            if self.__buySignal(i):
                signalList.append(nowCandle["close"])
            else:
                signalList.append(np.nan)

        return signalList

    def sellList(self):
        signalList = []
        for i in range(0, self.RANGE):
            signalList.append(np.nan)
        
        chartData = self.stockData_.chartData_

        flag = False
        for i in range(self.RANGE, len(chartData)):
            nowCandle = chartData.iloc[i]
            if flag:
                signalList.append(nowCandle["close"])
                flag = False
                continue

            if self.__buySignal(i):
                flag = True
            
            signalList.append(np.nan)

        return signalList     

지금까지 매매 전략을 코드로 녹여내는 방법에 대해서 기술해 보았습니다.

여기에 양념 토핑 하 듯이, 몇몇 규칙을 더 추가해서 나만의 전략을 만들어 보시다 보면 좋을 결과가 나올 것입니다.

(예를 들어 전날 양봉이 뜨기 전까지 매수를 대기한다든가…)

'재테크 > 주식 알람 시스템 만들기' 카테고리의 다른 글

10. Bot  (0) 2020.11.08
9. 머신 러닝에 대해서  (0) 2020.11.08
8-3. 단기 변동성 돌파 전략  (0) 2020.11.08
8-2. MACD 전략  (0) 2020.11.08
8-1. 골든 크로스 전략  (0) 2020.11.08
8. 매매 전략에 대해서  (0) 2020.11.08

소스파일은 github.com/galaxywiz/StockCrawler_py 에서 확인 가능합니다.

 

MACD(Moving Average Convergence & Divergence) 약자이며, 이동 평균선들 간의 수렴 확산을 보기 좋게 나타낸 지표입니다.

각각의 이동평균선은 확산(Divergence)와 수렴(Convergence)하는 성질을 이용한 매매 지표로, 시간이 흐름에 따라 이동평균선들의 수렴, 확산하는 시기를 포착하여 매수 / 매도 포지션을 취하는 방식입니다.

보통 EMA 9, 12, 26일 이동평균선을 사용합니다.


MACD
선은 EMA12– EMA26일 값이고, 시그널선은 EMA9 선을 사용하며, 오실레이트 값은 MACD선과 시그널선의 차로 계산해서 그래프상 보기 좋은 용도로 사용합니다.

 

일반적으로 MACD가 시그널을 상향 돌파하면 골든 크로스로 판단하여 매수하고,
반대로 하양돌파 하면, 데드 크로스로 판단하여 매도하는 전략입니다.

 

아래 차트는 이 전략을 사용해서 뽑아낸 차트입니다. 실제 hts 앱의 주식 차트 지표와 비교했을 때 같은 결과임을 알 수 있습니다.

[2020-10-30][롯데케미칼]
[MACDStrategy] long(
매수) 신호가 잡혔을 때 차트입니다.

#//---------------------------------------------------//
class MACDTradeStrategy(TradeStrategy):
    TERM = 1
    def __buySignal(self, timeIdx):
        if timeIdx < self.TERM:
            return False
            
        chartData = self.stockData_.chartData_
        prevCandle = chartData.iloc[timeIdx - 1]
        macd = prevCandle["MACD"]
        signal = prevCandle["MACDSignal"]
        if macd > signal:
            nowCandle = chartData.iloc[timeIdx]
            macd = nowCandle["MACD"]
            signal = nowCandle["MACDSignal"]

            if macd < signal:
                return True

        return False

    def __sellSignal(self, timeIdx):
        if timeIdx < 1:
            return False
            
        chartData = self.stockData_.chartData_
        prevCandle = chartData.iloc[timeIdx - 1]
        macd = prevCandle["MACD"]
        signal = prevCandle["MACDSignal"]
        if macd < signal:
            nowCandle = chartData.iloc[timeIdx]
            macd = nowCandle["MACD"]
            signal = nowCandle["MACDSignal"]

            if macd > signal:
                return True

        return False

    def buy(self, timeIdx):
        chartData = self.stockData_.chartData_
        if len(chartData) <= self.TERM:
            return False

        if self.stockData_.position_ == BuyState.STAY:
            if self.__buySignal(timeIdx):
                return True
        return False

    def sell(self, timeIdx):
        chartData = self.stockData_.chartData_
        if len(chartData) <= self.TERM:
            return False

        if self.stockData_.position_ == BuyState.STAY:
            if self.__sellSignal(timeIdx):
                return True
        return False

    def buyList(self):
        signalList = []
        for i in range(0, self.TERM):
            signalList.append(np.nan)
        
        chartData = self.stockData_.chartData_

        for i in range(self.TERM, len(chartData)):
            nowCandle = chartData.iloc[i]
            if self.__buySignal(i):
                signalList.append(nowCandle["close"])
            else:
                signalList.append(np.nan)

        return signalList

    def sellList(self):
        signalList = []
        for i in range(0, self.TERM):
            signalList.append(np.nan)
        
        chartData = self.stockData_.chartData_

        for i in range(self.TERM, len(chartData)):
            nowCandle = chartData.iloc[i]
            if self.__sellSignal(i):
                signalList.append(nowCandle["close"])
            else:
                signalList.append(np.nan)

        return signalList

 

 

코드를 읽어 보시면 이전의 골든 크로스 코드랑 많이 비슷하게 느껴 지실 겁니다. 골든 크로스는 2개의 EMA값을 크로스 하냐 마냐로 판단하고, MACD역시 MACD랑 시그널의 크로스를 하냐 마냐로 판단하기 때문에 코드가 유사하게 작성됩니다.

'재테크 > 주식 알람 시스템 만들기' 카테고리의 다른 글

9. 머신 러닝에 대해서  (0) 2020.11.08
8-3. 단기 변동성 돌파 전략  (0) 2020.11.08
8-2. MACD 전략  (0) 2020.11.08
8-1. 골든 크로스 전략  (0) 2020.11.08
8. 매매 전략에 대해서  (0) 2020.11.08
7. 유틸 함수들  (0) 2020.11.08

소스파일은 github.com/galaxywiz/StockCrawler_py 에서 확인 가능합니다.

 

골든 크로스(Golden Cross)2개 이상의 이동 평균선이 좋은(Golden)의미 = 매수 신호로 통과하였다 하여 골든 크로스라고 합니다.

단기 이동평균선과, 장기 이동평균을 상향 돌파하면, 매수세가 강하므로 상승추세라 볼 수 있고 이를 골든 크로스라고 합니다.

반대로 장기 이동평균선이 단기 이동평균선을 하향 돌파하면, 데드 크로스(Dead Cross) 라고 하고, 매도 신호로 판단합니다.

 

[2020-10-30][삼성SDI]

[MaTradeStrategy] long(매수) 신호가 잡혔을 때 차트입니다.

저는 단기를 EMA (지수 가중으로 최근 것에 좀더 평균값을 높게 쳐주는 방식) 5일선, 장기를 EMA20 선으로 설정해서 그어 봤습니다.

매수, 매도 차트를 보니 썩 좋아 보이진 않네요. 이 값은 따로 설정하기로 하고 아래와 같이 코드를 작성해 보도록 합니다.

#//---------------------------------------------------//
class MaTradeStrategy(TradeStrategy):  
    def __init(self, fast = "ema5", slow = "ema20"):
        self.MA_FAST = fast
        self.MA_SLOW = slow

    def __crossUp(self, timeIdx):
        if timeIdx < 1:
            return False

        chartData = self.stockData_.chartData_
        prevCandle = chartData.iloc[timeIdx - 1]
        fast = prevCandle[self.MA_FAST]
        slow = prevCandle[self.MA_SLOW]
        if fast < slow:
            nowCandle = chartData.iloc[timeIdx]
            fast = nowCandle[self.MA_FAST]
            slow = nowCandle[self.MA_SLOW]

            if fast > slow:
                return True

        return False

    def __crossDown(self, timeIdx):
        if timeIdx < 1:
            return False
            
        chartData = self.stockData_.chartData_
        prevCandle = chartData.iloc[timeIdx - 1]
        fast = prevCandle[self.MA_FAST]
        slow = prevCandle[self.MA_SLOW]
        if fast > slow:
            nowCandle = chartData.iloc[timeIdx]
            fast = nowCandle[self.MA_FAST]
            slow = nowCandle[self.MA_SLOW]

            if fast < slow:
                return True

        return False

    def buy(self, timeIdx):
        if self.stockData_.position_ == BuyState.STAY:
            if self.__crossUp(timeIdx):
                return True
        return False

    def sell(self, timeIdx):
        if self.stockData_.position_ == BuyState.STAY:
            if self.__crossDown(timeIdx):
                return True
        return False

    def buyList(self):
        signalList = []
        signalList.append(np.nan)
        chartData = self.stockData_.chartData_

        for i in range(1, len(chartData)):
            nowCandle = chartData.iloc[i]
            if self.__crossUp(i):
                signalList.append(nowCandle["close"])
            else:
                signalList.append(np.nan)

        return signalList

    def sellList(self):
        signalList = []
        signalList.append(np.nan)
        chartData = self.stockData_.chartData_

        for i in range(1, len(chartData)):
            nowCandle = chartData.iloc[i]
            if self.__crossDown(i):
                signalList.append(nowCandle["close"])
            else:
                signalList.append(np.nan)

        return signalList       

 

 

코드 읽어 보시면 느낌이 오실 거라 생각합니다.

42라인으로 외부에서 buy 함수 호출되면, 내부적으로 __crossUp 이란 함수를 호출하고, __crossUp이 정의된 6라인을 보시면, 지금 캔들과, 전 캔들의 ema 값을 갖고 와서 이들이 크로스 하고 있는지 체크합니다.

buyList /sellList는 이 buy 함수와 sell 함수의 연장선으로 각 캔들 데이터에 buy / sell 시그널을 붙여 주기 위해 사용합니다.

전에 주식 차트를 출력하기 위한 printChart.py 에서 사용하는 [buySignal] [sellSignal]의 데이터를 만들어 줍니다.

'재테크 > 주식 알람 시스템 만들기' 카테고리의 다른 글

8-3. 단기 변동성 돌파 전략  (0) 2020.11.08
8-2. MACD 전략  (0) 2020.11.08
8-1. 골든 크로스 전략  (0) 2020.11.08
8. 매매 전략에 대해서  (0) 2020.11.08
7. 유틸 함수들  (0) 2020.11.08
6. 메시지 알람 (텔레그램)  (0) 2020.11.08

소스파일은 github.com/galaxywiz/StockCrawler_py 에서 확인 가능합니다.

 

지금 까지가 차량의 보디 제작이었다고 하면, 이제 차량의 성능과 직관 되는 엔진이라 할 수 있는 매매 로직에 대한 기술입니다.

이전 코드들은 어떻게 보면, 프로그래밍 관점에서 이런 저런 기능들을 넣은 거라 하면, 이제부터는 주식 시장 관점에서 어떻게 하면 ohlc 데이터로 매수 매도 신호를 잡을 수 있는지 고민해 보면서 작성하는 파트가 되겠습니다.

우선 아래처럼 특정 폼을 만들어 줍니다. (매수/매도 시그널, 매수/매도 리스트 갖고 오기)

 

tradeStrategy.py

import numpy as np
from stockData import StockData, BuyState

#//---------------------------------------------------//
class TradeStrategy:
    def setStockData(self, stockData):
        self.stockData_ = stockData

    def buy(self, timeIdx):
        pass

    def sell(self, timeIdx):
        pass

    def buyList(self):
        pass

    def sellList(self):
        pass

이렇게 폼 (이쪽 용어론 추상 클래스)을 만드는 이유는 다른 클래스가 이 클래스를 사용시 어떻게 동작할지 정해지지 않지만, 외부에선 호출할 필요가 있기 때문에 사용합니다.

 

예를 들어, 오늘 저녁에 치킨을 시켜 먹자고 합시다.
가족들에겐 오늘 치킨 시켜 먹을꺼니까 저녁 준비 하지 말라고 알려줍니다.
그리고 이제 주문을 하는데, 치킨은 여러 종류가 있죠. 양념, 간장, 치즈, 파닭, 후라이드
그리고 그 세세한 부분을 주문하고 나중에 XX치킨이 배달되어 오겠죠.

 

이런 느낌이라고 보시면 됩니다. 이 다음에 만드는 Bot 프로그램에서, 전략을 불러오는데,

어떤 전략인지는 모르겠고, 매수/매도 함수만 통일시켜 줍니다.


그리고 기술지표 시그널을 사용해서 다양한 조합을 만들어 주면 되는데,

이 부분은 각자 생각해온 그런 전략이 있을 것이고, 거기에 맞게 여기만 코딩을 해주면,

마치 치킨은 치킨인데 어떤 양념을 통해서 맛있게 만든 치킨인지,

실패한 맛의 치킨인지를 주식 시장이 결정해 주게 됩니다.

 

여기서는 간단하면서 강력한(많은 사람들이 쓰는) 3가지 시그널에 대해서 작성해 보도록 하겠습니다.

이동평균선이 골드 크로스 하는지 파악하는 전략,

MACD 시그널을 이용한 전략,

마지막으로 레리 윌리엄스 란 분이 창안하신 변동성 돌파 전략에 대해서 기술해 보겠습니다.

 

'재테크 > 주식 알람 시스템 만들기' 카테고리의 다른 글

8-2. MACD 전략  (0) 2020.11.08
8-1. 골든 크로스 전략  (0) 2020.11.08
8. 매매 전략에 대해서  (0) 2020.11.08
7. 유틸 함수들  (0) 2020.11.08
6. 메시지 알람 (텔레그램)  (0) 2020.11.08
5. 주식 차트 그리기  (0) 2020.11.08

+ Recent posts