[ Splunk Project ] Splunk๋กœ ์ฃผ์‹ ๋ถ„์„ | Phase 11. ์ฃผ์‹ ๋งค๋งค ์‹œ๋ฎฌ๋ ˆ์ด์…˜
๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Splunk/Splunk Project

[ Splunk Project ] Splunk๋กœ ์ฃผ์‹ ๋ถ„์„ | Phase 11. ์ฃผ์‹ ๋งค๋งค ์‹œ๋ฎฌ๋ ˆ์ด์…˜

728x90
๋ฐ˜์‘ํ˜•

๐ŸŒž TODAY'S GOAL๐ŸŒž

    ๐Ÿ‡ ์ฃผ์‹ ๋งค๋งค ์ „๋žต์„ ์„ธ์šฐ๊ณ ,

    ๐Ÿ‡ ๋งค์ผ ์ •ํ•ด์ง„ ์‹œ๊ฐ„์— ์ฃผ์‹์„ (๊ฐ€์ƒ์œผ๋กœ) ๋งค๋งคํ•˜๊ณ ,

    ๐Ÿ‡ ๋งค๋งคํ•œ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ๊ธฐ๋กํ•˜๊ณ ,

    ๐Ÿ‡ ์•Œ๋ฆผ ์„ค์ •

 

 

๐ŸŒณ STEP 0 ๐ŸŒณ readstock ๋ช…๋ น์„ ๋‹ค์Œ์ฒ˜๋Ÿผ ์—…๋ฐ์ดํŠธ

    def generate(self):
        url = self.url.format(self.code)
        self.logger.info("Generating event with code %s" % (self.code))
        with urlopen(url) as doc:
            content = doc.read()
            content = content.decode('utf-8', 'ignore')
            soup = BeautifulSoup(content, 'lxml')
            cur_price = soup.find('strong', id='_nowVal').text.replace(",", "")
            cur_rate = soup.find('strong', id='_rate').text.strip()
            cur_time = soup.find('span', id='time').text.strip()
            #stock = soup.find('title')
            stock_name = self.code

        raw = {"price": cur_price, "rate": cur_rate, "code":stock_name, "time":cur_time }
        yield {'_time': time.time(), '_raw': raw}

 

๐ŸŒณ STEP 0 ๐ŸŒณ Phase 10์˜ ML์„ ์นดํ…Œ๊ณ ๋ฆฌ ์„ ์ • ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ
                           ๊ฐ’ ์˜ˆ์ธก ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋ณ€๊ฒฝ

index="kospi" code="$code$.KS" earliest=0
| sort _time  
| `mylag(Close, 10)` 
| table _time, Close, lag_* 
| where isnotnull(lag_9)
| fit StandardScaler "lag_0" "lag_1" "lag_2" "lag_3" "lag_4" "lag_5" "lag_6" "lag_7" "lag_8" "lag_9" "Close" with_mean=true with_std=true into "model_stock_predict_SS_$code$"
| fit RandomForestRegressor "SS_Close" from "SS_lag_0" "SS_lag_1" "SS_lag_2" "SS_lag_3" "SS_lag_4" "SS_lag_5" "SS_lag_6" "SS_lag_7" "SS_lag_8" "SS_lag_9" into "model_stock_predict_RF_$code$"

์ด๋ฅผ apply ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ "predict_stock_with_ml: ML์„ ์ด์šฉํ•œ ์˜ˆ์ธก" ๋ฅผ ์ฐธ์กฐํ•˜์ž.

ํ•ด๋‹น savedsearch ๋Š” ์‰˜์„ ๋งŒ๋“ค๊ณ  linux cron ์„ ์ด์šฉํ•ด ๋งค ์ฃผ ํ•œ๋ฒˆ ์‹คํ–‰ํ•ด์„œ ๋ชจ๋ธ์„ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.

โ€‹

$ vi run_build_model.sh

#!/bin/sh

home=/data/prj/stock

curl -k -u admin:changeme https://localhost:8089/servicesNS/admin/stock/search/jobs/export -d search="| inputlookup my_stock | table code" -d "output_mode=csv" -o "${home}/mystock.csv"

while read line; do
        code=${line}
        if [ ${code} != "code" ]; then
                curl -k -u admin:changeme https://localhost:8089/servicesNS/admin/stock/search/jobs/export -d search="savedsearch make_ml_model%20code%3D$code" >> ${home}/logs/buildmodel_`date '+%y%m%d'`.log
        fi

done < ${home}/mystock.csv

 

 

 

 

๐ŸŒณ STEP 1 ๐ŸŒณ Key-Value Store ์ถ”๊ฐ€

      ๋จผ์ € ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์—…๋ฐ์ดํŠธ ํ•  ๊ณต๊ฐ„์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค.

 

Lookup ์—์„œ "key-value" ์Šคํ† ์–ด๋ฅผ ์ •์˜ํ•ด ์ฃผ์—ˆ๋‹ค. (3์žฅ ์ฐธ์กฐ)

$ vi $SPLUNK_HOME/etc/apps/stock/local/collections.conf

[my_asset_history]

๐Ÿณ my_asset_history ๐Ÿณ

       ํ†ต์žฅ๊ณผ ๋น„์Šทํ•œ ์—ญํ• ๋กœ ํ˜„์žฌ ๊ณ„์ขŒ์— ์žˆ๋Š” ํ˜„๊ธˆ๊ณผ ์ฃผ์‹ ๋งค๋งค์‹œ ๋งค๋งค๋œ ๋‚ด์—ญ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํ† ์–ด

       ๐Ÿ”น date: ๊ฑฐ๋ž˜ ๋œ ์‹œ๊ฐ„

       ๐Ÿ”น balance: ๊ณ„์ขŒ ์ž”์•ก

       ๐Ÿ”นcode: ์ฃผ์‹ ์ฝ”๋“œ

       ๐Ÿ”น method: "BUY or SELL" ๊ธฐ๋ก

       ๐Ÿ”น count: ๋งค๋งคํ•œ ์ฃผ์‹ ๊ฐฏ์ˆ˜

       ๐Ÿ”น cost: ๋งค๋งคํ•œ ๊ฑฐ๋ž˜ ์•ก์ˆ˜

 

๐Ÿณ my_stock ๐Ÿณ

       ํ˜„์žฌ ์ฃผ์‹ ๋ณด์œ  ์ˆ˜๋Ÿ‰ ๋ฐ ๋ชฉํ‘œ ๊ธฐ๋ก

       ๐Ÿ”นcode: ์ฃผ์‹ ์ฝ”๋“œ

       ๐Ÿ”น interest: "0 or 1" ๊ด€์‹ฌ ์ข…๋ชฉ ํ”Œ๋ž˜๊ทธ

       ๐Ÿ”น share: ๋ณด์œ  ์ฃผ์‹ ์ˆ˜

       ๐Ÿ”น target: ๋ชฉํ‘œ ์ฃผ์‹ ๋น„์œจ (ํฌํŠธํด๋ฆฌ์˜ค ์ƒ์„ฑ ์‹œ ๊ฒฐ์ •)

 

 

๐Ÿณ stock_ml_predict ๐Ÿณ

      ML์„ ํ†ตํ•œ ์ฃผ์‹ ์˜ˆ์ธก(10์žฅ ์ฐธ์กฐ)

       ๐Ÿ”นdate: ์˜ˆ์ธก ์‹คํ–‰ํ•œ ๋‚ ์งœ

       ๐Ÿ”นcode: ์ฃผ์‹ ์ฝ”๋“œ

       ๐Ÿ”นclose: ์˜ˆ์ธกํ•œ ์‹œ์ ์˜ ์ข…๊ฐ€

       ๐Ÿ”นpredict: ์˜ˆ์ธก ๊ฐ€๊ฒฉ

 

 

๐Ÿณ stock_predict ๐Ÿณ

      predict ๋ฌธ์„ ํ†ตํ•œ ์ฃผ์‹ ์˜ˆ์ธก (5์žฅ ์ฐธ์กฐ)

       ๐Ÿ”นdate: ์˜ˆ์ธก ์‹คํ–‰ํ•œ ๋‚ ์งœ

       ๐Ÿ”นcode์ฃผ์‹ ์ฝ”๋“œ

       ๐Ÿ”นprice: ์˜ˆ์ธกํ•œ ์‹œ์ ์˜ ์ข…๊ฐ€

       ๐Ÿ”นpredict: ์˜ˆ์ธก ๊ฐ€๊ฒฉ

       ๐Ÿ”นexpected_value: 5์ผ ํ›„ ๊นŒ์ง€ ์˜ˆ์ƒ๋˜๋Š” ๊ฐ€๊ฒฉ ๋ณ€ํ™”์œจ

 

 

๐Ÿณ stock_statics_predict ๐Ÿณ

     ์‚ผ์ค‘์ฐฝ์„ ํ†ตํ•œ ์ฃผ์‹ ์˜ˆ์ธก (9์žฅ ์ฐธ์กฐ)

       ๐Ÿ”นdate: ์˜ˆ์ธก ์‹คํ–‰ํ•œ ๋‚ ์งœ

       ๐Ÿ”นcode์ฃผ์‹ ์ฝ”๋“œ

       ๐Ÿ”นclose: ์˜ˆ์ธกํ•œ ์‹œ์ ์˜ ์ข…๊ฐ€

       ๐Ÿ”นstep1: 1 ์ฐฝ์„ ํ†ตํ•œ ์ „๋žต

       ๐Ÿ”นstep2: 2 ์ฐฝ์„ ํ†ตํ•œ ์ „๋žต

       ๐Ÿ”นstep3: 3 ์ฐฝ์„ ํ†ตํ•œ ์ „๋žต

       ๐Ÿ”นslow_d: ๋‹จ๊ธฐ ํ˜„์žฌ ๊ฐ€๊ฒฉ ํ‰๊ฐ€ ์ง€์ˆ˜

 

 

๐Ÿณ today_target ๐Ÿณ

     ์˜ค๋Š˜ ๋ชฉํ‘œ ์ „๋žต

       ๐Ÿ”นcode์ฃผ์‹ ์ฝ”๋“œ

       ๐Ÿ”นbuy: ๋งค๋งคํ•  ๋ชฉํ‘œ ์ฃผ์‹ ์ˆ˜ (BUY/SELL)

       ๐Ÿ”นpredict: ๊ธˆ์ผ ๋ชฉํ‘œ ์˜ˆ์ƒ ์ฃผ๊ฐ€

 

์ž˜ ๋“ค์–ด๊ฐ„ ๊ท€์—ผ๋‘ฅ์ด๋“ค 1
์ž˜ ๋“ค์–ด๊ฐ„ ๊ท€์—ผ๋‘ฅ์ด๋“ค 2

 

 

๐ŸŒณ STEP 2๐ŸŒณ ์˜ˆ์ธก ๋‚ด์šฉ ์ €์žฅ ์Šค์ผ€์ฅด ๋งŒ๋“ค๊ธฐ

         savedsearch๋ฅผ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ ์Šค์ผ€์ฅด๋ง์— ๋“ฑ๋กํ•ด ๋งค์ผ ์ƒˆ๋กœ์šด ์˜ˆ์ƒ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค๋„๋ก ํ•œ๋‹ค.

 

 

๐Ÿณ stock_predict ๐Ÿณ

      predict ๋ฌธ์„ ํ†ตํ•œ ์ฃผ์‹ ์˜ˆ์ธก (5์žฅ ์ฐธ์กฐ)

| inputlookup my_stock | map search="
| search index=kospi code=$code$.ks earliest=-365d
| sort _time
| predict "Close" as prediction algorithm=LLT future_timespan=5 upper95=upper95 lower95=lower95
| eventstats latest(Close) as f_close, latest(Date) as f_date, latest(code) as code
| stats latest(f_date) as date, latest(f_close) as Close, latest(prediction) as predict by code
| eval predict = round(predict, 0)
| eval expected_value = round(((predict - Close) / Close)* 100, 2)
"
| rex field=code "^(?<code>\d+).KS"
| eval _key = date + "_" + code
| rename Close as price
| table _key, date, code, price, predict, expected_value
| outputlookup stock_predict append=true override_if_empty=true

์ด ๊ฒฐ๊ณผ๋ฅผ predict_stock์ด๋ผ๋Š” ์ œ๋ชฉ์˜ ๋ฆฌํฌํŠธ๋กœ ์ €์žฅ

 

 

 

 

 

๐Ÿณ predict_stock_with_ml ๐Ÿณ

      ML์„ ํ†ตํ•œ ์ฃผ์‹ ์˜ˆ์ธก(10์žฅ ์ฐธ์กฐ)

 

10์žฅ์— ์žˆ๋Š” ML์„ ์นดํ…Œ๊ณ ๋ฆฌ ์„ ์ • ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ๊ฐ’ ์˜ˆ์ธก ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

MLTK์˜ Experiment ํด๋ฆญ > Predict Numeric Fields ํด๋ฆญ > Create New Experiement

 

Experiment Title ์ž‘์„ฑ ํ›„ Create ํด๋ฆญ

 

index="kospi" code="068270.KS" earliest=0
| sort _time  
| `mylag(Close, 10)` 
| table _time, Close, lag_* 
| where isnotnull(lag_9)

search ์ฐฝ์— ์œ„์˜ ๊ฒ€์ƒ‰์–ด ์ž…๋ ฅ ํ›„ ๋‹๋ณด๊ธฐ ํด๋ฆญ

 

์œ„์™€ ๊ฐ™์ด ์„ค์ • ํ›„ Apply

 

์œ„์™€ ๊ฐ™์ด ์„ค์ • ํ›„ Fit Model ํด๋ฆญ > Save   &&   Show SPL

์œ„์— ์ƒ์„ฑ๋œ SEARCH COMMAND ๋ณต์‚ฌ ํ›„ stock ์•ฑ์˜ ๊ฒ€์ƒ‰ ์ฐฝ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ • ํ›„ ๊ฒ€์ƒ‰

| inputlookup my_stock 
| map search="
| search index="kospi" code="$code$.KS" earliest=0 
| sort _time 
| `mylag(Close, 10)` 
| table _time, Close, lag_* 
| where isnotnull(lag_9) 
| fit StandardScaler "lag_0" "lag_1" "lag_2" "lag_3" "lag_4" "lag_5" "lag_6" "lag_7" "lag_8" "lag_9" "Close" with_mean=true with_std=true into "model_stock_predict_SS_$code$" 
| fit RandomForestRegressor "SS_Close" from "SS_lag_0" "SS_lag_1" "SS_lag_2" "SS_lag_3" "SS_lag_4" "SS_lag_5" "SS_lag_6" "SS_lag_7" "SS_lag_8" "SS_lag_9" into "model_stock_predict_RF_$code$"

 

์ด ๋ถ€๋ถ„์„ SAVEDSEARCH๋กœ ์ €์žฅํ•œ๋‹ค.

 

์ดํ›„ ์„ค์ •์—์„œ ๊ฒ€์ƒ‰/๋ฆฌํฌํŠธ/์•Œ๋žŒ์— ๋“ค์–ด๊ฐ€์„œ ์ฟผ๋ฆฌ๋ฅผ ๋‹ค์Œ์ฒ˜๋Ÿผ ์ˆ˜์ •ํ•ด

ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ†ตํ•ด ๋ชจ๋ธ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ์ค€๋‹ค.

index="kospi" code="$code$.KS" earliest=0
| sort _time  
| `mylag(Close, 10)` 
| table _time, Close, lag_* 
| where isnotnull(lag_9)
 | fit StandardScaler "Close" "lag_0" "lag_1" "lag_2" "lag_3" "lag_4" "lag_5" "lag_6" "lag_7" "lag_8" "lag_9" with_mean=true with_std=true into "model_stock_predict_SS_$code$"
 | fit RandomForestRegressor "SS_Close" from "SS_lag_0" "SS_lag_1" "SS_lag_2" "SS_lag_3" "SS_lag_4" "SS_lag_5" "SS_lag_6" "SS_lag_7" "SS_lag_8" "SS_lag_9" into "model_stock_predict_RF_$code$"

์„ฑ๊ณต

 

| inputlookup my_stock 
| map search=" 
    | search index=kospi code=$code$.KS earliest=-20d
    | sort _time 
    | `mylag2(Close, 10, true)`
    | table _time, code, Date, Close, lag_*
    | eventstats latest(Date) as evaluate_date
    | where Date = evaluate_date
    | apply model_stock_predict_SS_$code$
    | apply model_stock_predict_RF_$code$
    | rename predicted(SS_Close) as predict
    | append [ | summary model_stock_predict_SS_$code$ | where fields = \"Close\"]
    | eventstats max(\"mean\") as ss_mean, max(var) as ss_var
    | eval predict = predict * sqrt(ss_var) + ss_mean
    | table Date, code, Close, predict"
| where isnotnull(Date)
| rex field=code \"^(?<code>\d+).KS\"
| rename Date as date, Close as close
| eval _key = date + "_" + code
| table _key, date, code, close, predict
| outputlookup stock_ml_predict append=true override_if_empty=true

์ด ๊ฒฐ๊ณผ๋ฅผ predict_stock_with_ml์ด๋ผ๋Š” ์ œ๋ชฉ์˜ ๋ฆฌํฌํŠธ๋กœ ์ €์žฅ

 

 

๐Ÿณ predict_stock_with_statics ๐Ÿณ

      ์‚ผ์ค‘์ฐฝ์„ ์ด์šฉํ•œ ์˜ˆ์ธก (9์žฅ ์ฐธ์กฐ)

| inputlookup my_stock  |map search="| search index=kospi code=$code$.KS earliest=-360d
    | sort _time
    | trendline ema130(Close) as ema130, ema5(Close) as ema5
    | table _time, Date, code, Close, ema130, ema5
    | join _time [ | search index=kospi code=$code$.KS earliest=-360d
          | sort _time
          | streamstats window=14 current=true max(High) as ndays_high, min(Low) as ndays_low
          | eval fast_k = (Close - ndays_low) / (ndays_high - ndays_low) * 100
          | streamstats window=3 avg(fast_k) as slow_d
          | table _time, fast_k, slow_d ]
          | where isnotnull(ema130)
| table _time, Date, code, Close ema130, ema5, slow_d
| streamstats window=2 list(ema130) as ema130_list, list(ema5) as ema5_list, list(slow_d) as slow_d_list
| eventstats latest(Date) as evaluate_date
| where Date = evaluate_date "
| eval ema130_pre = tonumber(mvindex(ema130_list, 0)), ema130_cur = tonumber(mvindex(ema130_list, 1))
| eval ema5_pre = tonumber(mvindex(ema5_list, 0)), ema5_cur = tonumber(mvindex(ema5_list, 1))
| eval slow_d_pre = tonumber(mvindex(slow_d_list, 0)), slow_d_cur = tonumber(mvindex(slow_d_list, 1))
| eval step1 = if(ema130_pre > ema130_cur, -1, 1) 
| eval step2_pre = if(slow_d_pre > slow_d_cur, -1, 1) 
| eval step3_pre = if(ema5_pre > ema5_cur, -1, 1)  
| eval step2 = case(step1 > 0 AND slow_d > 20, 1, step1 < 0 AND slow_d > 80, -1, 1=1, 0)
| eval step3 = case(step2_pre < 0 AND step3_pre > 0, 1,  step2_pre > 0 AND step3_pre < 0, -1, 1 = 1, 0)
| rex field=code "^(?<code>\d+).KS"  
| rename Date as date, Close as close
| eval _key = date + "_" + code
| table date, code, ,close,  step1, step2, step3, slow_d
| outputlookup stock_statics_predict append=true override_if_empty=true

์ด ๊ฒฐ๊ณผ๋ฅผ predict_stock_with_statics์ด๋ผ๋Š” ์ œ๋ชฉ์˜ ๋ฆฌํฌํŠธ๋กœ ์ €์žฅ

 

์™„์„ฑ๋œ ๋ฆฌํฌํŠธ๋“ค

์ด๋“ค์€ ๊ฐ๊ฐ ๋‹ค์Œ์ฒ˜๋Ÿผ ์Šค์ผ€์ฅด๋ง ํ•œ๋‹ค.

 

 

 

๐ŸŒณ STEP 3๐ŸŒณ ๋งค๋งค ์ „๋žต ์„ธ์šฐ๊ธฐ

 

๋งค๋งค ์ „๋žต์€ ๊ฒฐ๊ตญ์€ ์—ฌ๋Ÿฌ ๋ถ„์„์„ ํ†ตํ•ด์„œ

๋ช‡ ์ฃผ๋ฅผ ์–ผ๋งˆ์— ๊ตฌ๋งคํ•  ๊ฒƒ์ธ๊ฐ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฐœ์ธ๋งˆ๋‹ค ๋…ธํ•˜์šฐ๊ฐ€ ๊ฐ๊ฐ ๋‹ค๋ฅผ ๊ฒƒ์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ , ์‹œ๋ฎฌ๋ ˆ์ด์…˜์ด ์ง„ํ–‰๋˜๊ณ , ์ˆ˜์ต๋ฅ ์— ๋”ฐ๋ผ์„œ ๋งค๋งค์ „๋žต์„ ์ƒํ™ฉ์— ๋งž๊ฒŒ ๋ฐ”๊ฟ”์„œ ์ ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

 

| inputlookup stock_predict 
| eval _time = strptime(date, "%Y-%m-%d") 
| eventstats latest(date) as f_date 
| where date = f_date 
| rex field=code "^(?<code>\d+).KS" 
| eval p_score = case(expected_value >= 20 , 3, expected_value < 20 AND expected_value >= 10, 2, expected_value < 10 AND expected_value >= 1, 1, 
    expected_value <= -1 AND expected_value > -10, -1, expected_value <= -10 AND expected_value > 20, -2, expected_value <= -20 , -3, 1=1, 0) 
| table date, code, p_score 
| append 
    [| inputlookup stock_ml_predict 
    | eval _time = strptime(date, "%Y-%m-%d") 
    | eventstats latest(date) as f_date 
    | where date = f_date 
    | rex field=code "^(?<code>\d+).KS" 
    | eval expected_value = (predict - close) * 100 / close 
    | eval m_score = case(expected_value >= 10 , 2, expected_value < 10 AND expected_value >= 1, 1, 
        expected_value <= -1 AND expected_value > -10, -1, expected_value <= -10 , -2, 1=1, 0) 
    | table date, code, m_score, close, predict] 
| append 
    [| inputlookup stock_statics_predict 
    | eval _time = strptime(date, "%Y-%m-%d") 
    | eventstats latest(date) as f_date 
    | rex field=code "^(?<code>\d+).KS" 
    | eval s_score = case(step1 > 0 AND slow_d < 20, 5, step1 > 0 AND slow_d < 40, 4, step1 < 0 AND slow_d > 80, -5, step1 < 0 AND slow_d > 60, -4, 1= 1, 0) 
    | table date, code, s_score] 
| stats max(p_score) as p_score, max(m_score) as m_score, max(s_score) as s_score, max(close) as close, max(predict) as predict by date, code 
| eval score = p_score + m_score + s_score 
| append 
    [| inputlookup my_stock] 
| stats max(score) as score, max(share) as share, max(target) as target, max(close) as close, max(predict) as predict by code 
| append 
    [| inputlookup my_asset_history 
    | eval _time = strptime(date,"%Y-%m-%d %H:%M:%S") 
    | stats latest(balance) as balance ] 
| eval asset = close * share 
| eventstats max(balance) as balance, sum(asset) as total 
| eval my_total_asset = balance + total 
| eval rate = (asset / my_total_asset) * 100, share_rate = (asset / total) * 100 
| eval target_count = round(( round(my_total_asset * (target / 100)) - asset ) / close) 
| where isnotnull(code) 
| eval BUY = if(score > 0, target_count * (score /10), 0), SELL = if(score < 0, share * (abs(score)/10), 0) 
| eval BUY = if(BUY > 0, round(BUY), 0), SELL = if(SELL > 0, round(SELL), 0) 
| eval buy = BUY - SELL 
| lookup kospi_200 code OUTPUT name 
| eval predict = round(predict) 
| eval rate = round(rate, 2), share_rate = round(share_rate, 2) 
| eval _key = code 
| table _key, code, name, buy, predict
| outputlookup today_target

 

์ฝ”๋“œ๋ถ„์„

๋”๋ณด๊ธฐ

1๏ธโƒฃ ์šฐ์„  ์˜ˆ์ธก๋œ ๋‚ด์šฉ์„ ์ตœ์‹  ๋‚ ์งœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ key-value ์Šคํ† ์–ด์—์„œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋ชจ์•˜๋‹ค.

| inputlookup stock_predict 
| eval _time = strptime(date, "%Y-%m-%d") 
| eventstats latest(date) as f_date
| where date =  f_date 
...
| append [ | inputlookup stock_ml_predict  
    | eval _time = strptime(date, "%Y-%m-%d") 
    | eventstats latest(date) as f_date
    | where date =  f_date  
...]
| append [ | inputlookup stock_statics_predict 
    | eval _time = strptime(date, "%Y-%m-%d") 
    | eventstats latest(date) as f_date 
...]

 

2๏ธโƒฃ ๊ฐ ์˜ˆ์ธก๋ณ„๋กœ Max ์ ์ˆ˜๋กœ ๊ฐ€์ค‘์น˜๋ฅผ ๋‘์—ˆ๋‹ค.

       ์‚ผ์ค‘์ฐฝ ๋ฐฉ๋ฒ•์€ 5~4์ , ์‹œ๊ฐ„ ์˜ˆ์ธก์€ 3~1 ์ , ML์€ 2~1 ์  ์‚ฌ์ด๋กœ ์ ์ˆ˜๋ฅผ ๋งค๊ธฐ๊ณ ,
       + ์ ์ˆ˜์ด๋ฉด BUY, - ์ ์ˆ˜์ด๋ฉด SELL ์„ ํ•˜๋„๋ก ํ•œ๋‹ค.

      predict ์Šค์ฝ”์–ด ๊ฒฐ์ •์€
      5์ผ ํ›„ ์˜ˆ์ƒ๋˜๋Š” ๊ฐ€๊ฒฉ ๋ณ€๋™์ด 20% ์ด์ƒ์ด๋ฉด 3์ 

      10~20% ์ด๋ฉด 2์ 
      1~10% ์ด๋ฉด 1์ 

      ๊ทธ ์™ธ์—๋Š” 0์ ์ด๊ณ , ๋ฐ˜๋Œ€๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค.

..
| eval p_score = case(expected_value >= 20 , 3, expected_value < 20 AND expected_value >= 10, 2, expected_value < 10 AND expected_value >= 1, 1,  
                         expected_value <= -1 AND expected_value > -10, -1, expected_value <= -10 AND expected_value > 20, -2, expected_value <= -20 , -3, 1=1, 0)  
...
  • ์—ฌ๊ธฐ์„œ expected_value๊ฐ€ ๊ฐ€๊ฒฉ ๋ณ€๋™ ๊ฐ’์ด๋‹ค.

 

ML ์Šค์ฝ”์–ด ๋„ ๋น„์Šทํ•œ ํ˜•ํƒœ๋กœ ์ž…๋ ฅ๋œ๋‹ค.

...
    | eval m_score = case(expected_value >= 10 , 2, expected_value < 10 AND expected_value >= 1, 1,   
                         expected_value <= -1 AND expected_value > -10, -1, expected_value <= -10 , -2, 1=1, 0) 
...

 

์‚ผ์ค‘์ฐฝ ์Šค์ฝ”์–ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

...
 | eval s_score = case(step1 > 0 AND slow_d < 20, 5, step1 > 0 AND slow_d < 40, 4, step1 < 0 AND slow_d > 80, -5, step1 < 0 AND slow_d > 60, -4, 1= 1, 0) 
...

์—ฌ๋Ÿฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋‚˜์˜ค๋Š” ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ง€๊ณ  ์Šค์ฝ”์–ด๋ฅผ ์–ด๋–ป๊ฒŒ ์ฃผ๋Š”๊ฒŒ ๊ฐ€์žฅ ์ˆ˜์ต๋ฅ ์ด ์ข‹์€๊ฐ€์— ๋Œ€ํ•œ ML ๋˜๋Š” DL์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์‚ฌ์‹ค ๊ฐ€์žฅ ์ค‘์š”ํ•˜๊ณ  AI ํŠธ๋ ˆ์ด๋”ฉ์˜ ํ•ต์‹ฌ์ด ๋  ๊ฒƒ์ด๋‹ค. (์ด ๋ถ€๋ถ„์€ ์Šคํ”Œ๋ ํฌ scope์„ ๋„˜์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ...)

 

3๏ธโƒฃ ์ดํ›„ ๊ฐ ์Šค์ฝ”์–ด๋ฅผ ๋”ํ•ด์„œ ์ตœ์ข… ์˜ˆ์ธก ์Šค์ฝ”์–ด๋ฅผ ๋งŒ๋“ ๋‹ค.

...
| stats max(p_score) as p_score, max(m_score) as m_score, max(s_score) as s_score,   max(close) as close, max(predict) as predict by date, code
| eval score = p_score + m_score + s_score
...

 

4๏ธโƒฃ ํฌํŠธํด๋ฆฌ์˜ค ๊ตฌ์ถ• ๊ณ„ํš์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‚ด ์ž์‚ฐ์œผ๋กœ ๊ตฌ๋งคํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ ์ฃผ์‹์˜ ์ตœ๋Œ€ ์ฃผ์‹ ์ˆ˜๋ฅผ ๊ตฌํ•œ๋‹ค.

...
| append [ | inputlookup my_stock]
| stats  max(score) as score, max(share) as share, max(target) as target,  max(close) as close, max(predict) as predict   by code
| append [ | inputlookup my_asset_history 
    | eval _time = strptime(date,"%Y-%m-%d %H:%M:%S") 
    | stats latest(balance) as balance ]
| eval asset = close * share
| eventstats max(balance) as balance, sum(asset) as total
| eval rate = (asset / balance) * 100, share_rate = (asset / total) * 100
| eval target_count = round(balance * (target / 100) / close) - share
...

5๏ธโƒฃ ์Šค์ฝ”์–ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฃผ์‹์„ ์–ผ๋งˆ๋‚˜ ์‚ด์ง€/ํŒ”์ง€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค.

...
| eval BUY = if(score > 0, target_count * (score /10), 0), SELL = if(score < 0, share * (abs(score)/10), 0)
| eval BUY = if(BUY > 0, round(BUY), 0), SELL = if(SELL > 0, round(SELL), 0)
...

์ด ์ฟผ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ „๋žต์ด ๋งŒ๋“ค์–ด์ง„๋‹ค.

๋‹ค๋ฅธ๊ฑด ๋ชจ๋ฅด๊ฒ ๊ณ  Cellirion ํŒ”๋ผ๋Š” ๊ตฌ๋งŒ!ใ…‹ใ…‹ใ…‹

 

 

 

๐ŸŒณ STEP 4๐ŸŒณ ๋งค๋งค ์‹คํ–‰ํ•˜๊ธฐ

 

์ „๋žต์ด ๋งŒ๋“ค์–ด์กŒ์œผ๋ฉด ์ด์ œ ์‹ค์ œ ๋งค๋งค๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์‹œ๋ฎฌ๋ ˆ์ด์…˜์„ ๋งŒ๋“ ๋‹ค.

์‚ฌ์‹ค ๋ณต์žกํ•œ ์ฒด๊ฒฐ๊ณผ์ •๋„ ์—†๊ณ  ์ˆ˜์ˆ˜๋ฃŒ๋„ ์—†๋‹ค.

์–ด์งœํ”ผ ์‹ค์ œ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ์™ธ๋ถ€ ๋งค๋งค ์‹œ์Šคํ…œ๊ณผ ์—ฐ๊ฒฐํ•ด์•ผ ํ•˜๋Š”๋ฐ

์–ด๋””๊นŒ์ง€๋‚˜ ์ง€๊ธˆ ํฌ์ŠคํŒ…์€ ์Šคํ”Œ๋ ํฌ ํ•™์Šต์šฉ์ด๋‹ค.

 

๋กœ์ง์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์šฐ์„ ์€ ํ•œ๋ฒˆ ์ˆ˜ํ–‰ ๋  ๋•Œ ํ•˜๋‚˜์˜ ์ฃผ์‹๋งŒ ๊ฑฐ๋ž˜๋˜๊ฒŒ ํ•˜์˜€๋‹ค.

์•ž์—์„œ ์ €์žฅํ•œ "today_target" ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๋Š” ๊ฒƒ์œผ๋กœ ์‹œ์ž‘ํ•œ๋‹ค.

 

| inputlookup  today_target | where buy != 0 | head 1
| map search="| readstock code=$code$ 
    |  spath | eval buy = $buy$ , predict = $predict$ 
    | table code, price, time, buy, predict"
| rex field=time "^(?<online>\d{4}.\d{2}.\d{2}(\s?\d{2}?:\d{2})?)"
| eval online = if(len(time) > 10, 1, 0)
| eval B_DONE = if( buy > 0 AND online == 1, buy, 0) ,  S_DONE = if( buy < 0 AND online == 1, abs(buy), 0)
| eval outcome = price * B_DONE, income = price * S_DONE
| eval buy = buy - B_DONE + S_DONE
| append  [ | inputlookup my_asset_history | eval _time = strptime(date, "%Y-%m-%d %H:%M:%S") | stats latest(balance) as balance  ]
| eventstats max(balance) as balance 
| eval date=strftime(now(),"%Y-%m-%d %H:%M:%S") 
| eval balance =  balance - outcome + income, method = case (B_DONE != 0 , "BUY", S_DONE != 0 , "SELL", 1=1, ""), count = B_DONE - S_DONE, cost = income - outcome
| join code [ | inputlookup my_stock ]
| where online = 1
| eval share = share + B_DONE - S_DONE
| eval _key = code
| outputlookup today_target append=true override_if_empty=true
| outputlookup my_stock append=true override_if_empty=true 
| eval _key = strftime(_time, "%Y%m%d%H%M%S") + "_" + code
| outputlookup my_asset_history append=true

์ฝ”๋“œ๋ถ„์„

๋”๋ณด๊ธฐ

1๏ธโƒฃ ์šฐ์„  "map" ๊ตฌ๋ฌธ๊ณผ 2์žฅ์—์„œ ๋งŒ๋“  "readstock" ๋ช…๋ น์„ ์ด์šฉํ•ด ํ˜„์žฌ ์ฃผ์‹์„ ๊ฐ€์ ธ์˜จ๋‹ค.

    | map search="| readstock code=$code$ 
        | spath | eval buy = $buy$ , predict = $predict$ 
        | table code, price, time, buy, predict"

 

 

2๏ธโƒฃ 2์žฅ์— ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์•ฝ๊ฐ„ ์—…๋ฐ์ดํŠธ ํ•ด์„œ ํ˜„์žฌ ์‹œ๊ฐ„์„ ๊ฐ€์ ธ์˜จ๋‹ค.

...
| rex field=time "^(?<online>\d{4}.\d{2}.\d{2}(\s?\d{2}?:\d{2})?)"
| eval online = if(len(time) > 10, 1, 0)
...

์ด๋ฅผ ํ†ตํ•ด ์žฅ์ค‘์ธ์ง€, ์žฅ๋งˆ๊ฐ์ด ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

ํ˜„์žฌ ํ•œ๊ธ€์ด ํŒŒ์‹ฑ์ด ๋˜์ง€ ์•Š์•„์„œ(๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ…Œ์ŠคํŠธ ํ•ด๋ดค์ง€๋งŒ ์•„์ง ํ•ด๊ฒฐ์ด ์•ˆ๋œ๋‹ค. ใ… ใ… )

์žฅ ์ค‘์ผ ๋•Œ๋Š” ์‹œ๊ฐ„๊นŒ์ง€ ๋‚˜์˜ค๊ณ  ์žฅ๋งˆ๊ฐ์ด๋ฉด ๋‚ ์งœ๋งŒ ๋‚˜์˜ค๋Š” ํŠน์„ฑ์„ ์ด์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

3๏ธโƒฃ ๊ฑฐ๋ž˜ ๋‚ด์šฉ์„ KV_STORE์— ์ €์žฅํ•ด์ค€๋‹ค.

...
| outputlookup today_target append=true override_if_empty=true
| outputlookup my_stock append=true override_if_empty=true 
| eval _key = strftime(_time, "%Y%m%d%H%M%S") + "_" + code
| outputlookup my_asset_history append=true

์žฅ ์ค‘์ผ ๊ฒฝ์šฐ ์ „๋žต์— ๋‚˜์˜จ๋ฐ๋กœ ์ฃผ์‹์„ ๊ฑฐ๋ž˜ํ•˜๊ณ  ๊ฑฐ๋ž˜๋œ ๋‚ด์šฉ์„,

"my_stock", "today_target", "my_asset_history" ์— ๊ฐ๊ฐ ์—…๋ฐ์ดํŠธ ํ•ด ์ค€๋‹ค.

 

์•„์ง์€  buy๊ฐ€ 0์ด ์•„๋‹Œ ์ฃผ์‹์ด ๋‚˜์˜ค์ง€ ์•Š์•„์„œ ์ฃผ์‹์„ ๊ตฌ๋งคํ•  ์ˆ˜๋„ ํŒ” ์ˆ˜๋„ ์—†๋Š” ์ƒํ™ฉ์ด๋ผ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋Ÿผ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ ์„œ๋กœ ์ €์žฅํ•˜๊ณ  ์–ด์จŒ๋“  ์œ„ ์ฟผ๋ฆฌ๋Š” ์ €์žฅํ•˜๊ณ 

ํ•ด๋‹น ๋ถ€๋ถ„์„ alert ์œผ๋กœ ๋งŒ๋“ค๊ณ  ์Šค์ผ€์ฅด์„ ์‹คํ–‰ํ•œ๋‹ค.

๊ฑฐ๋ž˜๊ฐ€ 1๊ฑด์ด๋ผ๋„ ๋ฐœ์ƒํ•˜๋ฉด ์นดํ†ก์œผ๋กœ ์•Œ๋žŒ์„ ๋ณด๋‚ธ๋‹ค.

 

 

๐Ÿšซ ์ฃผ์˜ ๐Ÿšซ 

ํ…Œ์ŠคํŠธ์šฉ์œผ๋กœ key-value ์Šคํ† ์–ด๋ฅผ ์ด์šฉํ•ด ๊ฐ์ข… ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ณ  ์žˆ์œผ๋‚˜,
์ด ๊ณณ์— ์ค‘์š”ํ•œ ๋‚ด์šฉ์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ ๋ฐ”๋žŒ์งํ•ด ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค.

์‹ค์ˆ˜๋กœ "| outpulookup kv-store-name" ์„ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด ์—ฌ๊ธฐ ๊ธฐ๋ก๋œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚ ์•„ ๊ฐ„๋‹ค.

๋ณต๊ตฌํ•  ๋ฐฉ๋ฒ•๋„ ์—†๋‹ค.

 

 

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐฑ์—…์œผ๋กœ ์ €์žฅ๋œ ๋‚ด์šฉ๋“ค, ๋‹ค์‹œ ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ๋งŒ ๊ธฐ๋กํ•˜๋Š”๊ฒŒ ์ข‹์•„๋ณด์ธ๋‹ค. ์•„๋‹ˆ๋ฉด ์ฃผ๊ธฐ์ ์œผ๋กœ ํŒŒ์ผ๋กœ ๋ฐฑ์—…์„ ํ•˜๋˜์ง€....

key-value ์Šคํ† ์–ด์— ๋Œ€ํ•ด์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ append=true ์˜ต์…˜์ด ์ ์šฉ๋˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๊ธด ํ•œ๋ฐ...

๋งŒ์•ฝ key-value ์Šคํ† ์–ด๋ฅผ ์ด์šฉ์ค‘์ด๊ณ  ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ผญ ์ € ์˜ต์…˜์„ ๊นŒ๋จน์ง€ ๋ง์ž........

 

 

 

โ€‹

728x90
๋ฐ˜์‘ํ˜•