Computer >> 컴퓨터 >  >> 프로그램 작성 >> Redis

RedisTimeSeries에서 금융 애플리케이션 구축

일반적으로 세상에는 두 가지 유형의 투자자가 있습니다. 기본 투자자 회사에 투자할지 여부를 결정할 때 회사의 비즈니스 모델, 수익, 수익, 현금 흐름, 현재 평가, 위험 및 성장 전망과 같은 기본 지표를 살펴봅니다. 워렌 버핏은 기초 연구를 통해 저평가된 기업을 찾아 세계 최고의 부자가 되었습니다.

한편, 기술 투자자 회사의 펀더멘털에 거의 또는 전혀 관심을 기울이지 않고 수백 가지 기술 지표에서 매수, 매도, 보유 신호를 도출하는 데 집중합니다. 이러한 기술 투자자는 매일, 매주 또는 매월 거래합니다.

저는 여기에서 이러한 투자 스타일에 대해 찬성하거나 반대하는 것이 아닙니다. 그러나 기본 투자자와 기술 투자자 모두 수천은 아닐지라도 수백 개의 데이터 소스를 기반으로 연구, 분석 및 결정을 내립니다.

기본 투자자는 전 세계 수천 개의 회사와 수백 개의 산업에 걸쳐 대차 대조표, 손익 계산서, 현금 흐름표, 인구 통계학적 추세, 주제별 추세 및 사회적 추세를 연구합니다. 그들은 회사의 궤적과 회사의 성장 전망을 더 잘 이해하기 위해 해당 데이터 위에 재무 모델 또는 분석을 구축합니다.

기술 투자자는 수백 개의 기술 지표를 매시간 또는 매일 확인하여 투자 신호를 도출합니다. 기술 지표에 의존하는 투자자는 거래 전략을 수립하기 위해 여러 기간에 걸쳐 방대한 데이터를 처리해야 합니다. 그들은 방대한 수의 지표를 쿼리해야 하고 사실상 즉각적인 답변이 필요할 수 있습니다. 그들은 빠르게 변화하는 시장에 알고리즘과 거래 전략을 신속하게 적용해야 할 수도 있습니다. Redis Enterprise는 이러한 모든 문제를 해결할 수 있습니다.

최근에 Redis Enterprise가 금융 산업에 필수적인 도구인 이유에 대해 썼습니다. 이 블로그 게시물에서는 RedisTimeSeries를 사용하여 주가와 기술 지표를 저장, 집계 및 쿼리하는 방법을 보여 드리겠습니다. 내가 개략적으로 설명할 원칙은 회사의 재무 정보 또는 기본 투자자가 사용하는 기타 시계열 데이터를 저장하고 쿼리하는 데에도 사용할 수 있습니다.

RedisTimeSeries 모듈은 수백만 개의 이벤트, 샘플 및 가격 데이터를 수집하고 쿼리할 수 있습니다. RedisTimeSeries는 IoT에서 의료, 금융에 이르는 사용 사례의 추세를 파악하는 데 도움이 되도록 관련 시간 및 값 쌍을 저장하는 데 가장 적합합니다. RedisTimeSeries는 평균, 합계, 최소값, 최대값, 표준 편차, 범위 등과 같은 집계를 제공하여 데이터를 쉽게 분석하고 결정을 내릴 수 있도록 도와줍니다.

RedisTimeSeries로 주가 추적

이 게시물에서는 RedisTimeSeries를 사용하여 주가와 기술 지표를 저장하는 모델을 설명하겠습니다. 가격 및 지표에 대한 다양한 시계열 생성을 다루고, 원시 시계열 위에 집계를 생성하는 방법을 보여주고, 다양한 RedisTimeSeries 명령을 사용하여 대량 시계열을 얼마나 쉽게 수집하고 쿼리할 수 있는지 보여줍니다. 또한 고유한 사용 사례의 시작점으로 사용할 수 있는 샘플 코드를 Python으로 제공했습니다.

옳든 그르든 많은 사람들은 다우존스 산업평균지수(DJIA)를 미국 경제의 전조라고 생각합니다. DJIA의 모든 30개 주식에 대한 기술적 지표를 해당 주식의 가격 및 거래량과 함께 추적하고 싶습니다. 나는 Dow-component Goldman Sachs의 주가와 그 주식에 대한 기술 지표 중 하나를 추적함으로써 일을 시작합니다. 내가 가장 좋아하는 기술 지표 중 하나는 상대 강도 지수(RSI)입니다. RSI는 과매수 또는 과매도 영역에 있을 수 있는 주식을 측정하는 데 사용되는 모멘텀 지표입니다. RSI가 30 근처 또는 아래로 이동하면 주식이 과매도된 것으로 간주되어 매수 기회가 될 수 있습니다. 마찬가지로 RSI가 70 이상으로 이동하면 과매수 영역에 진입하고 좋은 매도 시기를 알리는 신호일 수 있습니다.

골드만 삭스 그룹의 상대 강도 지수

RedisTimeSeries에서 금융 애플리케이션 구축

거래 시간 동안 RSI는 다른 기술 지표와 마찬가지로 Goldman Sachs 주식의 수요와 공급에 따라 거래가 실행됨에 따라 달라집니다. RedisTimeSeries 모듈을 사용하여 다음과 같은 여러 주요 질문에 답할 수 있습니다. 

  • 각 지정된 시간 간격에 대한 기술 지표의 최소값과 최대값은 얼마입니까?
    • 이렇게 하면 거래의 진입점 또는 퇴장점을 빠르게 찾을 수 있습니다.
  • 특정 기간 동안 주가의 범위와 표준편차는 얼마입니까?
    • 범위와 표준편차는 기초 주가의 변동성을 나타내는 지표입니다.
  • 이 주식 거래의 수익성 있는 진입 및 퇴출 가격은 얼마입니까?
  • 특정 기간 동안 모든 주식에 대한 기술적 지표의 가치는 얼마입니까?

RedisTimeSeries 쿼리를 사용하여 지정된 기간 동안 최소 및 최대 RSI 값과 주가를 프로그래밍 방식으로 식별할 수 있습니다. 예를 들어, 거래일의 각 15분 기간 동안 최소 및 최대 RSI 숫자를 찾으려면 어떻게 해야 합니까? RSI가 30에 가까우면 경고를 생성하거나 거래를 하거나 다른 복잡한 거래 워크플로를 시작하여 매수 또는 매도 전에 다른 기술 지표를 분석할 수 있습니다. 원하는 모든 작업을 RedisTimeSeries 데이터베이스에서 쉽게 모델링할 수 있습니다.

주가 및 기술 지표에 대한 데이터 모델 

RedisTimeSeries에 대한 실습 경험을 얻는 가장 쉬운 방법은 RedisTimeSeries용 Docker 이미지를 실행하는 것입니다.

다음 명령을 실행하여 Docker 이미지를 가져와 실행합니다.

도커 실행 -p 6379:6379 -it --rm redis/redistimeseries

Redis 팀은 RedisTimeSeries 모듈이 각 시계열에 단일 메트릭을 보유하도록 신중한 설계 결정을 내렸습니다. 데이터 모델의 이러한 단순성은 데이터의 삽입 및 검색을 초고속으로 만듭니다. 기존 애플리케이션 중단에 대한 걱정 없이 필요에 따라 새 시계열을 추가할 수 있습니다. 즉, 데이터베이스 스키마나 애플리케이션을 손상시킬 염려 없이 새 데이터 소스를 쉽게 추가할 수 있습니다.

RedisTimeSeries 컨테이너를 실행하고 다음과 같이 Python을 사용하여 서버에 연결할 수 있습니다(올바른 IP 주소 또는 호스트 이름이 있는지 확인).

redistimeseries.client에서 가져오기 클라이언트 rts =Client(host='127.0.0.1', 포트=6379)

각 시계열에 단일 메트릭을 유지하는 설계 원칙에 따라 각 DJIA 주식에 대한 일중 주가와 RSI를 자체 시계열에 저장할 수 있습니다. 아래에 Goldman Sachs Group, Inc.(NYSE:GS)의 시계열을 만들었습니다. 저는 Goldman Sachs의 일중 RSI를 'DAILYRSI:GS'로 지정했습니다. 그리고 각 시계열에 다양한 레이블을 적용했습니다. 시계열에 레이블을 지정하면 레이블을 사용하여 모든 키를 쿼리할 수 있습니다.

rts.create ( 'dailyrsi :gs', labels ={ 'symbol':'gs', 'desc':'realative_strength_index', 'index':'djia', 'timeframe':'1_day', '표시기 ':'RSI'                   , 'COMPANYNAME':'GOLDMAN_SACHS_GROUP'})

여기에서 'INTRADAYPRICES:GS'라는 Goldman Sachs의 장중 주가에 대한 시계열을 만들었습니다. :

rts.create ( 'intradayPrices :gs', labels ={ 'symbol':'gs', 'desc':'share_price', 'index':'djia', 'pricetype':'Intraday', 'CompanyName ':'GOLDMAN_SACHS_GROUP'})

다음으로 특정 15분 시간 프레임 내에서 RSI 데이터에 대한 다양한 집계를 만들었습니다. (우리는 거래 요구에 맞게 더 길거나 더 짧은 시간 프레임에 집계를 만들 수 있었습니다.) 이러한 집계를 통해 RSI의 처음, 마지막, 최소, 최대 및 범위 값을 볼 수 있습니다. 집계를 만들려면 먼저 집계를 저장할 시계열을 만든 다음 집계된 값으로 시계열을 채우는 규칙을 만듭니다. 이 경우 'DAILYRSI15MINRNG:GS'라는 시계열을 만들었습니다. 15분 이내에 RSI 범위를 저장합니다. '생성 규칙' 원시 데이터에 범위 함수 적용('DAILYRSI:GS' ) 각 15분 동안 이를 'DAILYRSI15MINRNG:GS'로 집계합니다. .

rts.create ( 'dailyrsi15minrng :gs', labels ={ 'symbol':'gs', 'desc':'realative_strength_index', 'index':'djia', 'timeframe':'15_minutes', 'Aggregation ':'RANGE'                    , 'INDICATOR':'RSI'                    , 'COMPANYNAME':'GOLDMAN_SACHS_GROUP'}) rts.createrule('GOLDMAN_SACHS_GROUP'}) rts.createrule('DAILYRS'

여기에서 거래일 중 각 15분 간격 동안 Goldman Sachs 주가의 범위와 표준 편차를 계산하는 몇 가지 규칙을 만들었습니다.

rts.create ( 'intradayPrices15minrng :gs', labels ={ 'symbol':'gs', 'desc':'share_price', 'index':'djia', 'pricetype':'range', 'Aggregation ':'Range ','duration ':'15_minutes ','CompanyName ':'goldman_sachs_group '}) rts.createrule ('intradayPrices :gs ','intradayPrices15minrng :gs ','범위 ', 900) rts.create (' intradayPrices15MINSTDP :gs ', labels ={'symbol ':'gs ','desc ':'share_price ','index ':'djia ','pricetype ':'stddev ','Aggregation ':'stddev ','duration ':'15_MINUTES'                   , 'COMPANYNAME':'GOLDMAN_SACHS_GROUP'})rts.createrule( 'INTRADAYPRICES:GS',p           

비슷한 방식으로 DJIA(Dow Jones Industrial Average)의 30개 주식 모두에 대한 시계열을 만들 수 있습니다.

데이터 수집 방법  

RedisTimeSeries에 데이터를 수집하는 두 가지 방법이 있습니다. TS.ADD 명령을 사용하면 시계열에 각 주가 또는 기술 지표를 추가할 수 있습니다. 그러나 금융시장의 데이터는 거의 지속적으로 생성되고 RedisTimeSeries에 여러 샘플을 추가해야 하므로 TS.MADD를 사용하는 것이 좋습니다. 방법. MADD 함수는 튜플 목록을 인수로 사용합니다. 각 튜플은 시계열 키의 이름, 타임스탬프 및 값을 사용합니다.

RedisTimeSeries에서 금융 애플리케이션 구축

다음 Python 명령을 사용하여 시계열 키에 데이터를 삽입할 수 있습니다.

rts.madd()

RedisTimeSeries 쿼리

RedisTimeSeries의 대부분의 경우와 마찬가지로 데이터베이스를 쿼리하는 것은 쉽습니다. 주가 또는 기술 지표의 범위 및 표준 편차는 변동성을 나타냅니다. 다음 쿼리를 사용하면 15분 간격 내에서 Goldman Sachs 주가의 가격 범위와 표준 편차를 볼 수 있습니다.

rts.range( 'INTRADAYPRICES15MINRNG:GS'          , from_time =1603704600          , to_time   =1603713600)

범위 집계에 대한 이 쿼리는 다음과 같은 결과 집합을 제공합니다.

[(1603704600, 1.75999999999999), (1603705500, 0.775000000000006), (1603706400, 0.730000000000018), (1603707300, 0.449999999999989), (1603708200, 0.370000000000005), (1603709100, 1.01000000000002), (1603710000, 0.490000000000009), (1603710900, 0.89500000000001 ), (1603711800, 0.629999999999995), (1603712700, 0.490000000000009), (1603713600, 0.27000000000001) 

이 쿼리 결과에서 볼 수 있듯이 2020년 10월 26일 오전 9시 30분(동부 표준시)(정수 타임스탬프 =1603704600)에 거래일이 시작될 때 Goldman Sachs 주식은 변동성이 높아 $1.75 범위에서 거래되었습니다. 이제 이것을 10월 26일 오전 9시 45분(정수 타임스탬프 =1603705500)부터 시작하여 변동성이 $0.77 범위에서 떨어진 다음 15분과 비교하십시오. Goldman Sachs 주식의 가격 범위는 이후 15분 간격으로 계속 하락했으며 변동성은 개장 15분 간격 동안 도달한 수준으로 돌아오지 않았습니다.

RedisTimeSeries의 이 데이터는 대시보드와 차트에서 쉽게 시각화할 수 있습니다. 아래 차트는 15분 간격으로 Goldman Sachs의 가격 범위를 보여줍니다.

RedisTimeSeries에서 금융 애플리케이션 구축

아래 차트는 동일한 데이터를 꺾은선형 차트 형식으로 보여주며, 이는 Goldman Sachs가 거래하는 가격 범위가 시간이 지남에 따라 훨씬 더 좁아짐을 나타냅니다(이 차트는 x축에 정수 타임스탬프를 보여줍니다).

RedisTimeSeries에서 금융 애플리케이션 구축

집계 함수로 다른 변동성 측정(표준 편차)을 사용하여 유사한 쿼리를 수행할 수 있습니다.

rts.range( 'INTRADAYPRICES15MINSTDP:GS'          , from_time =1603704600          , to_time   =1603713600)
[(1603704600, 0.54657783830434), (1603705500, 0.23201149395202), (1603706400, 0.196072381345986), (1603707300, 0.160267138157647), (1603708200, 0.116990621700049), (1603709100, 0.28043101744222), (1603710000, 0.144379900126934), (1603710900, 0.327611558618967 ), (1603711800, 0.163118915546951), (1603712700, 0.151417199675549), (1603713600, 0.0963889432)84320 

이것은 많은 흥미로운 가능성을 열어줍니다. 일중 RSI 값이 30과 40 사이일 때 Goldman Sachs 주식의 가격을 알고 싶다고 가정해 보겠습니다. RSI에 대한 시계열과 주가의 시계열을 쿼리하여 거래의 수익성 있는 진입점을 식별할 수 있습니다.

여기에서 1605260100(2020년 11월 13일 오전 9:35 동부 표준시)에서 1605260940(당일 오전 9:49 동부 표준시) 사이의 시간 프레임에서 Goldman Sachs의 RSI 값을 쿼리하고 있습니다.

dailyGSRSIValue =rts.range( 'DAILYRSI:GS'                           , from_time =1605260100 )                          5,             

쿼리는 RSI 값이 1605260820(동부 표준시 오전 9시 47분)에 34.2996427544861임을 찾습니다.

[(1605260100, 75.0305441024708), (1605260160, 81.6673948350152), (1605260220, 83.8852225932517), (1605260280, 85.9469082344746), (1605260340, 94.3803586011592), (1605260400, 92.2412262502652), (1605260460, 85.6867329371465), (1605260520, 87.9557361513823 ), (1605260580, 89.9407873066781), (1605260640, 57.1512452602676), (1605260700, 50.5638232111769), (1605260760, 35.2804436894564), (1605260820, 34.2996427544861), (1605260880, 54.5486275202972), (1605260940, 64.7593307385219)]

이제 RSI 쿼리에 사용된 것과 동일한 간격으로 Goldman Sachs의 일중 가격을 쿼리하거나 RSI 값이 34.29일 때를 반영하도록 쿼리를 프로그래밍 방식으로 변경할 수 있습니다. 다음은 RSI 쿼리와 동일한 기간을 사용하는 예입니다.

dailyGSPrice =rts.range( 'INTRADAYPRICES:GS'                        , from_time =1605260100                                        , to_40 

쿼리는 지정된 범위에 대한 Goldman Sachs의 주가를 반환합니다. 1605260820(2020년 11월 13일 오전 9시 47분 ET 기준) 가격은 $217.18입니다.

[(1605260100, 216.57), (1605260160, 216.73), (1605260220, 217.08), (1605260280, 217.17), (1605260340, 217.87), (160526), ​​(160526), ​​(218.052) ), (1605260580, 218.11), (1605260640, 218.02), (1605260700, 217.72), (1605260760, 217.22), (1605260820, 217.18), (1605260), (1605260), (1605260)

RedisTimeSeries는 한 번에 여러 시계열을 쿼리할 수 있는 강력한 방법을 제공합니다. TS.MGET 명령을 사용하면 필터를 사용하여 여러 시계열에서 쿼리할 수 있습니다. 우리는 이미 다양한 시계열을 만들고 레이블을 부착했습니다. 이제 이러한 레이블은 시계열 전체에서 쿼리하는 필터 역할을 할 수 있습니다.

다음 Python 코드는 "DESC" 및 "TIMEFRAME"라는 두 개의 레이블을 기반으로 두 개의 필터를 적용합니다. 매개변수 “with_labels=False” 각 값에 대한 레이블 없이 결과 세트를 반환할 수 있습니다.

allRSIValues ​​=rts.mget(filters=['DESC=RELATIVE_STRENGTH_INDEX','TIMEFRAME=1_DAY'], with_labels=False)

이 쿼리는 여기에 표시된 것과 유사한 결과를 표시하며 여러 주식에 대한 마지막 RSI 값을 반환합니다.

<이전>[{'DAILYRSI:BA':[{}, 1605261060, 62.2048922111768]}, {'DAILYRSI:CAT':[{}, 1605261060, 68.3834400302'296'LYRS [, 59.2107333830133]}, {'DAILYRSI:CSCO':[{}, 1605261060, 52.7011052724688]}, {'DAILYRSI:CVX':[{}, 190526106 [1605261060, 73.597680480764]}, {'DAILYRSI:GS':[{}, 1605283140, 41.182852552541]}, {'DAILYRSI:IBM':[{}, 1060 [, 1605261060, 77.7760292843745]}, {'DAILYRSI:KO':[{}, 1605261060, 26.8638381005608]}, {'DAILYRSI:MMM16. }, 1605261060, 38.9991886598036]}, {'DAILYRSI:UNH':[{}, 1605261060, 74.26724228885775]}, {0'DAILYRSI:2672428885775]}, {0'DAILYRSI:211':6 {}, 1605261060, 47.3877762365391]}]

“with_labels=True”를 설정했다면 , 그러면 다음과 같이 결과에 각 시계열의 모든 레이블이 포함됩니다.

[{'DAILYRSI:BA':[{'SYMBOL':'BA', 'DESC':'RELATIVE_STRENGTH_INDEX', 'INDEX':'DJIA', 'TIMEFRAME':'1_DAY', 'INDICATOR':' RSI', 'COMPANYNAME':'BOEING'}, 1605261060, 62.2048922111768]}, {'DAILYRSI:CAT':[{'SYMBOL':'CAT', 'DESC':'RELATIVE_STRENGTH_INDEX'':' , 'TIMEFRAME':'1_DAY', '표시기':'RSI', 'COMPANYNAME':'CATERPILLAR'}, 1605261060, 68.3834400302296]}, {'DAILYRSI:CRMOL',':[{''CRMOL DESC':'RELATIVE_STRENGTH_INDEX', 'INDEX':'DJIA', 'TIMEFRAME':'1_DAY', 'INDICATOR':'RSI', 'COMPANYNAME':'SALESFORCE'}, 1605261060, 1339.281}0739.211 

결론

이 블로그 게시물은 시계열 데이터에 의존하는 금융 애플리케이션을 유연하게 구축하기 위한 RedisTimeSeries의 여러 명령 중 일부를 설명했습니다. 예를 들어, 주식 거래자는 수십 가지 변수를 기반으로 실시간으로 중요한 결정을 내릴 수 있어야 합니다. RedisTimeSeries는 스키마가 없습니다. 즉, 스키마를 정의하지 않고 데이터를 로드하거나, 새 필드를 즉시 추가하거나, 비즈니스 상황이 변경될 경우 데이터 모델을 변경할 수 있습니다. 실시간 성능과 간단한 개발자 경험 덕분에 시계열 데이터 작업이 재미있습니다!

여기에서 GitHub의 이 블로그 게시물에 대한 샘플 코드를 찾을 수 있습니다. 여기에서 RedisTimeSeries에 대해 자세히 알아볼 수 있습니다.