애들센스


처음으로 써보는 crontab 파이썬/쟁고

최근에 텔레그램봇을 만들면서 든 생각중 하나는 공부를 제대로 안하고 대충 했구나 하는 생각이다. 그냥 무심하게 개발관련 글들을 보았는데, 봇이 개인을 상대로 메시지를 보내는 경우도 있고, 채널에 메시지를 보내는 것이 있는 데, 미처 그런 생각을 하지 못하고 넘겨왔다. 또 많은 블로그나 정보에서 보여주는 내용이 봇의 구현인데, 속 시원한 답을 얻지 못하는 것은...

봇이 상시적으로 서비스를 하려면 웹서버같은 물건이 필요한 거 아닌가? 이런 서비스를 하려면 무엇을 해야 하는 지 알려주는 내용이 없을 까?

아무튼 간신히 시험삼아 시간을 뿌려주는 봇과 이를 받아주는 채널을 만들었다. 봇을 원하는 대로 만들기에 앞서 전체적인 프로세스를 체크하기 위한 목적이다.

이제 봇을 일정시간마다 뿌려주려면 crontab을 이용해야 한다. 서버가 필요한 건 아니고, 그냥 백그라운드로 스크립트를 실행하면 되는 것이다. 사실 리눅스에서 스케줄링을 하는 도구로 cron이라는 서비스(데몬)가 해주는 걸 알고는 있었다. 그러나 실제 그걸 사용할 일이 나에게는 없었다. 이번에 알게 된 것은 스케줄에 걸어둔 프로세스에 에러가 있으면, 얘가 아무 것도 안한다는 점이다. 파이썬 스크립트에 에러가 있어도 안되고, >>를 사용하여 로그를 만드는 부분의 에러가 있어도 안된다는 점이다.
[참고자료][CentOS] Linux 반복 예약작업(스케줄러) - Crontab

그리고

python my_script.py

형식으로 하면 정상동작하는 넘이 쉘스크립트로 작성해서 실행하면 "ImportError No named module~" 에러를 낸다. 여러 가지 구글검색을 통해 결국 성공한 방법은 경로를 꼼꼼히 적어두는 것이다.
다음은 crontab의 내용과 쉘스크립트의 내용이다.
[root@localhost tbot]# crontab -l
5 23 * * * /usr/bin/python3.6 /opt/tbot/teli.py >> /opt/tbot/finews.log
[root@localhost tbot]# ./start_bot.sh
[root@localhost tbot]# ll
total 12
-rw-r--r-- 1 root root 28 Nov 21 23:24 finews_11212324.log
-rwxrwxrwx 1 root root 84 Nov 21 23:24 start_bot.sh
-rwxr-xr-x 1 root root 337 Nov 21 11:24 teli.py
[root@localhost tbot]# cat start_bot.sh
/usr/bin/python3.6 /opt/tbot/teli.py >> /opt/tbot/finews_$(date +\%m\%d\%H\%M).log


야 이넘아! 고만 보내라~나 시계 있다

Beta Is Dead; Rock Is Dead 증권



투자자는 위험을 기피하는 속성이 있다. 그러나 더 많은 보상이 있다면 더 큰 위험을 수용할 수 있다. 위험이 작으면 작은 보상에도 만족한다. 그러면 위험을 어떻게 측정하나? 마코위츠와 샤프가 내린 정의는 변동성이다. 주식이나 포트폴리오의 가치가 오르락 내리락 하는 정도가 변동성이고 , 변동성이 크면 위험이 큰 것이다. 구체적으로 변동성은 표준편차로 측정하거나 베타로 측정한다.

흔히 위험과 수익률의 관계를 그래프로 그리면 우상향할 것으로 생각한다. 왜냐하면 우리의 머리속엔 ‘High Risk, High Return’이라는 명제가 박혀 있기 때문이다. 그러나 실제 아무런 상관관계를 보이질 않는다. 변동성이 크다고 해서 수익률이 좋은 것은 아니다. 반대의 경우도 마찬가지이다.

변동성의 측정, 즉 척도도 여러 논란이 있다. 가령 공매도를 한 투자자를 제외한 투자자들은 하락장의 변동성을 좋아하진 않는다. 오히려 상승장의 변동성은 반가워 한다. 상승장의 변동성이 클 수록 좋아한다. 변동성으로 대변되는 위험을 기피하는 속성과는 맞지 않는다. 변동성의 척도 가운데 하나인 베타는 많은 연구 결과 베타는 미래의 변동성을 예측할 수 없다는 결론을 얻었지만 지금도 많이 쓰인다.

1992년 유진 파마는 같은 시카고대학 교수인 케네스 프렌치와 함께 위험과 수익을 주제로 논문을 발표한다. 이 논문은 1963년부터 1990년까지 9,500개의 주식을 대상으로 주가순자산비율, 주가수익비율, 시가총액이 가장 낮은 주식들의 수익률이 장기적으로 가장 높았으며, 베타가 높은 주식과 낮은 주식을 비교해보면 수익률이 거의 비슷하다는 결론을 얻는다. 그들의 결론은 베타로 측정한 주식의 위험은 수익률을 예측할만한 지표가 아니라는 것이다.

파마와 프렌치의 연구결과 주가순자산비율과 주가수익비율이 가장 낮은 주식의 수익률이 가장 높고, 대형주보다 소형주 비율이 높다. 주가의 수익률과 높은 상관관계를 보이는 것은 베타를 비롯한 위험지표가 아니다.

"Beta as the sole variable in explaining returns on stocks is dead."


‘하나의 위험지표로 수익률을 예측할 수 없다’는 논문 이후 1년이 지나 파마는 위험을 계산할 때 베타외에 가치척도(high book to market)와 다른 기준(market capitalization, smaller caps are riskier) 을 고려해야 한다는 새 위험이론을 발표했다

VBA 아니고 엑셀에서 람다함수 만들기 오피스/VBA/Office.JS

파이썬 람다함수는 익명함수로서  변수에 저장할 수 있다. 아래의 예는 람다함수인데, 만들어진 함수는 변수 yAxb에 저장한다. 이 함수는 값을 x에 받아 2를 곱하고 다시 1을 더하여 돌려준다.

>>> yAxb = lambda x : 2*x + 1
>>> yAxb(4)
9

자바스크립트(ES6)에서는 일명 화살표함수라는 것이 있다. 파이썬의 람다함수처럼 이 역시 함수, 변수 yAxb에 저장한다.

// ES6
const yAxb = x => 2 * x + 1;
console.log(yAxb(4)); // 9

그런데, VBA도 할 수 없는 것을 엑셀이 비슷한 것을 만들 수 있다. 엑셀의 '이름'기능을 이용하는 것이다. 엑셀의 이름기능은 A1, B2, C4:E7 과 같은 의미없는 셀 주소 대신 의미있고 기억하기 좋은 이름을 부여주는 것이다.

워크시트의 각 셀주소는 일종의 메모리 영역이다. 프로그래밍에서 변수를 선언하면 자동으로 메모리에 변수를 붙여 주는 것인데, 셀주소가 메모리 주소이고, '이름'은 변수를 지정한 것으로 비유할 수 있다.

파이썬과 자바스크립트(ES6)에서 변수에 함수를 저장한 것 처럼 엑셀은 '이름'에 수식(함수포함)을 지정할 수 있다. 다음 그림을 보면

'yAxb'라는 이름을 주고 '=Sheet1!$B2*2+1'라는 수식을 정의하고 있다. B2라는 셀이 위의 파이썬, 자바스크립트 코드의 변수 x에 해당한다. 그래서 셀안에 '=yAxb'를 입력하면 B열의 각 행 값을 읽어와서 계산을 하게 된다.


ImportError = CentOS7+Django2.2+Python3.6 파이썬/쟁고

PC에서만 돌려보던 쟁고프로젝트를 외부서버에 올리려고 하다보니, 프로그래밍이 아닌 쟁고 실행환경을 꾸리는 게 더 힘들다. /etc/httpd/conf/httpd.conf도 봐야하고, /etc/httpd/conf.d/vhost.conf 도 만들어야 하고, wsgi.py를 수정해야 한다. 시스템에 기본적으로 설치된 파이썬이 2 버전이고, 이에 맞춰 쟁고도 1.7.3(파이썬 2.7버전에게 가장 최선인 쟁고버전) 설치하였다. 그러나 아무래도 3 버전이 필요해 설치했고 쟁고도 2.2버전을 설치했다.

우선 python manage.py runserver를 실행하면, 아래와 같은 에러메시지가 나온다.
django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17)

SQLite를 업그레이드 해야 하나 싶어 시도했지만, 결과는 삽질+삽질=실패
문제는 쟁고2.2.가 SQLite 와 문제가 있다고 한다. 그래서 지우고 2.1로 다운그레이드하니, 개발서버실행은 잘된다.

그리고 systemctl restart httpd.server를 하였다. 짜잔~ 서버 IP 입력해보니(도메인 따윈 필요없다. 남자라면 IP Address 정도는 외우..) 대충 다음과 같은 에러가 나온다.
ImportError at /
cannot import ...
Request Method: GET
Request URL:
Django Version: 1.7.3
Exception Type: ImportError
...
Python Version: 2.7.6
...

그러나 위의 에러 메시지를 보니 이 넘의 아파치가 뭔 넘의 의리가 넘치는 지 자꾸 2버전을 호출하는 것 같다. 그런데, 문제해결은 파이썬 2, 쟁고 1.7.3.을 지우는 게 아니었다(특히 파이썬2는 시스템에서 완장을 차고 뭔가 역할을 하고 있어, 지우면 안된다)
이런 문제를 찾아보니 다음과 같은 답변이 있다.
I believe that mod_wsgi is compiled against a specific version of python, so you need a py3.4 version of mod_wsgi.

즉 버전에 맞는 mod_wsgi를 설치해야 한다는 것이다. 그러면 설치해야 하는 데, 설치할 mod_wsgi의 정확한 이름을 알아야 한다.
다음은 yum search mod_wsgi 명령으로 검색한 결과이다.
$ yum search mod_wsgi
[...]
koschei-frontend.noarch : Web frontend for koschei using mod_wsgi
mod_wsgi.x86_64 : A WSGI interface for Python web applications in Apache
python27-mod_wsgi.x86_64 : A WSGI interface for Python web applications in Apache
python36-mod_wsgi.x86_64 : A WSGI interface for Python web applications in Apache

그래~ python36-mod_wsgi 넘을 설치해야 하는 구나. 그래서 다음과 같이 설치하니
yum install -q -y python36-mod_wsgi

평범한 깡통 쟁고 프로젝트가 뜬다. 감격을 해야 하나 싶다.

사람의 마음이 간사하다. 쟁고가 안풀리니까, 내심 '아파치 정지하고, 노드로 해봐야 하나...' 를 궁리하기도 하였다. 다음은 이런 저런 자료를 찾다가 본 자료인데,
[자바스크립트와 파이썬의 대리인인 노드와 쟁고, 웹개발에 어느 게 나을 까?] 엄마가 좋아, 아빠가 좋아 급의 질문인듯하다.

(스핀오프)날짜+시간에서 시간만 빼오기 오피스/VBA/Office.JS

지난 번 MOD()함수 포스팅에서 아래와 같이 날짜+시간에서 시간만 빼오는 방법을 보여주었다.
사실 엑셀은 날짜와 시간을 특별한 데이터 형식이 아닌 실수값으로 저장하고 있다. 정수부분은 1900년 1월 1일(기억이 정확하지 않는다)부터 세어온 일수이다. 그리고 소수점이하 숫자인 0.8989982639 는 오후 9시 34분을 가리키며, 이는 자정에서 시작하여 오후 9시 34분은 0.8989982639 , 약 89.89% 지난 것이다. 그래서 날짜와 시간이 같이 있는 데이터가 있다면 , MOD함수를 사용하여 시간부분을 뜯어낼 수 있다.

그런데 방법은 이것만 있는 것은 아니다. 엑셀의 함수중 NOW()함수는 현재날짜와 시간을 돌려주는 함수이다. TODAY()는 현재 날짜만 돌려주는 함수이다. 두 함수의 뺄셈(=NOW()-TODAY())은 시간을 돌려준다. 위에서 설명한 바와 같이 엑셀은 날짜를 실수값으로 처리한다. 정수부분은 날짜, 소수점이하는 시간을 가리킨다. 따라서 뺄셈연산의 결과 소수점만 남긴다. 즉 시간만 남는 것이다.

두 번째 운수좋은 날 - HP 10.1-inch Pavilion 10 Touchsmart Notebook PC 삽질의 추억

지난 번 첫 운수 좋은 날에 이은 두 번째 운수좋은 날 시리즈이다.
HP 10.1-inch Pavilion 10 Touchsmart Notebook PC (Sparking Black)
- (AMD 1GHz, 2GB RAM, 500GB HDD, AMD A4-1200, Windows 8.1)

동생이 사용하던 노트북이 있었는데, 앙증맞은 크기에 터치스크린을 가진 넘이었다. 그런데 이 넘은 애물단지였다. 메모리, CPU, 스토리지 등 맘에 두는 스펙은 아니었다. 게다가 터치스크린은 종종 오류를 일으켜서 귀신터치(건들지도 않았는데, 뒷목잡고 쓰러지는 자해공갈단, 양🐏아치 같은 터치)로 인해 화면을 계속 터치한 증상을 보인다.

뭐 이거야 장치관리자에서 꺼버리면 되는 거니까 넘어가고... 암튼 동생의 노트북을 묻고 더블로 가서 어디서 구한 중고노트북(삼성 뭐 거시기인데, 10년전 모델이라 최대설치가능메모리 8기가인...)을 주었다.

나는 동생의 노트북을 함 사용해볼까 싶어, 8기가 메모리를 추가하였다. 그래도 A4 CPU(CPU를 A4 재생용지로 만들었냐? 성능이 이따위냐?)와 HDD의 환장할만한 콜라보 덕에 성능은 그저 그렇다. 흠~ OS 설치는 귀찮지만 HDD버리고 SSD로 가자~ 문제는 OS 재설치이다. 윈도10이 최신이지만 이넘에겐 윈도8.1이 최상일 것 같았다. 사실 저 사양에서 8.1이 10보다 나을 것이다. 그래서 HP에 문의를 해보았다(윈도 8.1은 소매판매도 하지 않는 넘이다)

(나) : '거~ 새 SSD에 윈도8.1 재설치하고 싶은 데, 어떻게 하나요?'

그러나 어눌한 말투(고객센터가 중궈에 있는 듯)의 HP상담원 한 마디에 귀를 의심했다.

(상담원): '그넘은 SSD 설치해봐야 소용없어. SSD 따위는 쌩깔거야!! 그러니 생긴대로 살어~'
(나): '누나! 그거 사실이야? 인터페이스는 SATA인데...누나가 여기 온지 얼마 안되어서 이 바닥을 잘 모르는 것 같은데 말이야..'

헐~ 이 누나 ~ 교육을 제대로 못받았네. 세상에 그런 하드웨어가 어딨어...
HP가 SONY냐? 그런 이상한 짓을 하겠어(SONY 미안). 누나의 말을 개 무시하고 개복수술을 했다.
드뎌 부팅~ 근데 이넘이

(머신): '저장장치 없다 주인넘아~ 하드는 무너졌나? 쉐캬'

(나):
'왜 SSD를 사왔는데 먹지를 못하냐'

하아~ 그 누나 말이 진짜구나. 누나 잘못했어~ 나의 오만을 용서해줘~ 내가 건방졌어



생애 처음으로 본 VBA 버그 오피스/VBA/Office.JS

시작은 어떤 분이 외부 엑셀파일을 불러와서 데이터를 복사하는 문제를 해결해주려는 오지랍 덕분이었다. 거의 코드를 만들고 테스트를 하는 데, 대화상자에서 선택한 파일명을 기록하였다. 그리고 다시 이 파일을 열려고 하니 파일이 없다는 식의 시비를 건다. 수 차례의 삽질 끝에 알아 낸 원인은 파일명에는 "[" 와 "]" 때문이다.
  1. Application.GetOpenFilename()함수는 "[" 와 "]"가 있는 파일명을 돌려준다.
  2. 그리고 Workbooks.Open() 역시 "[" 와 "]"가 있는 파일을 열어준다.
  3. 그러나 열어 둔 워크북 개체의 이름을 조회하니 "[" 와 "]"를 "(" 와 ")" 로 바꿔 버리는 것이다.
  4. 실제 엑셀에서 다른 이름으로 저장시 "[" 와 "]"는 이름으로 허용되지 않는다.
  5. 그러나 탐색기에서는 이름 변경시 "[" 와 "]"가 허용된다.
말로 하니 복잡하니 아래의 코드를 실행하면, 열려는 파일명에는 "[" 와 "]"가 있고 잘 열린다. 그러나 wbk.Name은 "[" 와 "]"를 "(" 와 ")" 로 바꿔 보여준다.
Sub demoBug()
Dim strFileToOpen As String
Dim wbk As Workbook

strFileToOpen = "[BlackRock]_iShares_Global Product List June 30, 2015.xlsx"
Set wbk = Workbooks.Open("C:\Kings\" & strFileToOpen)

' [BlackRock]_iShares_Global Product List June 30, 2015.xlsx 출력
Debug.Print strFileToOpen

'(BlackRock)_iShares_Global Product List June 30, 2015.xlsx 출력
Debug.Print wbk.Name
End Sub
포스팅 분류를 '삽질의 추억'으로 분류해야 하나...그런데 다시 생각해보면 이건 버그는 아닌 듯, 엑셀개발팀과 윈도개발팀간에 손발이 안맞는 건가?

리액트가 문제가 아니라 손가락이 문제야~ 자바스크립트

실시간으로 시간을 출력하는 react-live-clock를 사용해보는 데, 간단한 코드 하나 해보는 데, 3~4번의 에러가 생긴다. 그중 하나 빼고 나머지는 ClockClcok 등으로 오타는 내는 데, 중복되는 알파벳을 하나 건너 반복하려는 무의식땜에 자주 이런다.
import React,{Component} from 'react';
import Clock from 'react-live-clock';

class LiveClockTest extends Component{
render(){
return(
<div>
<Clock format={'YYYY-MM-DD HH:mm:ss'} ticking={true} timezone={'US/Pacific'}/>
</div>
)
}
}
export default LiveClockTest;

아싸 함수, MOD의 활용 오피스/VBA/Office.JS

MOD함수는 나눗셈의 나머지를 돌려준다. 인싸인 VLOOKUP과 달리 사람들이 기억해주지 않는 아싸함수이다. 얘를 첨 보았을 때, 이해가 가지 않았다. 뭐 이런 함수를 뭐하러 만들었지...별 쓸데없어 보이는데.. 기껏 사용하는 것이 짝수행이나 홀수행마다 색칠을 하거나 합계를 구하는 수식에서 사용되는 정도.

다음은 MOD함수의 기본적인 사용법이다. 8을 2로 나누면 나머지는 0이고 이 값을 돌려주는 것이 MOD함수이다. MOD함수에겐 '몫' 따위는 1조차 관심없다.

MOD함수를 이용하면 소수점을 가진 실수에서 소수점 이하의 값을 구할 수 있다. 가령 43773.8989982639에서 소수점이하를 얻으려면 어떻게 할 까? 눈으로 보면 쉬운 건데, 막상 방법은... 간단하다. 이 숫자를 1로 나누는 것이다. 1로 나누면 소수점 앞의 값이 몫이고 그 이하는 나머지이다.
= MOD(43773.8989982639, 1) = 0.8989982639

그런데 위의 예에서 사용한 숫자 43773.8989982639 는 그냥 나온 것은 아니다. 이 숫자를 입력하고 셀 서식을 날짜로 바꾸면 '2019년 11월 04일 오후 9:34'이다. 사실 엑셀은 날짜와 시간을 특별한 데이터 형식이 아닌 실수값으로 저장하고 있다. 정수부분은 1900년 1월 1일(기억이 정확하지 않는다)부터 세어온 일수이다. 그리고 소수점이하 숫자인 0.8989982639 는 오후 9시 34분을 가리키며, 이는 자정에서 시작하여 오후 9시 34분은 0.8989982639 , 약 89.89% 지난 것이다. 그래서 날짜와 시간이 같이 있는 데이터가 있다면 , MOD함수를 사용하여 시간부분을 뜯어낼 수 있다.


(엑셀도감) 컬럼 숨기기 단축 키 오피스/VBA/Office.JS

[CTRL+0] 키는 현재 컬럼을 숨기기도 하지만 , 미리 여러 개의 컬럼을 선택(연속 또는 띄엄띄엄 선택)하고 사용해도 컬럼을 숨긴다.

어느 운수 좋은 날 삽질의 추억

어느 날 데스크탑(삼성 DM-C410)이 들어왔는 데, 십여년 전 많이 보던 디자인이다. 부팅해보니 당연히 HDD이다. OS는 윈도우7(32비트) 그리고 램(RAM)은 충격적인 2GB! 나의 구린 스마트폰도 4GB인데, 이게 현실인가?

그래도 업그레이드를 하면 미운 오리새끼가 백조로 거듭나지 않을 까 싶어, 과감하게 8GB 메모리를 2개=16GB, 하드디스크도 삼성EVO250G SSD를 바꾸고 윈도10으로 업그레이드를 시도하였다. 도합 비용이 15만원 들었는데, 이럴 바엔 중고컴을 하나 사는 게 낫겠다는 현타가 온다. 그나저나 상콤한 윈도 10 설치후 시스템 정보를 보니 메모리가 8GB로 표시된다.

헐~ 머리속을 확 지나가는 짐작은 '아하 이 넘의 스펙이 8GB이구나~'였다. 예전 같으면 삼성전자 홈페이지 가서 모델명 검색해가면 스펙을 확인했지만, 그냥 편하게 삼성전자 서비스로 문의를 해보았다. 엔지니어도 2011년이라니까 그 당시에 최고 한도가 8GB일 거란다. 그래도 확인해보라고 했더니 역시 8GB가 한계였다.

그러면 뱅크를 모두 채울 필요는 없으니 하나는 빼두자. 그래서 다시 뱅크에서 메모리 하나 빼고 부팅. 그러고 다시 확인해보니 4GB로 표시된다. '아하~ 뱅크별 메모리 한계가 4GB 이구나' 결국 4GB씩 도합 8GB를 인질로 잡혀있는 셈이다. 16GB를 사두고 8GB만 사용하자니 현진건 단편 '운수 좋은 날'이 떠오른다.
배경은 1920년대의 서울이다. 어느 비오는 날, 인력거꾼 김첨지는 그날따라 유독 가지 말라고 말리는 병든 아내를 두고 돈을 벌러 나온다. 그런데 그날따라 유독 손님이 많아서 김첨지는 많은 돈을 벌었다. 하지만 집에 가까이 갈수록 어떤 알 수 없는 불안감이 느껴져 불길해 하던 중, 마침 친한 친구 치삼이를 만나 그와 술을 마시며 시간을 보낸다. 술에 취한 상태에서도 아내가 그리도 먹고 싶다던 설렁탕을 사서 집에 돌아갔는데....설마설마하던 불안감을 계속해서 느끼던 김첨지는 결국 아내가 죽은 것을 확인하고는 그 시신을 붙들고 절규하며 "왜 설렁탕을 사왔는데 먹지를 못하냐"고 울부짖으며 절망하는 것으로 끝이 난다.(출처: 운수 좋은 날)


'왜 16GB를 사왔는데 먹지를 못하냐' 나의 운수 좋은 날은 이렇게 끝난다.


똥휴지로 설명하는 프로그래밍 파이썬/쟁고


오묘한 리액트와 구닥다리 프로그래머 자바스크립트

학생시절 공부하던 여러가지 파생상품 프라이싱 모델을 자바스크립트로 만들어 홈페이지를 꾸며 본 적이 있는 데(라떼는 말이야~), 제이쿼리, 노드 등 같은 자바스크립트 언어의 혁신이 있기 전 일이다. 그래서 자바스크립트는 그저 웹브라우저가 읽어 DOM에 접근하는 정도의 시시한 언어로 생각했다. 당연히 관심 뚝.

그런데 요즘은 "프로그래밍===웹프로그래밍"인데, 온통 자바스크립트의 세상이다. 리액트, 앵귤러, 뷰, 미티어 등등 뭔지는 몰라도 들어 본 것 만해도 여러 가지이다. 어쩌면 혼동스러운 프로그래밍의 세계이고 어찌보면 다양성이 풍부해진 세상이다.

리액트 책을 처음으로 보면서 신기한 것은 이게 내가 아는 자바스크립트 문법이 아니다. HTML/CSS도 텍스트에디터로 태그를 날코딩하였는 데, 그런 노가다도 줄었다. 다음은 책에 나온 예제인데, 버튼을 누르면 출력한 인사말을 버튼에 적힌 색상대로 바뀌는 것이다.

이런 코드 <h1 style={{color}}>{message}</h1> 에서 style은 <h1 style="color: blue;">안녕하세여</h1> 처럼 지정하는 데, 리액트는 1) 따옴표도 없고 2) 딕셔너리 형식의 css스타일값 지정도 없이 {{color}} 스테이트값만 넘겨주면 된다. 만들어진 페이지의 소스를 보면 버튼이나 H1태그 같은 것도 보이질 않는다.
import React,{useState} from 'react';

const Say=()=>{
  const [message, setMessage]=useState('');
  const onClickEnter=
    ()=>setMessage('안녕하세여');
  const onClickLeave=
    ()=>setMessage('안녕가세여');

  const [color, setColor]=useState('black');

  return (
    <div>
      <button
        onClick={onClickEnter}>입장
        </button>
      <button
        onClick={onClickLeave}>퇴장
        </button>
      <h1 style={{color}}>{message}</h1>
      <button style={{color:'red'}}
        onClick={()=>setColor('red')}>빨간색
        </button>
      <button style={{color:'green'}}
        onClick={()=>setColor('green')}>초록색
        </button>
      <button style={{color:'blue'}}
        onClick={()=>setColor('blue')}>파란색
        </button>
    </div>        
  );
};
export default Say;
리액트는 프런트엔드(front-end) 웹 프로그래밍인데, yarn start를 하면 간이 웹서버가 실행되고 웹페이지를 렌더링한다. '으응? 프런트엔드인데, 웹서버가 왜 필요한 거임?' 그동안 프런트엔드를 잘못 알았나 보다. 프런트엔드를 웹서버와 상관없이 독립적으로 클라이언트인 웹브라우저에서 실행되는 클라이언트 사이드 스크립팅인줄 알았다.

추가로 setMessage()와 같은 콜백함수를 정의도 하지 않았는데(리액트가 제공하는 함수도 아닌데...) 이걸로 '안녕하세여'나 '안녕가세여'와 같은 메시지를 어떻게 전달하는 지 모를 일이다. 이럴 때 당장 이해 안가도 영원한 치트키, '그럴려니...' 하고 넘어가는 지혜를...

자주 오는 단골손님 알아보기 오피스/VBA/Office.JS

MATCH(찾는 값, 배열, 옵션)함수는 주어진 배열에서 찾는 값이 몇 번째에 있냐? 가령 MATCH(B, ABCD, 0)이라고 하면 B는 ABCD중 2번째 있으므로 2를 돌려줄 것이다. 그런데 A,B,C,D 각각 하나 하나 네 번 찾는 대신 A,B,C,D를 통째로 찾으면 편하지 않을 까? 배열수식은 이런 경우에 사용한다.

MATCH(ABCD, ABCD, 0)

그래서 실제 결과가 어떤 지 알고 싶어 엑셀로 해보았다. 다만 그대로 하지 않고 C와 D를 2번 반복하도록 해보았다. 즉

MATCH(ABCDCD, ABCDCD, 0)

같은 식이다.

C는 목록에서 세 번째 위치하는 데, 두 번 나오기 때문에 '3'이라는 결과가 두 번 나온다. D도 마찬가지로 네 번째 위치하고 역시 두번 나오므로 '4'라는 숫자가 두 번 나온다.

그리고 MODE()함수는 가장 자주 나오는 빈도값를 알려주는 최빈값(가난한 값?)을 알려준다. 그래서 MODE()를 같이 사용하면 최빈도를 가진 값을 돌려준다. 그리고 INDEX()함수를 사용하여 빈도가 높은 목록값을 찾아둔다.

=INDEX(ABCDCDC, MODE( MATCH( ABCDCDC, ABCDCDC, 0 ) ) )

위의 예에선 C가 세 번 나오는 데, 수식의 결과는 C에 해당하는 항목을 돌려준다.


그러나 이 방법에는 단점이 하나 있다. 최빈 값을 가진 항목이 두개 이상이라면 먼저 나온 항목만 보여준다는 점이다.

도움이 안되긴 너도 마찬가지야~ YARN 삽질의 추억

김민준 개발자의 "리액트를 다루는 기술(길벗) 개정판"을 받은 지 어느 새 한 달이상 되어 가는 마당에 독서의 계절을 맞아(가을이 맛이 가는 시점에 그걸?) 각 잡고 책을 보는 중이다. (a.읽어보고 b.정리하고 c.진짜 돌아가냐 싶어 돌려보고)를 LOOPING하는 중이다.
for each 챕터 in 리액트를 다루는 기술.챕터쓰

if 두뇌.read(챕터):
두뇌.summary(챕터, where:=구글독스)
고물컴.run(코드)

next
그런데 yarn 설치부터 덜커덩거리더니

(brew install yarn --without-node명령에서 --without-node가 뭐잉? 하더라, 저자 양반 이거 어찌 된거요? (유튜브채널, <velopert/> 구독/알람하고 있어요 ㅎㅎ) brew install yarn --ignore-dependencies로 해결. 참고:`brew install yarn --without-node` no longer possible) ,

프로젝트를 실행하는 "yarn start"를 했더니, '내가 제공해주는 웹팩을 써야함. 야메로 맘대로 설치하지 말고 형 믿고 1번부터 7번까지 따라해봐...' 따위의 메시지를 보낸다.

그대로 따라하는 데, 있다는 파일은 없어 넘어가고 다음 단계, 지우라는 거 지우고,...야~ 안되잖아.
역시 전문개발자 뿐만 아니라 나와 같은 야메개발자도 스택오버플로가 최고. 유저폴더의 node_modules지우니까 안정을 되찾음.
중화인민공화국이나 조선인민민주주의 공화국이 이름과 달리 민주국가가 아닌 것처럼, 윈도우 및 오피스, MS사이트의 도움말이 도움이 안되는 것처럼, 얘(yarn)도 마찬가지이다. 근데 스택오버플로가 누구꺼더라?

(수학)부피와 표면적 삽질의 추억

3.5 Rational Functions and Equations
9. The volume of a rectangular prism with a square base is fixed at 500 cm3.
a) Determine the surface area of the prism as a function of the length of the side of the square base.
b) Graph using technology and use the graph to determine what values of the side length would give a surface area of less than 1000 cm2.
밑면이 정사각형인 막대모양의 프리즘의 부피는 500 cm3이다.
a) 정사각형인 밑면의 길이가 주어질 때 프리즘의 표면적을 구하는 함수를 만들어라
막대의 표면적(S)은 밑면 2개, 측면 4개의 넓이의 합이다. 밑면의 길이를 L이라고 하고 프리즘의 가장 긴 옆면의 길이를 H라고 하면,
S=2*L*L+4*L*H
그리고 부피(V)는 V=L*L*H=500이다. 표면적(S)는 밑변 L의 함수이므로 V식을 H에 대해 정리하고(H=V/L2) 이를 S에 대입하면
S(L)=4*L*H+2*L*L
=4*L*(V/L2)+2*L2
=(4*V)/L+2*L2
=(4*500)/L+2*L2

b) 표면적이 1000 cm2이하인 경우 밑변의 최대길이를 구하여라
이 문제는 식을 다음과 같이 세울 수 있다.
S(L)<=1000
이 식을 양변에 (-L)을 곱하여 정리하면
1000*L-2*L3<=2000
L이 가질 수 있는 최대값은 엑셀의 해찾기를 사용하거나 MathPapa의 도움을 받으면 된다.




패턴인식 인공지능을 탑재한 엑셀 오피스/VBA/Office.JS

머신러닝이나 인공지능이 전과 다른 점은 자료를 주고 학습하여 스스로 로직을 만들게 하는 것이다. 학습하고 흉내내는 인간의 행태를 옮기려는 것이다. 다음 그림을 보면 여러분은 누가 여러분에게 따로 말하지 않아도 뭘 해야 하는 지 알 것이다. 엑셀에도 이런 기능이 있다고 한다

'서울특별시 강남구 영동대로 513 코엑스'에서 '서울특별시'만 입력하고 CTRL+E를 입력하면 엑셀은 '주인넘이 공백이 나오기 전까지의 글자만 원하는 구나, 그럼 소원대로 해주지~' 라고 하여 부산광역시~인천광역시 등 이하의 주소에서 앞의 시나 도이름만 뽑아주는 것이다. 이메일주소도 마찬가지이다. 네이버 도메인만 입력하면 나머지 이메일주소에서 도메인만 추출한다.

단축키 CTRL+E 만 기억하자

자세한 설명은 아래의 출처에 가면 볼 수 있다
(출처: 엑셀 능력자가 알려주는 엑셀 최고의 기능)

일치하는 항목들을 여러 컬럼으로 풀어놓기 오피스/VBA/Office.JS

어느 분이 질문하신 것중에 위의 그림과 같은 내용에서 [구분]별로 분류하여 [상세]에 해당하는 내용을 정리하는 것이 있었다.
가령 [제공]에 해당하는 [상세]는 '식사제공(중식)','식사제공(석식)','화훼제공','기념품제공'이고 [수령]에 해당하는 [상세]는 '교통제공','선물제공','운동제공','화훼제공'이다.

위의 그림과 같이 수식으로 해결하면 다음과 같다.
= IFERROR(INDEX(상세,SMALL(IF(구분=$F4,ROW(상세)-MIN(ROW(상세))+1),COLUMNS($F$4:F4))),"")

이다. 여기 수식에서 상세는 식사제공(중식)~화훼제공이 입력된 B컬럼의 셀 영역이고 , 구분은 제공~수령이 입력된 A컬럼 셀영역이다. 그리고 각 셀마다 배열수식(CTRL+SHIFT+ENTER 으로 마무리)으로 입력한다.
    G4셀내 함수를 간략히 설명하면 다음과 같다
  • IFERROR() 함수는 에러가 날 경우 이를 처리할 함수이다.
  • INDEX() 함수는 [상세] 영역에서 지정한 행의 값을 가져온다. 실제 데이터를 가져오는 역할을 한다.
  • SMALL()함수는 주어진 배열(array)에서 k번째 작은 값을 가져온다.
  • SMALL()함수의 결과는 INDEX()함수에서 말한 지정한 행의 값이 된다.
      SMALL()함수의 인수 array와 k는 다음의 수식이다.
    • array에 해당하는 식 : IF(구분=$F4, ROW(상세)-MIN(ROW(상세))+1)
    • k에 해당하는 식 : COLUMNS($F$4:F4)
그런데 수식은 아무리봐도 복잡하다. VBA로 해도 초보에겐 복잡하기는 마찬가지인데, 만일 VBA로 한다면 다음과 같다.
Sub GetMatchAll()
Dim lookup_value
Dim lookup_array As Range
Dim rng As Range
Dim matches As String

lookup_value = "수령"
Set lookup_array = Sheet6.Range("A1:A8")

For Each rng In lookup_array
If rng.Value = lookup_value Then matches = matches & "," & rng.Offset(0, 1).Value
Next
Debug.Print Right(matches, Len(matches) - 1)
End Sub
위의 코드는 If문을 사용하여 비교하여 TRUE이면 matches 변수에 [상세]항목을 계속 붙여 나가는 것이다. 그런데 중복된 항목은 체크하지 않는다. 중복된 항목을 체크하려면 간단히 If문에 InStr()함수를 추가한다.
If rng.Value = lookup_value And InStr(1, matches, rng.Offset(0, 1).Value, vbTextCompare) = 0 Then matches = matches & "," & rng.Offset(0, 1).Value


오늘의 걷기 삽질의 추억

일주일에 한번은 집에서 회사까지 걸어 출근한다.  이런 출근을 시작한 것은 거의 10년 전부터인데, 안하는 해도 있기도 하고 겨울엔 개점휴업이기도 했다. 첨엔 EBS 라디오를 들으며 어학공부/운동 삼아 했는 데, 바글거리는 인파에 끼어 실려가느니, 걸어다니는 게  좋다.


당산과 양화 사이에 코스모스 밭


아래는 얼마전에 찍은 길. 태풍이 지나간 직후라서 쓰러진 나무는 베어져 있다.





엑셀 매크로 문제를 도와주기 힘든 이유 오피스/VBA/Office.JS

현대사회의 필수품인 PC에서 발생하는 문제는 PC구성요소가 다양한 만큼 여러 유형의 문제가 생긴다. 예전 사무실에서 일부 PC가 불안정하거나 성능이 나쁜 문제가 있었다. 메모리를 올리고 각종 설정을 바꾸어도 고쳐지지 않았다. 알고보니 PC로 들어오는 전력이 불안정한 게 원인이었다. 상상도 못한 원인이다.

엑셀이나 엑셀매크로도 비슷한 처지이다. 엑셀에는 많은 셀과 수식, 서식, 유효성 검사 등 많은 요소를 때려박고 매크로까지 가담하면 문제의 원인이 어렵거나 의외일 수 있다. 코드만 보고 해결하는 게 아니라 워크시트 등등 여러 가지를 봐야 한다. 둘 다 없이 증상만 갖고는 원인의 가능성 정도만 얘기할 수 밖에 없다.

제목이 '엑셀 매크로 문제를 도와주기 힘든 이유'라서
내용이 '도와줘봐야 호구잡힌다~'는 내용처럼 보인다.
사실 그것에 대해 할말은 많지만 에이~ 해봐야 무슨 소용이...


그러나 이런 문제가 생기면 묻지도 따지지도 않고 도움을 드립니다. 무슨 상업광고같은 멘트를...

Black-Litterman 모델 증권

자산배분 아이디어의 시작은 마코위츠의 평균-분산(mean-variance)모형
1952년 마코위츠(Harry Markowitz)는 포트폴리오 구성에 관한 아이디어를 담은 'Portfolio Selection'이라는 간단한 논문을 발표했으며 이 논문은 이후 투자시장 에 큰 변화를 불러오게 된다. 자산의 기대수익률과 변동성은 비례한다는 하이리스크, 하이리턴 원칙이 시장에 엄격히 적용됨에도 불구하고 자산배분이라는 방법론은 이 원칙에 부분적인 균열을 유도할 수 있음을 발견한 것이다. 즉, 서로 다른 자산들간에 발생하는 분산의 방향의 차이가 상호간에 상쇄간섭을 일으켜 포트폴리오 전체의 변동성을 낮출 수 있으며 이는 효율투자경계(efficiency frontier)에서도 확인할 수 있듯 투자의 효율성 극대화로 이어지게 되는 것이다.

평균-분산 모형의 문제를 보완한 블랙-리터만 모델
그러나 평균-분산 모형은 이론적 명료함에도 불구하고 현실 시장에서 적용하기에 는 여러 한계가 있었다. 기대수익률 변화에 대한 지나친 민감함, 이로 인한 특정 자산 편중이 그러한 문제에 해당했다. 1990년에 처음 발표된 블랙-리터만 모델은 이러한 문제들을 효과적으로 제거할 수 있었고 이후 현재까지 가장 보편적으로 활용되는 자산배분 모형이 되었다.

1990년 골드만삭스의 피셔블랙과 로버트 리터만에 의해 만들어진 모델이다. 피셔블랙! 친숙한 이름인데, BSOPM을 만든 그 분이다. 이 모델은 십수 년간 자산배분계의 표준모형이랄 만큼 널리 쓰이고 있다. 이 모델은 자산의 시장가치에 비례한 자산배분에 기대수익률에 대한 투자자의 견해를 고려 분산투자를 통해 리스크를 줄일 수 있다. 모형의 실질적 구현도 간단명료하다.
  1. 투자대상물을 선별한 다음, 각각의 시가총액 별 비중을 구한다. 이를 통하여 내재균형수익률을 계산한다.

  2. 다음으로 투자대상물에 대한 나름의 분석을 실시한다. 전체를 조사하지 않아도 무방하다. 사정이 여의치 않아서 몇 가지만 조사하여도 된다. 이를 Prior 분포로 설정한다.

  3. 투자대상물에 대한 최종 비중을 결정할 때, 위 “1)”과 “2)”에 제시된 의견이 적절히 섞이도록 한다. 이를 Posterior 분포라고 부른다.
한마디로 말해서, 블랙리터만 모형은 포트폴리오를 구성하는 데에 있어서, 시가총액 비중을 기본으로 두고, 여기에 투자자의 분석을 가미하는 형태다. 여기서 언급할 점이 있는데, 바로 시가총액 비중이 지니는 의미에 대해서다. 블랙과 리터만은 시가총액이란 자산시장의 수요와 공급이 일치하는 상황에서 결정된다고 언급했다. 단지 자산시장의 수요자 입장만 고려한다면, 이는 평균-분산 모형처럼, 주어진 환경 아래에서 특정조건을 만족하는 최적화된 자산을 선택하면 된다.

그러나 공급자 입장까지 고려한다면, 이는 달라진다. 최적화된 자산은 희소성의 원칙에 따라 모든 투자자가 원하는 만큼 가질 수는 없다. 결국 시가총액 비중까지 투자자가 획득할 수 있는 것이다. 따라서 시가총액이란 자산시장의 수요와 공급자 모두가 최적화된 자산을 찾는 과정이 온전히 묻어 있는 결과물이라는 뜻이다.

다른 한편으로는 이러한 생각도 해볼 수 있다. 시가총액 비중이 높은 것에 더 많은 자원을 투입한다는 것은, 결국 최근의 승자가 미래의 승자가 되리라는 가정을 하는 것이다.

마코위츠의 자산배분
2가지의 자산 A1, A2가 있을 때 A1은 A2보다 높은 리스크와 기대수익률을 가짐. 두 개를 조합하면 기대수익률은 종전과 동일하지만 리스크가 준다. 이런 리스크과 기대수익률의 조합은 무수히 많으며 이를 연결해 놓은 선이 효율적 경계선이다. 이 선위의 포트폴리오는 가장 효율적인 구성이며 투자자의 목표수익률이나 리스크감수한도만 지정하면 효울적인 자산배분을 가진 포트폴리오가 만들어 진다.

그러나 소수의 우월한 자산쪽으로 과도하게 배분되는 문제가 발생하고 투자자의 의견(기대수익률)을 반영할 수 없었는데, 이를 보완한 것이 블랙리터만 모델이다. 블랙리터만 모델은 변동성의 비중을 활용하여 기대수익률을 계산한다. 각 자산의 시가총액을 갖고 비중으로 삼는데 시가총액은 수요와 공급이 이루는 균형점이다. 이 균형점에서 나오는 수익률을 기대수익율,내재수익률,균형수익률이라 한다. 이를 바탕으로 투자자의 의견을 반영하는데, 절대수익과 상대수익을 나누어 각각의 의견에 대한 신뢰도를 반영할 수 있다(의견을 넣치 않아도 무관) 이것들을 모형으로 만들어 새로운 수익률과 변동성이 나오고 이에 따른 투자비중을 결정하게 된다.

블랙-리터만 모델은 2가지 특징을 통해 설명할 수 있다. 첫 번째는 자산 별 시장 내 시가총액을 통해 역으로 자산 별 적정 수익률을 산정하는 역최적화(reverse optimization)방법론이며 또 하나는 투자자의 시장전망을 수리화해 비중조정에 적용하는 베이지안 확률론의 도입이다.

글로벌 자산배분모형으로서 블랙-리터만의 한계 인식할 필요
애초 미국 내 주식시장을 대상으로 한 자산배분모형이었던 블랙-리터만 모형은 그러나 글로벌 자산배분 모형으로 도입되기에는 한계점을 안고 있다는 점을 인식 할 필요가 있다. 모델의 가장 큰 특징인 역최적화 방식이 글로벌 자산들을 대상으로 했을 때는 부자연스러운 결과를 만들어내기 때문이다. 선진국과 신흥국 시장의 시가총액 차이가 단순히 기대수익률과 변동성의 함수가 아닌 지역 자체의 경제 규 모 차이에 기인한다는 점이 고려되지 않은 결과였다. 따라서 국내에서 무리한 블랙-리터만 모델의 적용은 지나친 선진국 자산 편중의 결과로 나타날 수 있는데 이에 대한 보완 방법이 모델 활용 이전에 고려될 필요가 있을 것이다.

자산배분 모델의 시작은 마코위츠의 평균-분산모형(mean-variance model)
(처음부분과 중복되는 내용이지만 그냥 올립니다)
현대적 투자관점에서의 자산배분은 1952년 마코위츠(Harry Markowitz)를 그 시점으로 한다. 당시 25세의 대학원생이었던 마코위츠는 Journal of Finance 3월호에 “Portfolio Seletion”이라는 짧은 논문을 게재했고 알다시피 이 아이디어는 이후 시장에 큰 변화를 불러오게 된다.
‘하이 리스크, 하이 리턴’이라는 시장의 격언은 단순하면서도 비가역적인 진리를 담고 있다. 만약 리스크가 낮으면서도 수익률이 높은 자산이 존재한다면 투자자들은 집중적으로 그 자산을 매수해 가격을 높이게 될 것이며 결국 리스크 수준에 맞는 적정한 균형 수익률로 회귀하게 될 것이기 때문이다. 즉, 안전과 높은 수익이 양립할 수 없다는 의미이며 월가식 표현으로 공짜 점심(free lunch)은 없다고 말할 수 있다.

자산배분을 통해 리스크 억제와 수익성 확대 효과를 얻을 수 있음이 견고한 법칙의 빈틈을 발견한 것이 바로 마코위츠의 포트폴리오 이론이라고 할 수 있 다. 자산들의 가격변동에서 발생하는 이분산이 상호간에 상쇄간섭을 일으켜 포트폴리오 전체의 변동성을 낮추는 것을 확인한 마코위츠는 이 현상이 투자의 효율성을 높일 수 있 음을 직관한 것이다.
효율투자경계(efficient frontier)는 포트폴리오 구성이 어떻게 투자의 효율을 높일 수 있 는지 잘 보여준다. 특히 주목할 부분은 backward구간, 즉 변동 성이 감소하면서도 수익성은 높아지는 비중 구간이 존재한다는 점이다. 포트폴리오를 구성함으로써 앞서 말한 하이 리스크, 하이 리턴 원칙을 부분적으로 넘어설 수 있음을 보 여주고 있다. 일반적으로 포트폴리오 구축을 리스크 분산의 차원에서 이해하고 있지만 조금 더 정확하게 표현하자면 투자효율 확대, 즉, 리스크를 통제하면서도 수익성을 희생하지 않는다는 것이 자산배분의 본질적 의미라 할 수 있다.

시장위험 프리미엄

위험 프리미엄

시장의 기대수익률과 무위험수익률간 차이를 시장위험프리미엄이라고 한다.  편하게 무위험수익률에 만족할 수도 있지만, 위험을 조금 더 감수하더라도 추가로 수익을 얻으려고 위험자산에 투자를 한다면 추가로 얻을 수 있는 수익은 위험에 대한 보상인 위험프리미엄인 것이다.


시장위험 프리미엄 = 시장기대수익률 - 무위험 수익률


매우 간단한 식이지만 학자들은 이 간단한 개념을 두고 고민을 하고 연구를 한다. 시장위험 프리미엄을 계산하는 세부적인 방법(수익률의 계산방법, 수익률 계산기간, 무위험수익률을 무엇으로 삼을 것인가 등등)은 분석하는 사람마다 다를 수 있기 때문이다. 아직은 마코위츠의 평균-분산 포트폴리오 모델처럼 인정받는 시장위험 프리미엄 모델이 없다.


몇 가지 시장위험 프리미엄을 추정하는 방법은 다음과 같다.

  • 과거 데이터를 이용하는 과거 시장위험프리미엄

  • 포워드-룩킹(Forward-looking) 모델

  

과거 데이터를 이용하는 방법에서는 프리미엄을 산출하는 기간을 얼마로 할 것인지를 정하는 문제, 산술평균 수익률을 사용할 지 아니면 기하평균수익률을 사용할지 등 수익률산출방법 문제 등을 해결해야 한다. 하지만 실무에서 가장 많이 사용하는 방법이다.


포워드-룩킹 모델은 주식의 현재가치를 이용하여 시장위험프리미엄을 구하는 방법이다. 이 방법은 배당수익률이 일정하다는 가정하에  특정시점에서 주식의 가치를 구하는 고든(Gordon)의 성장모형을 바탕으로 한다.

1) P = D/(Ke - g)

여기서

P 기업의 현재주가

D 기업의 예상배당

Ke 자기자본비용 = 비유동 이자부 부채의 만기수익률 + 위험프리미엄

g 배당성장률


2) Ke = D/P + g

여기서

g = 장기실적예상성장률 <- 일정배당성향을 유지한다는 가정하에 

Ke = 장기국공채수익률 + 시장위험프리미엄 <- 시장의 베타는 1이므로 


3) 시장위험 프리미엄 = 기업의 배당수익률 + 장기실적 예상 성장률 - 장기 국공채수익률 



펌) '깔끔한 글' 쓰는 방법 13가지

글을 쓰는 거, 여기서는 잘 쓰는 거는 중요하다. 검색을 하라고 하면 아이들은 구글 검색엔진이 아니라 유튜브에서 먼저 검색을 할 정도로 현재는 동영상 미디어의 시대이다. 이런 흐름속에 매사가 급한 현대인은 글을 읽고 이해하기 보다, 동영상을 보고 이해하는 것을 선호한다. 그러나 글이 나름의 장점을 가지고 있다. 복잡한 내용을 다루는 경우 글이 강점을 가지고 있는데, 대신 잘 쓰는 게 중요한다.

전략적 자산배분 증권

자산배분은 국내외 주식, 채권, 현금과 같은 다양한 자산을 조합해 포트폴리오의 리스크를 주어진 투자자의 리스크허용한도와 매치시키는 투자전략이다. 이때 리스크는 장기수익률의 변동성을 말한다. 서로 다른 자산들은 시장이나 경제환경변화에 다르게 반응한다. 전략적 자산배분의 목적은 포트폴리오의 변동성이 개별자산의 변동성합보다 낮게 자산을 구성하는 것이다.

전략적 자산배분은 효율적으로 자산을 배치하여 분산의 잇점을 극대화를 추구하며, 이를 위해 평균분산분석을 이용한다. 효율성은 주어진 수준의 리스크에서 달성가능한 가장 높은 수익률로 정의된다. 다양한 리스크 영역에 따라 배치된 자산배분은 효율적 투자선을 형성하게 된다.

마소가 인터넷쇼핑몰 하는 줄 알았네요.

CNBC: Microsoft launches e-commerce tools as Amazon rivalry intensifies.
https://www.cnbc.com/2019/09/23/microsoft-launches-dynamics-365-commerce-taking-on-amazon.html

Equity Swap이란? 증권

(흑우 동생) : '형! 요즘 주식 뭘 사야해~'
(사짜 형님) : '야~ 주식 사지마~ 내가 갖고 있는 주식으로 얻는 매매차익, 배당 등을 너한테 줄 테니까
대신 그 돈에서 예금해두고 이자 나오는 거 나한테 줘라'.
(흑우 동생) : 이게 뭔 사기꾼 같은 소리야~
(사짜 형님) : '주식 사고팔면 수수료 나가고 팔때 세금 나가잖아. 그리고 형이 종목을 잘 고르잖아. 그리고 난 롱숏 전략도 사용할 수 있어! 게다가 형 말처럼 하면 수수료/세금을 절약하고 좋잖아'
(흑우 동생) : 흠 설득력 있네. 설마 흑우가 되는 건 아니지?

에쿼티 스왑을 쉽게 설명하자면 대충 이런 내용이다. 사실 제비용을 뺀 금액을 교환하는 것이지만... Equity Swap이란 미래에 정해진 시점에 기초자산에서 발생하는 현금흐름과 기초자산을 매수기 위한 담보에서 발생하는 수익을 교환하는 계약이다.

자세한 내용은 EquitySwap.pdf 에 ...

심심한 김에 회사에 재능기부?-월급 받잖아~ 오피스/VBA/Office.JS

많은 사람들이 매일 하는 단순작업을 자동화하는 것이 VBA인데, 그런 작업중 하나의 예를 가지고 최선의 VBA코드를 만들어 보려고 한다. 일단 개인적인 의견이지만 최선의 VBA코드는 코드를 되도록 줄이는 것이다. 아예 VBA코드가 없는 게 최선의 VBA프로그래밍이다. 이게 무슨 개똥같은 철학같은 소리이고 어불성설인가? 가지 많은 나무에 바람 잘 날 없다는 속담이 딱 들어 맞는다. 가령 아래와 같은 워크시트가 있는 데, 둘 다 같은 목적과 작업순서를 가진다.

B열의 값이 1.0 이상인 종목에 대하여 C~G열까지 복사하기
(이번 경우에는 C4:G8 (하이라이트 친 부분)이 복사할 셀영역이다)


I열의 값이 25.0 이상인 종목에 대하여 J~Q열까지 복사하기
(이번 경우에는 J4:G7 (하이라이트 친 부분)이 복사할 셀영역이다)


VBA 로 나름 최선의 코드를 만들면 다음과 같다.
Sub GapOver()
    On Error Resume Next
    Const CELL_BEGIN = "B4"
    Call CpyRange(Range(CELL_BEGIN), ">=1", 5)
End Sub

Sub BigPL()
    On Error Resume Next
    Const CELL_BEGIN = "I4"
    Call CpyRange(Range(CELL_BEGIN), ">=25", 8)
End Sub

Sub CpyRange(rngCrit As Range, strCrit As String, numCols As Long)
    Dim cnt As Long
   
    cnt = WorksheetFunction.CountIf(Range(rngCrit, rngCrit.End(xlDown)), strCrit)
    If cnt < 1 Then Exit Sub
    Range(rngCrit.Offset(0, 1), rngCrit.Offset(cnt, 0).Offset(-1, numCols)).Copy
End Sub
 같은 작업이므로 CpyRange() Sub프로시저를 공통으로 만들어 호출한다.
GapOver Sub 프로시저는 판단을 할 셀 영역의 시작부분과 판단기준, 복사할 컬럼의 수를 던져준다(Range(CELL_BEGIN), ">=1", 5)
마찬가지로 BigPL Sub 프로시저는 판단을 할 셀 영역의 시작부분과 판단기준, 복사할 컬럼의 수를 던져준다(Range(CELL_BEGIN), ">=25", 8)

이제 세 개의 매개변수를 넘겨받는 CpyRange() 프로시저는 조건에 맞는 셀의 갯수를 세어서 범위를 계산하고 복사한다. 이렇게 하면 일일이 셀 영역을 지정하여 복사하지 않고 버튼 하나만 누르면 자동으로 클립보드에 복사가 된다. 이후 붙여넣기는 알아서 쓰면 되는 거구...

그런데 코드를 더 줄일 수 있지 않을 까 하는 씰데없는 궁리를 해본다. 가장 중요한 기능-셀 영역을 판단하여 잡는 것-을 VBA가 아닌 엑셀로 할 수 있지 않나...그래서 고안한 아이디어는 OFFSET(), COUNTIF() 함수를 사용하여 셀영역에 이름을 붙이는 것이다.


수식 =OFFSET('일일 리스크관리'!$C$4,0,0,COUNTIF('일일 리스크관리'!$B$4:$B$53,">=1"),5)=OFFSET('일일 리스크관리'!$J$4,0,0,COUNTIF('일일 리스크관리'!$I$4:$I$53,">=25"),8) 는 COUNTIF()의 결과에 따라 동적인 셀 영역을 만들어 준다. COUNTIF()함수는 VBA 코드에서 사용한 바 있는 데, 조건을 만족하는 셀의 갯수를 돌려주는데, 이는 복사할 행의 갯수를 의미한다.

수식이 완성되었으므로 코드는 다시 더 줄어든다.
Sub GapOver()
    Range("종목과다").Copy
End Sub

Sub BigPL()
    Range("손익과다").Copy
End Sub

PS.무료로 간단한 매크로 만들어 드립니다. 대신 이 블로그의 글감으로 사용할 수 있습니다. 그러니 민감한 정보는 주지마세요.

건스앤로지스 Guns N' Roses - You could be Mine - Full Cover

깨방정스럽던 리드보컬 이름이 가물가물해졌지만 여전히 노래는 좋네요. 조만간 개봉할 터미네이터 다크페이트가 기대됩니다.

X 같은 XLOOKUP?

클리앙 새로운 소식 게시판에 가보니 XLOOKUP이라는 함수가 생기나 봅니다.
뭔가 욕같은 느낌이 드는 이름이지만 XLOOKUP이라는 함수가 추가될 예정인가 봅니다. 아직 제가 사용하는 엑셀에는 그런 함수가 없는 데, VLOOKUP의 단점을 보완해줄 느낌적인 느낌이군요. 자매품으로 XMATCH 함수도 있다는 군요.

이딴 거 말고 VBA 에 이어 또 다른 스크링팅 언어로 파이썬이나 자바스크립트(office.js가 있지만)를 엑셀에 낑겨 넣으면 좋겠습니다.


[원본 글] Announcing XLOOKUP

[클리앙]엑셀의 VLOOKUP, HLOOKUP을 대체할 XLOOKUP

[Mr.Excel]The VLOOKUP Slayer: XLOOKUP Debuts Excel

숫자판 자물쇠 열기 삽질의 추억



네 개의 비밀번호를 가진 숫자판 달린 자물쇠가 하나 있는 데, 이것 풀려면 몇 번 시도해봐야 할까?
순서는 상관없는 것으므로 조합이다. 8개중 4개를 뽑는 것이므로

8C4 = 8! / (8-4)!4! = 70

얼핏 기대한 것보다 의외로 가능한 조합이 적어 다행이다. 부작용이라면 쇠를 주물럭거리다보니 손에서 비린내가 나는 듯...

검색을 해보면 무식하게 일일이 70번 시도하는 게 아니라(운이 나쁘면 70번, 운이 좋으면 1번이지만) 자물쇠의 특성을 이용하여 아래의 URL과 같이 푸는 라이프해킹같은 방법도 있다.

[URL]누름식 비밀번호 자물쇠 푸는법 (밑에 열림버튼이 없을때)

1 2 3 4 5 6 7 8 9 10 다음