搜尋此網誌

2010-12-31

backtesting - moving average

程式碼
import yfq

def moving_average(interval, prices):
 temp = []
 for i in range(len(prices) - interval + 1):
  temp.append(sum(prices[i:i+interval])/interval)
 return temp

def transaction(interval, dates_prices):
 temp = []
 len_data = len(dates_prices) - interval
 mv = moving_average(interval, [r[1] for r in dates_prices])
 for i in range(len_data):
  if dates_prices[len_data - i][1] < mv[len_data - i] and dates_prices[len_data - i - 1][1] > mv[len_data - i - 1] and (not temp or temp[-1][1] > 0):
   temp.append([dates_prices[len_data - i - 1][0], -dates_prices[len_data - i - 1][1]])
  if dates_prices[len_data - i][1] > mv[len_data - i] and dates_prices[len_data - i - 1][1] < mv[len_data - i - 1] and (not temp or temp[-1][1] < 0):
   temp.append([dates_prices[len_data - i - 1][0], dates_prices[len_data - i - 1][1]])
 return temp
先取出資料,並以五日線來測試。
>>> from backtest01 import *
>>> a1 = yfq.get_historical_prices('2330.tw','20100101','20101230')
>>> a2 = [[r[0] ,eval(r[6])] for r in a1[1:]]
>>> a3 = transaction(5, a2)
計算買一股的損益
>>> sum([r[1] for r in a3])
0.3500000000000085
計算買一元的最後結果
>>> ans = 1
>>> for r in a3:
...     if r[1] < 0:
...             ans /= -r[1]
...     if r[1] > 0:
...             ans *= r[1]
... 
>>> ans
0.9951649627810805

PS
修改中

2010-12-12

py3k 使用 gnuplot

出處

程式碼
import os
class gnuplot:
    def __init__(self):
        print("opening new gnuplot session...")
        self.session = os.popen("gnuplot","w")
    def __del__(self):
        print("closing gnuplot session...")
        self.session.close()
    def send(self, cmd):
        self.session.write(cmd+'\n')
        self.session.flush()
用法
>>> from gnuplot import *
畫一個 \(y = sin(x)\)
>>> g = gnuplot()
opening new gnuplot session...
>>> g.send("plot sin(x)")
清除
>>> del g
closing gnuplot session...

2010-12-11

Linux 下的 MSN 客戶端 - emesene

emesene

前一陣子又有許多人的 MSN 出問題,我就推薦了 emesene,多平台 (Linux, Mac, Windows),連 Windows 的使用者都讚不絕口。由於通常出問題的都是 client 端軟體,所以就換一個 open source 的 client 就好了。為什麼 server 端比較少問題呢?因為寫 server 的人比較貴,所以比較厲害。俗話說︰一分錢一分貨。那為啥免費軟體寫的更好?因為 open source 不會亂塞東西進程式,而且瘋子黑客比正常人厲害。

PS
最近 emesene 在徵人,要推出第二代,從開發者到測試人員都有,想提昇自己程式功力或鍛鍊溝通能力的人 (當然是英文),請踴躍參加。

計算個股的 alpha, beta, r2, correlation

$$r_{i}=\alpha +\beta r_{b}$$
\(r_{i}\)︰rate of return of stock i
\(r_{b}\)︰rate of return of benchmark

程式碼
import yfq
from volaty import *
gsl.gsl_stats_correlation.restype = c_double

#將兩數列的時間對齊,symbol1 為指數,symbol2 為個股
def match_time(symbol1, symbol2, start_date, end_date):
    temp1 = yfq.get_historical_prices(symbol1, start_date, end_date)
    temp2 = yfq.get_historical_prices(symbol2, start_date, end_date)
    temp3 = dict([[r[0], eval(r[6])] for r in temp2[1:]])
    temp = []
    for i in temp1[1:]:
        if temp3.__contains__(i[0]) == True:
            temp.append([i[0], eval(i[6]), temp3[i[0]]])
    return temp

def performance(symbol1, symbol2, start_date, end_date):
    temp = match_time(symbol1, symbol2, start_date, end_date)
    len_data = len(temp)
    x = []
    y = []
    for i in range(len_data - 1):
        x.append(temp[i][1]/temp[i+1][1] - 1)
        y.append(temp[i][2]/temp[i+1][2] - 1)
    c0 = c_double()
    c1 = c_double()
    cov00 = c_double()
    cov01 = c_double()
    cov11 = c_double()
    sumsq = c_double()
    corre = gsl.gsl_stats_correlation(to_array(x), c_int(1), to_array(y), c_int(1), len_data)
    gsl.gsl_fit_linear(to_array(x), c_int(1), to_array(y), c_int(1), len_data, byref(c0), byref(c1), byref(cov00), byref(cov01), byref(cov11), byref(sumsq))
    return {'alpha': c0.value, 'beta': c1.value, 'r2': sumsq.value, 'corre': corre, 'samples': len_data}
用法
>>> from portfolio import *
>>> performance('^DJI','INTC','20080101','20101210')
{'alpha': 0.00027794897183290666, 'beta': 1.1291841437940686, 'samples': 743, 'corre': 0.7802726964872447, 'r2': 0.18706544590574303}

PS1
台灣的部份問題特別多,主要可能是因為除權的關係(其實就是國際能見度低啦,所以懶的找人修正),造成換算 adj. closing 常常有問題,連大型股 Delta 跟 ASUS 都一樣。
PS2
我看一下 google finance 中 INTEL 的資料也有問題,Nov 24, 2010 沒有成交量,而且也沒有 adj. closing。
PS3
採用 adj. closing 是因為要考慮 total return,指數由於不含息,所以可以考慮用 ETF 代替。

2010-12-09

用 py3k 讀取 C 語言動態檔的 pointer

pointer 是 C 語言最重要的功能之一,也是效能的關鍵。python 中用來讀取 pointer 的是 byref(),使用方式如下。
>>> from ctypes import *
>>> libc = CDLL("libc.so.6")
>>> a = c_int()
>>> b = c_float()
>>> libc.sscanf(b"234 5.654", b"%d %f", byref(a), byref(b))
2
>>> a
c_int(234)
>>> b
c_float(5.6539998054504395)
至於精確度,那就沒辦法了。

2010-12-08

製作 C 語言動態檔給 py3k 使用

這篇是給喜歡簡潔的人看的,或者是需要做最佳化的人,不然可以選擇用 Cython。
將以下存為 forpy.c
int sum(int a, int b, int c) {
 return a + b + c;
}
編譯為動態檔
gcc -shared forpy.c -o forpy.so
在python呼叫與使用
>>> from ctypes import *
>>> mydll = cdll.LoadLibrary('/home/user/forpy.so')
>>> mydll.sum(2,5,8)
15

unrar 專治 p7zip-rar 不能解的 rar

沒辦法,現實社會就是這樣,rar 格式是有版權的,雖然 p7zip-rar 可以解多數的 rar (這也不是開放版本),但是就是有少數不能解,這時唯一的辦法就是用官方的非免費版本。
sudo apt-get install unrar
解壓縮
unrar x target.rar

2010-12-07

如何連結 GSL 並用 gcc 編譯

列出要連結 GSL 所要的正確參數
pkg-config --libs gsl
用 gcc 編譯
方法一
gcc test.c -o test `pkg-config --libs gsl`
方法二
gcc test.c -o test -lgsl -lgslcblas -lm

2010-12-02

自由貿易有避免通膨的效果

最近又看到媒體在炒中國輸出通膨,認為幾年前中國輸出通縮,現在成本上漲後變成輸出通膨。有時太直觀的答案是錯的,這個就很明顯。

先看一下一國的消費模式
$$choice=min[C_{china}, C_{vietnam}, C_{indonesia},C_{others}]$$除非中國成本遠遠低於其他國家,所以當中國的成本上漲後,依然還是最低,這時才會發生中國來的東西漲價這樣的情形;但當漲價到不是最低時,這時我們就會選擇其他國家的東西來當來源,這時中國不管物價怎麼漲都不影響進口物價了。

事實上,Wal-Mart 早已開始慢慢轉向越南等其他國家採購了,所以可知中國成本最低的時代逐漸遠離,除非中國內地或南寧可以完全複製珠三角模式,否則及早尋找多國貿易的路線還是比較重要的。

2010-11-30

Too big to fail

這句沒有主詞的話本身沒有對錯問題,主要是看對應到哪裡。對於政治人物來說,應該是 my sponsors are too big to fail。

政府不能做的事叫做「圖利特定人」,金融業如果面臨崩潰風險,政府要做的是「支撐系統風險」,說某一兩家金融機構倒閉會引起信心危機是事實,但會倒的乾乾淨淨則是言過其實。假如真的這麼好用,那以後戰略專家的超限戰只要研究這個主題就好了,因為弄倒指標公司就可以摧毀整個產業了。

仔細分析金融風暴的成因,多數跟某種一窩蜂的行為有關,這次很明顯是不動產借貸導致的。不過我們會發現,美國各家銀行在住宅抵押貸款的風險暴露比例是不一樣的,citibank 跟 BOA 就比其他大銀行高很多,wells fargo 雖然也受傷頗深,但北方這些信用較好的州還是為它帶來信用分散的優點,最值得稱讚的是 JP Morgan,在 2000 年合併 Chase 後,將貸款證券化後賣出,使得這家銀行的營業槓桿維持在較低的水平,多元化的業務也讓收入並不依賴於不動產抵押貸款帶來的利差。因此我們可以發現,業務分散跟風險管理能力是因應危機的最佳事前準備工作。(真要挑缺點的話,JP Morgan 的手續費收入比例太高,VaR 太低,不過 JP Morgan 是銀行,不是券商)

一樣的道理,歐洲本輪的風暴都不是意外,面臨危機的都是先前赤字就超過歐元標準的國家,唯一的例外是愛爾蘭,以國家的力量去保證私人銀行的債務。這凸顯出歐元沒有懲罰會員國帶來的問題,陷入「制裁就是介入主權」這樣的處境,結果帶來了國家版的「逆選擇」。結果發生問題後,還是得介入才能解決,這樣的「尊嚴」也未免太貴了。

另一方面,這個社會也沒有積極處分肇事者,眾所周知,現代的銀行都不是私人擁有的,在美國只要持有 1% 股份就可以當董事甚至董事長,這些公司出事之後暴露出許多的問題,除了內控問題,還有主管機關的監理問題,這些牽涉的人數之多,範圍之廣,也都是可以追查的,基於金融業的人比較沒種的情形,司法單位事實上是很容易就可以抓出一大串的人。

從以上可以知道,原來對政治人物,這些特定公司真是太重要的,萬一出事很有可能會連累到自己,為了要「師出有名」,too big to fail 實在是太好用了,連信用評等公司都把這項放到最主要的人為信用分數加減項中,看來這招應該可以再撐半個世紀。

2010-11-29

totem 的多媒體插件

雖然一遇到新格式就會自動抓,但是有時後會不夠精明,所以可以用下面的指令安裝全部的常用套件。

sudo apt-get install gstreamer0.10-fluendo-mp3 gstreamer0.10-ffmpeg gstreamer0.10-plugins-bad gstreamer0.10-plugins-ugly

2010-11-27

Standard Barrier Options

$$A = \phi Se^{(b-r)T}N(\phi a_{1})-\phi Xe^{-rT}N(\phi a_{1}-\phi \sigma \sqrt{T})$$
$$B = \phi Se^{(b-r)T}N(\phi a_{2})-\phi Xe^{-rT}N(\phi a_{2}-\phi \sigma \sqrt{T})$$
$$C = \phi Se^{(b-r)T}(H/S)^{2(\mu +1)}N(\eta b_{1})-\phi Xe^{-rT}(H/S)^{2\mu}N(\eta b_{1}-\eta \sigma \sqrt{T})$$
$$D = \phi Se^{(b-r)T}(H/S)^{2(\mu +1)}N(\eta b_{2})-\phi Xe^{-rT}(H/S)^{2\mu}N(\eta b_{2}-\eta \sigma \sqrt{T})$$
$$E = Ke^{-rT}[N(\eta a_{2}-\eta \sigma \sqrt{T})-(H/S)^{2\mu}N(\eta b_{2}-\eta \sigma \sqrt{T})]$$
$$F = K[(H/S)^{\mu +\lambda }N(\eta c)+(H/S)^{\mu -\lambda}N(\eta c-2\eta \lambda \sigma \sqrt{T})]$$
$$a_{1} = \frac{ln(S/X)}{\sigma \sqrt{T}}+(1+\mu)\sigma \sqrt{T}$$
$$a_{2} = \frac{ln(S/H)}{\sigma \sqrt{T}}+(1+\mu)\sigma \sqrt{T}$$
$$b_{1} = \frac{ln(H^{2}/SX)}{\sigma \sqrt{T}}+(1+\mu)\sigma \sqrt{T}$$
$$b_{2} = \frac{ln(H/S)}{\sigma \sqrt{T}}+(1+\mu)\sigma \sqrt{T}$$
$$c = \frac{ln(H/S)}{\sigma \sqrt{T}}+\lambda \sigma \sqrt{T}$$
$$\mu = \frac{b-\sigma ^{2}/2}{\sigma ^{2}} = \frac{b}{\sigma ^{2}}-\frac{1}{2}$$
$$\lambda = \sqrt{\mu^{2}+\frac{2r}{\sigma ^{2}}}$$
$$\left\{
\begin{array}{l r}
C_{di(X>H)} = C+E & \mbox{\(\eta \) = 1, \(\phi \) = 1}\\
C_{di(X<H)} = A-B+D+E & \mbox{\(\eta \) = 1,\(\phi \) = 1}\\
C_{ui(X>H)} = A+E & \mbox{\(\eta \) = -1,\(\phi \) = 1}\\
C_{ui(X<H)} = B-C+D+E & \mbox{\(\eta \) = -1,\(\phi \) = 1}\\
P_{di(X>H)} = B-C+D+E & \mbox{\(\eta \) = 1,\(\phi \) = -1}\\
P_{di(X<H)} = A+E & \mbox{\(\eta \) = 1,\(\phi \) = -1}\\
P_{ui(X>H)} = A-B+D+E & \mbox{\(\eta \) = -1,\(\phi \) = -1}\\
P_{ui(X<H)} = C+E & \mbox{\(\eta \) = -1,\(\phi \) = -1}\\
C_{do(X>H)} = A-C+F & \mbox{\(\eta \) = 1, \(\phi \) = 1}\\
C_{do(X<H)} = B-D+F & \mbox{\(\eta \) = 1,\(\phi \) = 1}\\
C_{uo(X>H)} = F & \mbox{\(\eta \) = -1,\(\phi \) = 1}\\
C_{uo(X<H)} = A-B+C-D+F & \mbox{\(\eta \) = -1,\(\phi \) = 1}\\
P_{do(X>H)} = A-B+C-D+F & \mbox{\(\eta \) = 1,\(\phi \) = -1}\\
P_{do(X<H)} = F & \mbox{\(\eta \) = 1,\(\phi \) = -1}\\
P_{uo(X>H)} = B-D+F & \mbox{\(\eta \) = -1,\(\phi \) = -1}\\
P_{uo(X<H)} = A-C+F & \mbox{\(\eta \) = -1,\(\phi \) = -1}\\
\end{array} \right.$$

\(C\)︰買權 (call)
\(P\)︰賣權 (put)
\(_{u}\)︰up
\(_{d}\)︰down
\(_{i}\)︰in
\(_{o}\)︰out
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S\)︰現貨價格 (spot price)
\(X\)︰履約價格 (strike price) (exercise price)
\(H\)︰障礙價格 (barrier price)
\(K\)︰現金退還 (cash rebate)
\(r\)︰無風險利率 (risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本 (cost of carry)。
\(T\)︰離到期日還有多久,單位是年
\(\sigma\)︰波動率 (volatility),單位是 %

Options on Options

$$\begin{align}
C_{call} &= Se^{(b-r)T_{2}}M(z_{1},y_{1};\rho )\\
&\quad -X_{1}e^{-rT_{2}}M(z_{2},y_{2};\rho )\\
&\quad -X_{2}e^{-rt_{1}}N(y_{2})
\end{align}$$
$$\begin{align}
P_{call} &= -Se^{(b-r)T_{2}}M(z_{1},-y_{1};-\rho )\\
&\quad +X_{1}e^{-rT_{2}}M(z_{2},-y_{2};-\rho )\\
&\quad +X_{2}e^{-rt_{1}}N(-y_{2})
\end{align}$$
$$\begin{align}
C_{put} &= -Se^{(b-r)T_{2}}M(-z_{1},-y_{1};\rho )\\
&\quad +X_{1}e^{-rT_{2}}M(-z_{2},-y_{2};\rho )\\
&\quad -X_{2}e^{-rt_{1}}N(-y_{2})
\end{align}$$
$$\begin{align}
P_{put} &= Se^{(b-r)T_{2}}M(-z_{1},y_{1};\rho )\\
&\quad -X_{1}e^{-rT_{2}}M(-z_{2},y_{2};-\rho )\\
&\quad +X_{2}e^{-rt_{1}}N(y_{2})
\end{align}$$
$$y_{1} = \frac{ln(S/I)+(b+\sigma ^{2}/2)t_{1}}{\sigma \sqrt{t_{1}}},
y_{2} = y_{1}-\sigma \sqrt{t_{1}}$$
$$z_{1} = \frac{ln(S/X_{1})+(b+\sigma ^{2}/2)T_{2}}{\sigma \sqrt{T_{2}}},
z_{2} = z_{1}-\sigma \sqrt{T_{2}}$$
$$\rho = \sqrt{t_{1}/T_{2}}$$

For Call on call and Put on call, solve this equation to get \(I\).
$$C(I,X_{1},T_{2}-t_{1}) = X_{2}$$
For Call on put and Put on put, solve this equation to get \(I\).
$$P(I,X_{1},T_{2}-t_{1}) = X_{2}$$
\(C_{call}\)︰Call on call
\(P_{call}\)︰Put on call
\(C_{put}\)︰Call on put
\(P_{put}\)︰Put on put
\(C\)︰普通買權 (plain vanilla call)
\(P\)︰普通賣權 (plain vanilla put)
\(M\)︰二元 (二變量) 常態密度函數 (bivariate normal density function)
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S\)︰現貨價格 (spot price)
\(X_{1}\)︰標的選擇的履約價格 (strike price of underlying option) (exercise price of underlying option)
\(X_{2}\)︰OoO履約價格(strike price of options on options) (exercise price of options on options)
\(r\)︰無風險利率 (risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本 (cost of carry)。
\(t_{1}\)︰OoO 離到期日還有多久,單位是年(duration of options on options)
\(T_{2}\)︰標的選擇權離到期日還有多久,單位是年(duration of underlying option)
\(\sigma\)︰波動率 (volatility),單位是 %

2010-11-26

Complex Chooser Options

$$\begin{align}
w(S,X_{c},X_{p},t,T_{c},T_{p}) &= max[C(S,X_{c},T_{c}),P(S,X_{p},T_{p})]\\
&=\quad Se^{(b-r)T_{c}}M(d_{1},y_{1};\rho _{1})\\
&\quad -X_{c}e^{-rT_{c}}M(d_{2},y_{1}-\sigma \sqrt{T_{c}};\rho _{1})\\
&\quad -Se^{(b-r)T_{p}}M(-d_{1},-y_{2};\rho _{2})\\
&\quad +X_{p}e^{-rT_{p}}M(-d_{2},-y_{2}+\sigma \sqrt{T_{p}};\rho _{2})
\end{align}$$
$$d_{1} = \frac{ln(S/I)+(b+\sigma ^{2}/2)t}{\sigma \sqrt{t}}$$
$$d_{2} = d_{1}-\sigma \sqrt{t}$$
$$y_{1} = \frac{ln(S/X_{c})+(b+\sigma ^{2}/2)T_{c}}{\sigma \sqrt{T_{c}}}$$
$$y_{2} = \frac{ln(S/X_{p})+(b+\sigma ^{2}/2)T_{p}}{\sigma \sqrt{T_{p}}}$$
$$\rho _{1} = \sqrt{t/T_{c}}$$
$$\rho _{2} = \sqrt{t/T_{p}}$$
$$I = \frac{X_{c}e^{-r(T_{c}-t)}N(z_{1}-\sigma \sqrt{T_{c}-t})+X_{p}e^{-r(T_{p}-t)}N(-z_{2}+\sigma \sqrt{T_{p}-t})}{e^{(b-r)(T_{c}-t)}N(z_{1})+e^{(b-r)(T_{p}-t)}N(-z_{2})}$$
$$z_{1} = \frac{ln(I/X_{c})+(b+\sigma ^{2}/2)(T_{c}-t)}{\sigma \sqrt{T_{c}-t}}$$
$$z_{2} = \frac{ln(I/X_{p})+(b+\sigma ^{2}/2)(T_{p}-t)}{\sigma \sqrt{T_{p}-t}}$$

\(w\)︰抉擇選擇權 (chooser)
\(C\)︰買權 (call)
\(P\)︰賣權 (put)
\(M\)︰二元 (二變量) 常態密度函數 (bivariate normal density function)
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S\)︰現貨價格 (spot price)
\(X\)︰履約價格 (strike price) (exercise price)
\(r\)︰無風險利率 (risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本 (cost of carry)。
\(t\)︰離抉擇日還有多久,單位是年
\(T\)︰離到期日還有多久,單位是年
\(\sigma\)︰波動率 (volatility),單位是 %

Simple Chooser Options

$$\begin{align}
w(S,X,t_{1},T_{2}) &= max[C(S,X,T_{2})-P(S,X,T_{2})]\\
&=\quad Se^{(b-r)T_{2}}N(d)\\
&\quad -Xe^{-rT_{2}}N(d-\sigma \sqrt{T_{2}})\\
&\quad -Se^{(b-r)T_{2}}N(-y)\\
&\quad +Xe^{-rT_{2}}N(-y+\sigma \sqrt{t_{1}})
\end{align}$$
$$d = \frac{ln(S/X)+(b+\sigma ^{2}/2)T_{2}}{\sigma \sqrt{T_{2}}}$$
$$y = \frac{ln(S/X)+bT_{2}+\sigma ^{2}t_{1}/2}{\sigma \sqrt{t_{1}}}$$

\(w\)︰抉擇選擇權 (chooser)
\(C\)︰買權 (call)
\(P\)︰賣權 (put)
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S\)︰現貨價格 (spot price)
\(X\)︰履約價格 (strike price) (exercise price)
\(r\)︰無風險利率 (risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本 (cost of carry)。
\(t_{1}\)︰離抉擇日還有多久,單位是年
\(T_{2}\)︰離到期日還有多久,單位是年
\(\sigma\)︰波動率 (volatility),單位是 %

Time-switch Options

$$
C = Ae^{-rT}\sum_{i=1}^{n} N(\frac{ln(S/X)+(b-\sigma ^{2}/2)i\Delta t}{\sigma \sqrt{i\Delta t}})\Delta t$$
$$P = Ae^{-rT}\sum_{i=1}^{n} N(\frac{-ln(S/X)-(b-\sigma ^{2}/2)i\Delta t}{\sigma \sqrt{i\Delta t}})\Delta t$$

\(C\)︰買權 (call)
\(P\)︰賣權 (put)
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S\)︰現貨價格 (spot price)
\(\alpha\)︰履約價格 (strike price) (exercise price)
\(r\)︰無風險利率 (risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本 (cost of carry)。
\(T\)︰離到期日還有多久,單位是年
\(\Delta t\)︰基本的間隔時間 (time interval)
\(A\)︰累積乘數 (accumulation)
\(\sigma\)︰波動率 (volatility),單位是 %

Ratchet Options (Moving Strike Options) (cliquet options)

$$
C = \sum_{i=1}^{n}Se^{(b-r)t_{i}}[e^{(b-r)(T_{i}-t_{i})}N(d_{1})-\alpha e^{-r(T_{i}-t_{i})}N(d_{2})]$$
$$P = \sum_{i=1}^{n}Se^{(b-r)t_{i}}[\alpha e^{-r(T_{i}-t_{i})}N(d_{2})-e^{(b-r)(T_{i}-t_{i})}N(d_{1})]$$
$$d_{1} = \frac{ln(1/\alpha )+(b+\sigma ^{2}/2)(T-t))}{\sigma \sqrt{T-t}}$$
$$d_{2} = d_{1}-\sigma \sqrt{T-t}$$

\(C\)︰買權 (call)
\(P\)︰賣權 (put)
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S\)︰現貨價格 (spot price)
\(\alpha\)︰履約價格 (strike price) (exercise price) / 現貨價格 (spot price)
\(r\)︰無風險利率 (risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本 (cost of carry)。
\(T\)︰離到期日還有多久,單位是年
\(\sigma\)︰波動率 (volatility),單位是 %

Forward Start Options

$$
C = Se^{(b-r)t}[e^{(b-r)(T-t)}N(d_{1})-\alpha e^{-r(T-t)}N(d_{2})]$$
$$P = Se^{(b-r)t}[\alpha e^{-r(T-t)}N(d_{2})-e^{(b-r)(T-t)}N(d_{1})]$$
$$d_{1} = \frac{ln(1/\alpha )+(b+\sigma ^{2}/2)(T-t))}{\sigma \sqrt{T-t}}$$
$$d_{2} = d_{1}-\sigma \sqrt{T-t}$$

\(C\)︰買權 (call)
\(P\)︰賣權 (put)
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S\)︰現貨價格 (spot price)
\(\alpha\)︰履約價格 (strike price) (exercise price) / 現貨價格 (spot price)
\(r\)︰無風險利率 (risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本 (cost of carry)。
\(T\)︰離到期日還有多久,單位是年
\(\sigma\)︰波動率 (volatility),單位是 %

2010-11-25

Excutive Stock Options 員工股票選擇權

$$
C = e^{-\lambda T}[e^{(b-r)T}SN(d_{1})-e^{-rT}XN(d_{2})]$$
$$P = e^{-\lambda T}[e^{-rT}XN(-d_{2})-e^{(b-r)T}SN(-d_{1})]$$
$$d_{1} = \frac{ln(\frac{S}{X})+(b+\frac{\sigma^{2}}{2})T}{\sigma \sqrt{T}}$$
$$d_{2} = d_{1}-\sigma \sqrt{T}$$

\(C\)︰買權 (call)
\(P\)︰賣權 (put)
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S\)︰現貨價格 (spot price)
\(X\)︰履約價格 (strike price)(exercise price)
\(r\)︰無風險利率 (risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本 (cost of carry)。
\(T\)︰離到期日還有多久,單位是年
\(\sigma\)︰波動率 (volatility),單位是 %
\(\lambda\)︰年度跳動率 (jump rate per year)

2010-11-11

替 ubuntu 的 py3k 安裝 pycairo

由於 Lucid 預設是 python2.6,而且安裝程式在判斷時不會去找 python3,所以需要先把 python3 設為預設,可以參考這篇

pre-requirement
sudo apt-get install python3-dev libcairo2-dev
然後下載 for python 3.x 的版本,切換到該目錄
./waf configure
./waf build
sudo ./waf install

PS
如果是要用 python2.6 的版本,可以直接從 repositories 安裝。

ubuntu 改變指令列預設應用程式

由於 Lucid 預設是 python 2.6,而 google app engine 要用 python 2.5,而我主要用 python3,所以要常切換,但是有的安裝程式都選預設的,因此要手動調整。

首先分別給予優先次序,數字越高越優先
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 80
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.5 60
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.6 40
設定要選用哪一個
sudo update-alternatives --config python
最後,要記得改回 python2.6,不然會出現一些小問題,因為 Lucid 很多 python scripts 都不相容 python3k。

gnumeric 的轉檔命令列 - ssconvert

常常需要從網路上抓資料的人,很不喜歡的檔案格式應該是 xls,需要依靠其他 library 來轉檔,python2 可以用 xlrd 來讀取資料,不過我是用 python3,所以不能用,而且根據這篇顯示,目前都沒有支援 python3 的計畫,所以此路不通。

好在安裝 gnumeric 有一個命令列工具 ssconvert,可以直接將檔案轉換,支援的有 excel 97/2000/XP/2003/2007,Lotus,Xbase等,詳細名單可以輸入以下指令查詢
ssconvert --list-importers
輸出格式也很多,不過不支援 ps,可以輸入以下指令查詢
ssconvert --list-exporters
示範用法︰將 source.xls 轉成 target.csv
ssconvert source.xls target.csv

2010-11-10

破解外資迷思 - 資訊不對稱篇

我通常對吹牛的人冷眼看待,不過有的人實在吹的太誇張,而且還到處招搖撞騙,這篇就是針對這一小撮人的。

一般來說,金融市場價格是 random walk,所以賺賠的機率是一半一半。但是有種東西叫資訊,這東西是很有價的,尤其是大型參與者的動向。

這裡要舉的就是外資銀行外匯交易員的吹噓,通常自稱有 God's sense 或 God's feeling,就跟乩童自稱神明附身一樣,都是胡扯。關鍵在於這些人處在的位置是大型的外商銀行,這些外商銀行通常身兼保管銀行,也有很多大型國際客戶,因此他們會清楚知道客戶的動向,所以他們做的動作說穿了就是跟單,有的人被拆穿會說他是在做 flow following,其實是一樣的意思。就好比接主力單的營業員會跟單一樣,搭客戶的順風車。

另外還有一種資訊不對稱,就是仲介交易的人口風不緊,把你的交易動態洩漏出去,所以有經驗的 portfolio manager 會叫 dealer 下給不同的 broker,再從 broker 口中探尋其他人的動態。這招聰明一點,可是 broker 也不笨,他會把小客戶的動向告訴大客戶,這樣大客戶可以在短線修理小客戶,broker 則可以賺到更多手續費。over-the-counter 型態的交易很常見這樣的現象,譬如 IRS(Interest Rate Swap)。

這種情形其實相當多,好比央行修理投機客,也是打電話問台北外匯經紀或元太,到底現在是誰在掛單,然後再打電話去銀行道德勸說或請喝咖啡,有時會突擊進行金檢。

類似的情形在 1998 年亞洲金融風暴也發生過,當時 Soros 從很多基金公司借股票來賣,HKMA 問港交所是誰在賣,也問 broker 是誰在賣,不過這些法人很有職業道德,死都不講,最後 HKMA 使出大絕招,把所有的場內交易員都叫進來 (當時還是人工撮合),把接 Soros 單的人擠出去,完成了護盤的動作。

整段看下來,就知道那些吹牛的人有多淺,下次遇到這些人,不爽的話不用給他們面子。

PS
法人 dealers 跟 brokers 看似肝膽之交,其實都是建立在利益上,所以 brokers 經常要滿足 dealers 的「各種需求」以換取交易量,畢竟通風報信這檔子事的進入門檻是挺低的。

2010-11-09

在 acer R3610 裝 CUDA

由於內建的 ION 顯示晶片有支援 CUDA,內有 2 (MP) X 8 (Cores / MP) = 16 Cores,所以可以做 16 條的平行運算 (parallel computation),以下憑印象寫的,有問題請提出。

System:
OS: ubuntu 10.04, Linux-x86_64
linux core: 2.6.32-25-generic
NVIDIA driver: 260.19.12
CUDA: 3.2.12(RC2)
gcc: 4.4.3

安裝步驟︰
1.先裝 libxi-dev 跟 libxmu-dev
sudo apt-get install libxi-dev libxmu-dev
2.下載 toolkit 跟 SDK 並變更檔案權限
chmod a+x cudatoolkit_3.2.12_linux_64_ubuntu10.04.run
chmod a+x gpucomputingsdk_3.2.12_linux.run
3.安裝 toolkit
sudo sh ./cudatoolkit_3.2.12_linux_64_ubuntu10.04.run
4.設定 path 與 libraries
export PATH=$PATH:/usr/local/cuda/bin
export PATH=$PATH:/usr/local/cuda/bin64
由於安全性因素,所以 LD_LIBRARY_PATH 內設定的路徑在重新開機後會清空,所以採取以下作法,參考 LD_LIBRARY_PATH in Ubuntu 10.04 Lucid
sudo gedit /etc/ld.so.conf
加入這兩行並存檔
include /usr/local/cuda/lib
include /usr/local/cuda/lib64
為了避免衝突,需要修改一些 libraries,參考 INSTALLING CUDA ON UBUNTU 10.04
sudo gedit /etc/modprobe.d/nvidia-graphics-drivers.conf
改成如下並存檔
blacklist vga16fb
blacklist nouveau
blacklist lbm-nouveau
blacklist nvidia-173
blacklist nvidia-96
blacklist nvidia-current
blacklist nvidiafb
5.安裝 SDK
sudo sh ./gpucomputingsdk_3.2.12_linux.run
設定連結
sudo ln -s /usr/lib/nvidia-current/libcuda.so /usr/local/cuda/lib64
sudo ln -s /usr/lib/nvidia-current/libGL.so /usr/local/cuda/lib64
sudo ln -s /usr/lib32/libGLU.so /usr/local/cuda/lib
6.編譯範例
cd ~/NVIDIA_GPU_Computing_SDK/C
make
會在 smokeParticles 這裡停下來,說缺了 libGLU,我設了 32 位元跟 64 位元的連結都沒用,所以放棄;不過我要的已經好了
cd bin/linux/release
./deviceQueryDrv
輸出畫面如下
CUDA Device Query (Driver API) statically linked version 
There is 1 device supporting CUDA

Device 0: "ION"
  CUDA Driver Version:                           3.20
  CUDA Capability Major/Minor version number:    1.1
  Total amount of global memory:                 265617408 bytes
  Multiprocessors x Cores/MP = Cores:            2 (MP) x 8 (Cores/MP) = 16 (Cores)
  Total amount of constant memory:               65536 bytes
  Total amount of shared memory per block:       16384 bytes
  Total number of registers available per block: 8192
  Warp size:                                     32
  Maximum number of threads per block:           512
  Maximum sizes of each dimension of a block:    512 x 512 x 64
  Maximum sizes of each dimension of a grid:     65535 x 65535 x 1
  Maximum memory pitch:                          2147483647 bytes
  Texture alignment:                             256 bytes
  Clock rate:                                    1.10 GHz
  Concurrent copy and execution:                 No
  Run time limit on kernels:                     Yes
  Integrated:                                    Yes
  Support host page-locked memory mapping:       Yes
  Concurrent kernel execution:                   No
  Device has ECC support enabled:                No
  Device is using TCC driver mode:               No

PASSED

Press ENTER to exit...

ubuntu 9.10 可以參考 How to Install CUDA 3.0 SDK on 64 bit Ubuntu 9.10 (Karmic)
ION LE 也可以裝,這個人用 HP mini 311,請參考 CUDA on Nvidia ION under Linux Does it work?

興櫃市場不是公開市場

最近看到報紙熱炒一些興櫃轉上市或上櫃的公司,忽然發現我沒有寫過這篇,所以趕快補上。

所謂的興櫃其實是更像 over-the-counter 的市場,同一時間存在多個買價跟賣價,要跟哪一個出價成交是可以自由選擇的,也就是說不一定會跟最佳的買價或賣價成交。

小投資人可能會好奇,為啥不跟最佳的價格成交呢?原因還是出在做價。譬如某 A 券商以 75 元賣給某 B 券商,隔日某B券商再以 85 元賣給某 A 券商,如此就可以決定該興櫃股票的公開市價。可能還有人會問,那不會有其他成交嗎?答案是很難,因為承銷商只願意跟配合作價的另一方承銷商做價,別忘了這是可以指定交易對象的市場。

所以啦,興櫃的 K 線圖是承銷商開心怎麼做就怎麼做,媒體故意誤導當然是其中有隱情,有理智的人都知道要從基本面來評估未公開交易的金融商品,只有想賺快錢的人才想投機。說得誇張一點,興櫃市場比交易量大的未上市市場更黑暗,因為未上市市場還算是半公開市場,遵循一定的市場邏輯。至於這個奇怪的興櫃市場,就讓奇怪的人去玩吧。

2010-11-08

破解外資迷思 - 放假福利篇

一般初到台灣外商上班的人,最開心的應該是一年可以休四個禮拜的假,尤其是美系的外商。許多人以為這是福利,沒錯,但這也是一種交易,公司以放你長假的方式交易內部稽核。

先解說一下這個制度運作的狀況,通常一年會叫你放兩次各兩週的假,然後你不在的這段期間,稽核人員就會來查你的日常工作流程,是否有問題,譬如你是不是有做一些鑽公司稽核漏洞的地方,或者是你無意間犯下損害公司利益的事。這套制度運作良好,因為你的代理人會在兩個禮拜內遇到各種狀況,包括灰色地帶的事情。

初次放假的人回來後,稽核會給出一大串應改進事項,新人通常會很驚訝,因為自己會以為都很小心的地方都需要被糾正。而且,每一次休假回來都還是有新的問題,甚至會覺得稽核在找麻煩。

平心而論,這是一套好制度,而出發點則是「性惡論」。因為員工有可能為了自己的利益而做出損害公司的事情,公司為了抓出問題,需要用控制變因的方式來處理,也就是當你不在時是否會出問題。而要讓這套理論成功的關鍵就是適當的價格,也就是放長假,多數的員工會認為這是一項福利。

而稽核的人員常常都是直屬於全球總部,上層單位不是 CEO 就是董事會,所以對於分公司可以說是絕對性的中立,大大減少了分公司舞弊的可能性。

所以下次聽到有人說外商的放假福利時,就會知道這其實是很好的雙贏策略跟公司治理,員工跟股東同時受益,雖然出發點是「性惡論」。

2010-11-06

懶人的 PDF 中文亂碼解決方式

這篇相當的不硬派,但是實在被 PDF 內嵌字型搞煩了,adobe reader 升到 9.4 版後,9.1 版的中文插件有問題;xpdf 可以用,但是很醜;比較好用的是 foxitreader,不過不是 open source,而且搜尋功能不能直接輸入中文。後來想到 google 要用 chrome 當 OS,所以這個一定可以,一試之下,果然沒錯,不管簡體繁體的內嵌字型都可以正常閱讀了。目前只要等 chrome 改版,新增列印功能,就可以把檔案輸出到 evince 閱讀了。

這邊有關於技術的討論,有興趣自己看。

update on 2010.12.04︰chrome 9.0.597.0.dev 已經支援列印功能了。

PS
關於更舊的 PDF 檔內嵌細明體等 M$ 字型的,可以安裝 poppler-data 來解決找不到字型的問題,在 Synaptic 裡有。

2010-11-04

好用的文件轉檔程式 - Calibre

Kindle 不支援 epub,但是卻支援 mobi,可能有較為深層的策略思考(其實是因為這專利是自己的吧),作為一個一般消費者,還是把格式搞定比較重要。目前原生支援 mobi、prc、txt、tpz、pdf,有點少。

Calibre,一個開放原始碼的轉檔程式,多平台,支援 epub、fb2、lit、lrf、mobi、pdb、pdf、pmlz、rb、rtf、tcr、txt 互轉,內建一個 viewer 可以讀 epub 與 mobi 等格式。

PDF 檔在 kindle 上看有點麻煩,雖然已經是原生支援,但是字型不能放大縮小,只能整頁放大縮小,轉成 mobi 檔可能是現階段比較好的解決方式。這是目前看中文文件的最佳方式,不過檔名還是只能用英文,不然都會出現一堆亂碼。至於寄到 yourname@free.kindle.com 轉檔為 .azw,中文一樣行不通,不管是 BIG5 或 UTF8。

以 root 權限安裝。
apt-get install calibre
轉換 epub 為 txt。
ebook-convert input.epub output.txt
看來又重演眾家廠商看好未來商機,為了建立地盤所以打格式戰,有當年 blu-ray 大戰 HD DVD 的味道。

2010-11-03

計算歷史波動率

$$u_{i} = ln(\frac{s_{i}}{s_{i-1}})$$
$$\sigma = std(u_{i}) = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}(u_{i}-\bar{u})^{2}}$$

程式碼
import math
import yfq
from ctypes import *
gslcblas = CDLL('libgslcblas.so.0',mode=RTLD_GLOBAL)
gsl = CDLL('libgsl.so.0')
gsl.gsl_stats_sd.restype = c_double

#計算波動率
def volaty(data):
    len_data = len(data)
    temp = []
    for i in range(len_data - 1):
        temp.append(math.log(data[i]/data[i+1]))
    return gsl.gsl_stats_sd(to_array(temp), c_int(1), c_int(len_data - 1)) * math.sqrt(252)

#取得收盤價
def closing_prices(symbol, start_date, end_date):
    temp = yfq.get_historical_prices(symbol, start_date, end_date)
    return [eval(r[6]) for r in temp[1:]]    #用eval把str轉為num,a1[0]為定義,故不需要

#將python list轉變為C的array
def to_array(data):
    len_data = len(data)
    initi = c_double * (len_data)
    temp = initi(0)    #先把全部設為0,否則無法逐一變更
    for i in range(len_data):
        temp[i] = data[i]
    return temp
使用方式︰
>>> from volaty import *
>>> volaty(closing_prices('2330.tw', '20091027', '20101027'))
0.178008114423158

2010-11-02

替 ubuntu 安裝台灣教育部的中文全字庫

由於 Lucid 預設是採用 WQY Micro Hei,部份寫法跟台灣正體中文不同,相信對於很講究正體中文的人來說,應該是深惡痛絕,譬如國文老師。好在有中文全字庫這樣的政府資源,讓需要的人可以用正確的正體中文。

總共提供兩種向量字型,全字庫正楷體跟全字庫正宋體,安裝方式如這篇

替 ubuntu 安裝新字型

因為有的動畫片採用 .ass 字幕,有些特殊效果會用不同字型來表達,所以需要安裝這些字型,至於使用哪些字型,可以參考這篇把字幕檔抽出來看看就知道了,少部份會附上字型檔,那就更方便了。

首先建立一個新檔案夾在 /usr/share/fonts/truetype/others
sudo mkdir /usr/share/fonts/truetype/others
拷貝新字型到目錄
sudo cp 新字型 /usr/share/fonts/truetype/others/
更新系統中的快取
sudo fc-cache -f -v

增加其他 python 版本到 ubuntu repositories

雖然可以直接從 python 官網下載其他版本的 python,但 Lucid 只有是 2.6 跟 3.1,為了日後維護的方便,所以採取 ppa 的 solution。

Old and New Python Versions

由於 google app engine 只支援 python 2.5,所以想用的人就乖乖適應吧。

2010-11-01

外幣計價商品 - 台灣的結構債回顧

我不反對任何 copy 的動作,正如我對這個部落格的文章與程式的態度,可恥的是剽竊,還有欺騙外行人的舉動,這正是台灣的金融業最令人不齒的。

首先,基於各類型的投資需求與規避法規的需求,衍生性商品因應而出。在前幾年利率很低的時候,推出了大量的結構式商品,這看起來是好的趨勢,真正令人詬病的是假專業真詐騙。

傳統銀行業務由於過份競爭而需要殺價,到了賣結構債這件事,變成了吹牛大賽。一般來說,組成一個 100 元面額的結構債,只要條款設得夠黑心,70 ~ 85 元就可以完成,銀行抽 1 元,業務員抽 3 ~ 5 元,而且風險越大的商品,佣金給的越高,所以業務員無不發揮唬爛的口才說服客戶買各種高風險產品。

最早的時候,這個業務是由外資券商的投顧在做,後來變成主要是券商的海外投資公司進行,譬如 XX 資產管理公司,這類紙上公司通常設在香港,然後由券商的母公司進行業務擔保;不過有某一兩家規模很大的,卻是沒有人擔保的。這個時期,外資券商投顧負責批發給台灣的下游資產管理公司。沒多久,券商發現可以自己去找這些外商的亞洲分部直接 quote 價格 (猜對了,這些掛在台灣的人,職位都很低,不過媒體還是超愛),佣金可以被少抽一手。券商是有能力複製這些東西的,不過投資公司的規模太小,信用等級太低,所以這條路行不通,也做不大。

艱困的銀行業看到了這玩意,發現可以用國際部或信託的 vehicle 來做這個業務,正解。因為相對於投資管理公司只是一般類型的公司,如果開戶在那,實際上是資產管理公司的子帳戶,帳戶名稱實際上是 XX 證券香港分公司- XX 資產管理公司-某某客戶,也就是說資產管理公司才是子帳戶的擁有人;在這方面,銀行的帳戶是完全屬於客戶的,所以你可以從銀行領券出來,卻不能從資產管理公司領券出來。有鑑於此,後來也有券商把資產管理公司升級成 XX 證券(香港),這樣就跟銀行打成平手了。

這些銀行的缺德事從這裡開始,由於批發量更大,想賺的也更多,所以最兇殘的商品都從這邊出來,加上高佣金的吸引,銀行行員都是一知半解就開始賣,一般有點年記的行員都還有道德良心,所以不嚴重,但是高層為了手續費收入,大舉聘用各種銷售人員來賣這玩意,這些人平均水平大概跟信用卡推銷員差不多,由於無知加上高獎金誘惑,這段時期可以說是結構債良心黑暗期,連坐計程車都會被推銷。

這時銀行總公司的人員好像顯的很無能,為了搶一杯羹,但是數學不好,程式語言也不好,所以就想出了 back-to-back 這樣的方式,賺更多但是換成自己銀行的名子來銷售,這個時期銀行陸續找了一些新人進來,也有自行設計與避險的產品,少數銀行甚至有 tailor-made 的產品。但好景不常,2007年 country wide 事件後,大家心態趨於保守,加上因銷售解說不當造成的糾紛越來越多,很快就賣不動了。

事後總結,銀行發現自行設計商品比較好賺 (多賺十幾倍),但是這些人很貴,便宜的人都是 copycat (一知半解),比不懂還遭,因為不懂就不敢玩;找來那些外商的 sales 當頭是很笨的作法,因為 sales 都是滿口謊話,不利於銀行業的長期經營;亂找 sales 賣也容易發生糾紛,好在主管機關跟司法單位偏袒,不然可能會被告倒。所以各銀行又走回老路,這些東西還是代銷就好,而且不能選風險太高的。

PS1
海外 quote 價格多半是香港 (equity) 跟新加坡 (rate, fx)
PS2
其實壽險公司也買了很多這玩意,傳言有 sales 因此買了遊艇。
PS3
高難度的事業跟電影一樣,想用小資本來玩多半是很慘,數學好又不想離開台灣的人都當精算師去了。
PS4
要拆解這些商品不難,只要看懂 pay-off 就可以完成,這邊有基本的概念。

2010-10-30

如何取得專業的基本面資料

如果想要做仔細一點的基本面研究,時常會發現難以取得專業的資訊,譬如想要研究半導體,會發現無論本土中文或外商英文報告都很少講到產品技術性的問題,偏偏這是影響科技公司長期發展最重要的事,這時就需要閱讀公開說明書了。

所謂的公開說明書 (prospectus) 是公司需要從資本市場籌資時的公開說明文件,譬如上市、增資,發行債券等,都需要出一份這樣的文件,由發行公司跟承銷商共同完成,裡面涵蓋所有需要揭露的資訊,尤其是在公司的產品、策略、市場競爭狀況等等,所以如果需要做研究,尤其是對這產業頗熟悉,公開說明書值得好好閱讀一番。

台灣的部份,公開資訊觀測站新站→資本資料→電子書→公開說明書;公開資訊觀測站舊站→常用報表→公開說明書。

香港的部份,HKExnews披露易,中文叫做上市文件,進階搜尋→所有標題類別及文件類別→標題類別→上市文件,英文叫做 Listing Documents,Advanced Search→Headline Category and Document Type→Headline Category→Listing Documents;因為官方文件都是英文的,所以英文的文件比較齊。

美國的部份,otcMarkets,輸入搜尋名稱或 ticker 後,在 financials 裡,找 424B (prospectus)、10-K (年報)、10-Q (季報)、S-1 (註冊敘述)等文件。這網站相當不錯,提供多種格式,PDF、RTF、HTML、Excel等,相信對於要直接抓資料的人應該很有用。

台灣的政府機關網頁實在寫的夠爛,觀測站的 JAVA 為啥可以寫的這麼不相容於其他瀏覽器,為啥可以寫的這麼不穩,網站配置為啥可以這麼醜,使用介面為啥可以這麼難用,就算做不到 W3C 標準,好歹也要追上香港吧。

2010-10-25

最偉大的套利 - 員工配股 - 內部成本外部化

所謂賠錢的生意沒人做,砍頭的生意有人做,市場就是這種邏輯。其中最經典的,要屬台股的員工配股問題。

其實所謂的台版員工配股,就是一種內部成本外部化,將企業要付給員工的薪資轉到資本市場來付,常見的作法是,本來一個月工資5萬,變成一個月工資四萬加一張股票(10元X1000股),很明顯,這是一種套利(公司本身現金流出減少)。當然也只有在公司賺錢的情形下,提撥15%出來發獎金,但是把獎金換成股票,這時股價就發揮了乘數的效果,如果股價50元,員工可以拿到的獎金就會變成五倍。仔細想一下,也會發現這會損害股東權益,因為持股比例被稀釋了,照道理股東應該會反對,事實上這裡有一個有趣的狀況,就是只要股東持股的市值能夠繼續上升,雖然持股比例被稀釋了,股東還是能夠接受這個遊戲規則,這裡又出現了另一個套利現象,資本市場補貼了股東的損失。

至於為什麼資本市場也會買單呢,第一,這些本來該當教授跟研究單位的人,跑去做大學生跟研究生做的事,的確為公司帶來了巨大利益;第二,市場本身也非一直是有效率的,市場本身也會誤判(譬如某公司公佈業績後股價暴跌);第三,媒體大力宣揚填權效應。主要靠著以上三個原因,造就了台版員工配股這種怪異的現象,直到資本市場逐漸承受不住與社會對公平的討論,這制度才劃下句點。

這個有趣的套利制度維持了近20年,算是很慢很慢才被修正,而且政府不管動機為何,竟是意外做了對的事。

reference: 李存修談金融》員工分紅費用化 股價會跌嗎?
基本的會計觀念告訴我們,企業所支付的錢,除了付給股東之外,都屬費用或成本。然而今日普遍存在於企業界,用以激勵員工的「分紅入股」,卻被當作是盈餘的分配,而不是薪資費用。

從稅的角度來看,應該做費用的項目沒有費用化,會使稅前盈餘增加,稅負也會跟著提高,對企業應該是不利的。可是在各種獎勵投資的租稅減免下,高科技產業的稅率極低,企業也就樂於以股票取代部分正常薪資,以減少現金支出的壓力。久而久之,大家也就有樣學樣,習以為常。

近日傳出改革的呼聲,希望將員工分紅入股費用化,而且以市價入帳,以反映真正的成本結構,引起廣泛的討論,有主張維持現狀的、有主張按面額計價的、有主張按市價打八折的、也有人主張98年促升條例屆滿後,再行實施,莫衷一是。

在此我們不討論員工分紅入股是否合理,事實上,它對台灣科技產業的蓬勃發展有一定的貢獻。我們所要討論的是員工分紅入股費用化之後,是否會造成股價下跌?

假設一家公司EPS 3元,市價60元,本益比20倍,員工分紅之股票若按市價計算,占EPS兩成,稅率為零。費用化之後EPS降為2.4元,若本益比維持20倍,股價將跌到48元。此一推論看似有道理,其實不然。

在現制之下,員工分紅之總股數必須揭露,專業的財報分析人員自會將之從盈餘中扣除,調整成員工分紅費用化後之應有盈餘,尤以外資為然。

這些調整後的盈餘資訊,經由投資行為,應已反映在股價上,會計上是否將之費用化已不重要,這是一個效率市場應具有的特質,而眾多的實證研究已能支持臺灣股市具有半強式的效率性,換言之,股價具有瞬間反映公開資訊之價值的能力,因此我們認為員工分紅的費用化不會引起股價下跌,除非該等資訊過去沒有揭露。

再從另一個角度來看,中大型的科技公司多有跨國掛牌,如ADR、GDR等。以ADR在美國上市的公司,必須按美國一般公認會計原則編製報表,自須將員工分紅費用化,ADR之價格自然反映了費用化後的盈餘。眾多的研究指出,ADR之價格與其在台灣的原股價格有密切的連動關係,因此,台灣的股價也應已反映費用化的影響,日後何時開始實施,以何種價位來計算,都不應再度對股價有所影響,「股價會大跌」之說不太可能出現。

也有人認為股東的股票股利也應按市價課綜合所得稅,以達員工與股東之公平待遇,此說乍聽之下似有道理,其實不然。股票股利只是把股權切割得更細,讓每位股東得到更多股票,按持股比率來看,其實並沒有改變,猶如一塊pizza原來切成八片,每人吃一片,後來切成十六片,每人吃二片,每人吃到的份量並未改變,也因此美國對股票股利及股票分割均不課稅。台灣按面額來計算股票股利所得,從而課所得稅,本來就不太合理,更遑論用市價來計價?

員工分紅入股之屬性與股東之股票股利完全不同,員工分紅是真正的所得,課稅當屬合理;股東之股票股利只是pizza的重新分割,並不是真正的所得,股價因除權而下跌,股數雖然增加,理論上總價值在除權交易日開盤時應不會改變,日後是否填權仍在未定之天,二者不應相提並論。

(作者是台大財金系教授,專長公司治理、金融創新、資本市場與財務管理)

【2006/06/20 經濟日報】 @ http://udn.com

PS1
員工配股費用化後,反應了社會總共付出的成本,多數公司玩不下去,那些原本該在教書跟研究單位的人,紛紛又回到了原來的崗位。
PS2
國外本來就是配股跟選擇權要費用化,所以這套騙術行不通。
PS3
這偉大的套利,據說是TSMC發明的,民國7X年時,成績不好的EECS學生都到這公司,當時這是一家準國營事業,面臨倒閉破產的危機,所以想出了這個招式,後來遭到各電子公司模仿。

理論與實際的差異 - 套利與基差

現實狀況永遠與理論狀況有落差,但是通過某些作為,可以使的落差減少,套利就是其中的一個辦法。

以台股指數期貨為例,除了除息季節外(因為加權股價指數需要減去股息),一般基差都是維持在 +-50 點以內,這個範圍就是券商的套利成本,由於自營商不需要買賣手續費,所以不會有人比券商的成本更低。

2000 ~ 2003 年年台股大動盪時,經常出現 200 點以上的基差,加上政府曾大力進場做多期貨,曾一度達到 250 點至 300 點,不過在券商紛紛進場套利下 (當時空間大到個人戶都可以套利),基差迅速縮小,股價還是往基本面靠攏。

時至今日,套利交易已經發展成全自動的一系列動作,需要的個股也只有 15 ~ 20 支,多數都直接寫好邏輯在主機中,當遇到時直接下單執行,平倉也是一樣,所以基差就只在今日這個範圍了。

2010-10-22

交易與交易所

在台灣交易有價證券,大部分都是通過交易所來進行的,包括所謂的 OTC (over-the-counter),也是透過財團法人櫃台買賣中心 (以下簡稱 OTC)

走出台灣,會發現很多東西是透過非交易所來交易的,好比外匯,24hr 不間斷交易,主要參與的銀行不斷的報買賣價,而交易人也不斷的透過銀行的交易平台來下單,不需要主要交易商,依靠著不斷的出價來形成市場,這算是目前最好的交易制度了。

在這樣的制度下,價格是有效率的,也是難以被單一機構影響的,假如價格會向真實價值靠攏的話,即時的價格就反應了市場已知的訊息與預期的資訊。

外匯市場是 over-the-counter,沒有主管機關,也不需要申報部位給主管機關。

不過美國政府現在準備把 swap 交易弄到交易所,而台灣幾年前也搞過把 IRS 弄到 OTC。當時的時空背景是這樣的,由於沒有長天期利率衍生性商品,所以當債券市場走空時,交易商沒有交易工具可以做,就把點子動到 IRS 上。當時正好櫃買中心成功的把債券交易從 over-the-counter 轉變成透過 OTC 的電子平台,短天期的債券選擇權也慢慢開始在 OTC 的電子平台交易,所以看起來只要平台做的比原來的更好,大家就會往更好的平台移動。

有很多交易是透過 over-the-counter 來完成的,如果可以標準化,做成有交易所的電子平台就不難,而且政府可以有效管理。不過有的政府官員會出爾反爾,關閉某個商品或平台,這樣會大大傷害政府的威信,即使這商品不是通過交易所來交易的,譬如 1997 年亞洲金融風暴,台灣央行永久關閉本地 NDF 市場,馬來西亞暫時關閉外匯市場。

綜合來看,會有交易是因為有市場有交易的需求,會有交易所是因為有一個獨立第三者做中介跟監管的需求,只要交易所的平台做的好,有信譽,交易商也會樂於轉到新的地方交易。

PS1
櫃買中心的 IRS 交易平台最後是失敗的,原因不明。個人以為是既得利益者搞的,因為在不透明的平台與資訊下,可以獲得的利益是驚人的,施壓讓這平台終止也不是啥難事。
PS2
台灣央行關閉 NDF 後,台灣本地就不能交易 NDF 了,不過境外還是繼續交易,甚至 reuters 跟 bloomberg 的頁面上還是各玩各的,不過因為參與者少很多,流動性變得更差了,所以很多在海外有分支機構的,就用海外名義繼續玩,連申報都不用;恭喜央行成功減少自己的責任又讓大股東得以跳脫小股東的監督,以後出國都會有人幫忙買單的。

2010-10-21

資訊揭露與散戶的理解能力

事情的始末是這樣的,亞洲果業於 2009 年 11 月 26 日於香港上市,但是在 2009 年 11 月 2 日向交易所提出一股分拆成十股的申請,所以我們知道所有的股東權益都會變成十分之一,而手中的股票則變成十倍,每股淨值由 37.3 元變成 3.73 元。

奇妙的事情就這麼發生了,上市那天,散戶瘋狂的以分拆前的價格買進,而 IPO 投資者則以中了樂透般的心情大量賣出,結果當然是股價往基本面靠攏,開盤時 51 元,一路跌到 20 元,然後 11 點 57 分交易所以震盪過大而暫停交易。隔日事情清楚後繼續交易,股價於 7.1 元收盤。

這個事件告訴我們一件事,散戶對於公開資訊的揭露是多麼的無知,事情從頭到尾都是透明的,連國外投資者都很清楚,因為這些都有公告,而且披露易上也有,只有散戶不清楚,這也間接說明一件事,專業投資人與業餘投資人的差距,一個連交易規則都不懂的人,想要在投資領域勝出是多麼困難的事。

這也可以歸納出另一個結論,由於散戶先天在專業知識上的劣勢,導致其交易傾向以賭為主,當面對公平市場時,勝率為 50%,當面臨巨大變化時,勝率便會小於 50%。可悲的是,很多投資機構的交易員也是這樣玩,不過因為公司有風險控管而不容易出事,這也是為啥風險控管越好的公司越賺錢,因為勝率較高。

2010-10-20

GAAP 與 IFRS

這個是健康會計的另一個重要轉捩點,美式的 GAAP 無法對即時損益符合實際風險暴露部位 (exposure),這是台灣的上市上櫃最大的問題,尤其是很多低毛利的公司喜歡賭外匯,但是因為都是用 option 跟 swap 的方式交易,所以會計師看不懂,而發函給交易對手,很可能交易對手為了自己的利益與掩蓋客戶的愚蠢,經常都不會回覆參考價。所幸這問題再 34 號跟 35 號會計公報實施後有了大幅度的改善,很多上市上櫃公司因為不能作假會計後,所以這些交易量呈現崩潰式的下滑。

IFRS 會計原則是比較接近風險控管的會計制度,雖然我對國內的會計師處理這類商品的能力依然大有疑問,但是我相信再調高簽證費後,應該會有錢去請懂的人,不然的話,就準備牢裡蹲吧。

PS1
香港中信泰富 2008 年發生過類似的事件,董事長的女兒交易外匯衍生性商品虧損 155 億港幣,約當六百多億台幣,這事件事實上是明顯有問題,不過因為事涉太子黨第二代,最後也不了了之,香港的司法對於太子黨也是會轉彎。
PS2
台灣博達案中,會計師才被停業兩年,虧損說要事務所負責,事實上是替所有的員工減薪一起賠,各位從事會計基層工作的人,如果覺得值得就繼續助紂為孽好了,反正台灣本來就司法不公。

調整基金投資組合沒有持有成本問題

基本上,基金需要每日計算淨值,也就是要用市價來評價,英文叫 mark-to-market。可是常常會看到很多經理人說,買進成本是多少等等來吹噓,事實上只是進一步暴露自己的無知。

由於即時計算淨值,所以應採用的是機會成本觀念,也就是這一億元的某 A 股票,是不是會比換成一億元的某B股票帶來更大的好處,所謂的好處除了較佳的獲利機會,也包括一樣的獲利機會下較小的風險,像是波動率等等。

其實這也是 VaR 的基礎,因為風險講究的是當下面對的不確定性,現在市值一億元的股票,並不會因為成本是八千萬或五千萬而有所不同。

PS
如果出個考券,這問題 95% 以上的基金經理人會答錯,更不用說實踐了。

2010-10-17

CUDA 與 OpenCL

一般來說,日常工作不會用到多核心跑到滿載,但是我近期卻遇到了,甚至 CPU 多次響起過熱的嗶嗶聲,差點沒被嚇死。其實只要做影片轉檔就會遇到,而且還不是 bluray 轉 1080P,不過是 DVD 轉 mp4 而已。

這件事讓我回想到財務工程的計算問題,幾年前我就想過是不是能把 GPU 拿來計算呢,因為它有多核心,但是自從改採用純 C 語言做計算後,從來就沒遇到過速度的問題,更別提 CPU 跑到快死掉。記得 Yield Book 是採用 64 核心的架構,我預期 2012 年就可以出現個人也可以組裝的狀況,直到發現 CUDA與OpenCL,個人以為現在就可以超越 Yield Book 的硬體架構了,哈哈。

OpenCL 的目標就是一套 API 可以使用全部 CPU+GPU+DSP 等等,CUDA 則是一種統一計算架構。

舉例來說,Nvidia GTX280 比 Intel Q9770 快 14 倍,有些比較甚至高達 31 倍。

這方面的書看來還很少,應該趕快弄些資料來研究研究。

PS
已經有一家廠商叫 SciComp 在賣這玩意了,可惜沒公司支持,不然就買一套來玩玩,以 CUDA 3.0 來說,GPU 可以比 CPU 快 117 倍;自己寫也是可以啦,不過沒有迫切需求,慢慢來就可以了。

2010-10-16

BBS Extension for Firefox

現在已經比較少人用了,除了台灣跟中國還很流行,老一輩的人應該都用過,至少也聽過,尤其是鼎鼎大名的 PTT

ubuntu 上當然有內建的 telnet 套件,打開終端機就可以使用,不過容易出現亂碼,尤其是上中文的 BBS。不過現在已經有純 JavaScript 的插件了,pcmanfx,其他平台可以到 PCMan BBS Project 看看。

2010-10-14

股票型基金如何拼績效

其實長期來說都不如指數型基金,每年 95% 以上都輸 ETF,連續三年都贏 ETF 則低於 0.1%,但這些基金經理人還是很拼命的做績效。

最常見的是,大基金養小基金,同一個投信公司,總要有一兩檔撐門面,所以小基金會去買冷門股,然後再由大基金把股價做高。要不然就是,大舉賣出競爭對手的重點持股,使自己的績效相對突出。

其他的部份就都是在媒體上亂放消息,跟記者亂講一通,使自己知名度上升,便於日後換工作,因為這行業一年要換超過一個的基金經理人。真正有潛力的新人大多都會在自營部或新金部,幫客戶交易的人通常只要能安撫客戶就好了,因為啥都不做也有管理費可以收,至於好賺的申購手續費,就交給舌燦蓮花的業務員就可以了。

債券型基金如何作假

除了分券以外,常用的還有資本利得對沖、掛帳、假定存等。

資本利得對沖,就是把帳面上的利率做低產生資本利得,衝高短期的收益率,但是長期的收益率會降低,所以就有了下面的招式。

掛帳,也是為了讓基金淨值不波動而產生,通常都借用券商或銀行的戶頭,進行買賣的動作,產生損益後灌回給基金,但是交易哪有只賺不賠的,所以一段時間便需要算一次帳,萬一虧損金額過大而無法認列時,就出現了下面這些情形。

假定存,以過低於的利率買進債券,但當利率大幅度上升時,就會產生巨幅的虧損,靠資本利得對沖是處理不了的,這時便會找一家銀行把這批債券賣給它,然後做成一個不可解約的超長期定存,天期通常是債券的到期日(數年到十數年不等),利率一定低於當初的買進成本,這樣就可以不認列市價的巨幅損失,而以超低的殖利率來做每日會計。

其實很容易發現,這些都是邪門歪道,而且會惡性循環,做假的規模一個比一個還要大,但是台灣99%的債券型基金都這麼做,而且每隔幾年這些基金團隊就會大風吹一次,因為大家底子都不乾淨,所以也從來沒出過事,為了向這麼大規模的集體犯罪致意,寫下這篇文章以做紀念。

PS
其實帳掛來掛去,換了人之後可能就不認帳了,所以股東就算知道也不敢動這些人,所謂不處罰壞人就是懲罰好人,這個市場就這樣亂搞下去,甚至單一團隊可以搞到上百人,自己做不好還可以中傷清流,跟主管機關私相授受,像是出書,舉行認證考試等等。

公平市價與債券分券制度

評價一個金融資產一優先次序有三種,市價、理論價、模型價,其實不是硬性的規定,不過會計有所謂的保守原則,應該要選擇獲利最小或損失最大的入帳,不過很多金融從業人員會鑽漏洞,加上會計師的金融專業程度與數學程度不佳,就有了台灣債券市場最奇妙的特色,分券。

所謂的分券制度當然是為了作假會計產生的,為什麼要作假會記呢?因為債券型基金需要把每日的淨值做到跟馬多夫一樣,每日淨值持續而且可預測性的向上,所以希望有這樣的東西。於是,當一個公司要發 30 億元公司債時,就會把它切割成 10 份,分別是甲券、乙券、丙券、丁券、戊券、己券、庚券、辛券、壬券、癸券,每種券的發行日相差一日,到期日也相差一日,這樣雖然是一模一樣的東西,卻可以有各自的公平市價,債券型基金就可以實現其馬多夫式的上漲了。

2010-10-08

MAME 模擬器

ubuntu 上也可玩模擬器,尤其是以前那些懷念的街機(arcade),只要安裝 SDLMAME 就好了。

安裝順序如下︰mame-common,mame,mame tools
安裝 GUI︰gmameui

接著還要有各製造商的 bios,譬如 Neo-Geo,然後去找遊戲的 roms,譬如 ROMNation

接著從終端機輸入
gmameui

這裡要作一下設定,第一次進入要選擇 MAME 執行檔的位置,/usr/games/mame,也要選一個 ROMs 的位置。接著做一些設定,選 Options → Default Options → Display → Video → Video mode → OpenGL,不選 Options → Default Options → OpenGL → Filter,選 Options → Default Options → Performance → Automatic framskip,就完成了。

最後,File → Audit All Games,就知道下載的 roms 有哪些是可以玩的,完成。

PS
Neo-Geo 的 bios 網路上有點難找,不是不能用就是連結斷了,所以我附上一個可以用的。

ubuntu 上看 1080P 影片

現在的顯示晶片越來越娛樂導向,假如只是要看 1080P 影片的話,根本不需要花大錢買獨立顯示卡,內建晶片組就綽綽有餘,Acer L3600 內建 Intel G31 顯示晶片加上 Intel E6750,Acer Revo R3610 內建 Nvidia ION 晶片,就是其中的代表,即便在 Linux 作業系統都可以很順暢的播放 1080P 影片。

在設定 Intel G31 方面,其實是比較簡單的,只要加入 Cutting edge multimedia 這個 repository 後,就可以安裝較新版的 VLC 以及 decode libraries,所以 VLC 跟 Gnome 內建的 Totem Movie Player 都可以順暢的播放 1080P 影片。

設定 Nvidia ION 方面也一樣,先加入 Cutting edge multimedia,然後安裝新版的 VLC 跟 vdpau-video,也可以安裝 smplayer (GUI for mplayer) 跟 mplayer-git (目前只有這個版本才能用 vdpau)。裝好 VLC 後還要進行設定才能使用 ION 來做硬體解壓縮,選 Tools → Preferences → Input&Codecs → Codecs → Use GPU acceleration (experimental)。smplayer 也一樣要設定才能啟用 ION 做硬體解壓縮,選 Options → Preferences → General → Video → Output driver → vdpau。比較可惜的是,Totem Movie Player 不能選硬體解壓縮,所以只能用 VLC 跟 smplayer 來播放 1080P 影片。

PS
要正確顯示中文字幕,這些 player 都需要設定預設字幕編碼,以 VLC 為例,可以選Tools → Preference → Subtitles & OSD → Display Settings → Font → WenQuanYi Micro Hei 當預設字體。

2010-10-07

好用的轉檔工具 - handbrake

官網

首先要安裝 ffmpeg,為了穩定因素,所以要自行編譯。
./configure
make
make check
sudo make install
影音格式實在太複雜,而 ffmpeg 的說明檔又太大太多,所以還是先用有 GUI 的程式,等以後熟了再用指令。HandBrake 看來是目前的最佳選擇之一,開源加上多平台支援。

HandBrake 還有一個方便的功能,就是把 DVD 直接轉為 MP4 或 MKV,畢竟小檔案比較容易保存,DVD 畫質以才 480i,一片 4.7GB 實在太佔空間了。

2010-10-05

替 py3k 安裝 lxml

wget http://python-distribute.org/distribute_setup.py
sudo python3 distribute_setup.py
sudo apt-get install libxml2-dev
sudo apt-get install libxslt1-dev
sudo apt-get install python3-dev
sudo easy_install lxml

2012.06.02 更新︰現在可以直接從 repository 更新了。
apt-get install python3-lxml

2010-10-02

字幕編輯軟體 - aegisub

除了 gaupol 外,另一個強大好用的字幕編輯軟體 aegisub,提供多樣化的字幕設計。

其實我覺得還是 srt 檔最好,想要變化花樣的人可以自己再加工,但是很多大陸字幕小組喜歡做完特效才釋出,我是覺得越做越醜,但是還是只能接受,只好抓回來再回復原狀。

另一個有趣的地方是,這些小組的簡體字幕編碼也都很混亂,看來應該要有人去宣導 UTF8 才對。

輸出成 srt 檔很簡單,就是 .ass 另存新檔時把副檔名指定為 .srt 就好了。

2010-09-30

tucan 免費空間下載軟體

網路上有許多好心人喜歡把較小的影音檔放在免費空間上,而這些免費空間常常都有每日總量限制,或者是等待時間等不方便的地方,當然如果只要下載一兩個檔案,直接用手按就好,但如果要下載數十個檔案,我們就會想要一個下載管理員,當今日的額度用完後,可以在 24 小時候自動繼續下載,或是自動等待 45 秒後下載。

tucan就是這樣一個好用的軟體,可以直接在 ubuntu 的 repository 找到,支援以下空間︰rapidshare, megaupload, gigasize, mediafire, 4shared, sendspace, zshare, filefactory, easy-share, badongo, depositfiles, hotfile, uploading,差不多主流的都有了,如果有付費的帳號密碼,也可以支援,算是除了 Transmission 跟 aMule 外一定要裝的。

這軟體是用 python 跟 gtk+ 寫的,只有 330KB,可以下載來研究看看。

2010-09-29

day count convention

計算債券價格或固定收益的東西,最麻煩的就是 day count convention,如果是用 gnumeric,那就直接設定參數就好了,但如果想要自己寫一個快一點小巧一點的程式,就得慢慢找資料寫程式了。維基的說明還不錯。瑞士交易所ISDA 也有簡單說明文件,可以參考看看。

程式碼
#include <stdio.h>
#include <time.h>        /* mktime tm */

/* List all decleration in the beginning because ISO C forbids mixed declarations and code. */
struct tm totm(char date[8]);
struct tm calctm(struct tm date, int n);
unsigned int leapyear(int year);
unsigned int comptm(struct tm t1, struct tm t2);
int days(char date1[8], char date2[8], int basis);
double yearfrac(char date1[8], char date2[8], unsigned int freq, int basis);

int main() {
    char s1[8] = "20120302";
    struct tm t1, t2;
    t1 = totm(s1);
    t2 = calctm(t1, -5);
    printf("%s%.8f\n", asctime(&t2), yearfrac("20070815","20070823", 2, 9));

    return 0;
}

/* 不採用 strptime,因為 libc 的 time.h 有一些問題,要另外宣告函數原型才能使用。 */
struct tm totm(char date[8]) {
    struct tm t;
    t.tm_year = (date[0] - 48) * 1000 + (date[1] - 48) * 100 + (date[2] - 48) * 10 + (date[3] - 48) - 1900;
    t.tm_mon = (date[4] - 48) * 10 + (date[5] - 48) - 1;
    t.tm_mday = (date[6] - 48) * 10 + (date[7] - 48);
    t.tm_hour = 0;
    t.tm_min = 0;
    t.tm_sec = 0;
    t.tm_isdst = 0;
    mktime(&t);

    return t;
}

struct tm calctm(struct tm date, int n) {
    struct tm temp = date;
    temp.tm_mday += n;
    mktime(&temp);

    return temp;
}

/* C89 doesn't have bool. C99 has stdbool.h to use bool. */
unsigned int leapyear(int year) {
    if ( year % 4 == 0 ) {
        if ( year % 100 == 0 ) {
            if ( year % 400 == 0) {
                return 1;
            } else {
                return 0;
            }
        } else {
            return 1;
        }
    } else {
        return 0;
    }
}

unsigned int comptm(struct tm t1, struct tm t2) {
    if ( t1.tm_year == t2.tm_year && t1.tm_mon == t2.tm_mon && t1.tm_mday == t2.tm_mday ) {
        return 1;
    } else {
        return 0;
    }
}

int days(char date1[8], char date2[8], int basis) {
    int Y1, Y2, M1, M2, D1, D2;
    struct tm t[2];
    t[0] = totm(date1);
    t[1] = totm(date2);
    Y1 = t[0].tm_year;
    Y2 = t[1].tm_year;
    M1 = t[0].tm_mon;
    M2 = t[1].tm_mon;
    D1 = t[0].tm_mday;
    D2 = t[1].tm_mday;
    /* N = (D2 - D1) + 30 * (M2 - M1) + 360 * (Y2 - Y1) */
    switch ( basis ) {
        case 0:
            /*
            30U/360
            http://www.eclipsesoftware.biz/DayCountConventions.html#x3_01a
            date is changed in one rule the changed value is used in the following rules:
            If the investment is EOM and (Date1 is the last day of February) and (Date2 is the last day of February), then change D2 to 30.
            If the investment is EOM and (Date1 is the last day of February), then change D1 to 30.
            If D2 is 31 and D1 is 30 or 31, then change D2 to 30.
            If D1 is 31, then change D1 to 30.
            */
            if ( calctm(t[0], 1).tm_mon == 2 && calctm(t[1], 1).tm_mon == 2 ) {
                D2 = 30;
            } else if ( calctm(t[0], 1).tm_mon == 2 ) {
                D1 = 30;
            } else if ( D2 == 31 && ( D1 == 30 || D1 == 31 ) ) {
                D2 = 30;
            } else if ( D1 == 31 ) {
                D1 = 30;
            }
            break;
        case 1:
            /*
            30U/360
            http://www.eclipsesoftware.biz/DayCountConventions.html#x3_01b
            If D2 is 31 and D1 is 30 or 31, then change D2 to 30.
            If D1 is 31, then change D1 to 30.
            */
            if ( D2 == 31 && ( D1 == 30 || D1 == 31 ) ) {
                D2 = 30;
            } else if ( D1 == 31 ) {
                D1 = 30;
            }
            break;
        case 2:
            /*
            30E/360
            http://www.eclipsesoftware.biz/DayCountConventions.html#x3_02
            If D1 = 31, then change D1 to 30.
            If D2 = 31, then change D2 to 30.
            */
            if ( D1 == 31 ) {
                D1 = 30;
            }
            if ( D2 == 31 ) {
                D2 = 30;
            }
            break;
        case 3:
            /*
            30E/360 ISDA
            http://www.eclipsesoftware.biz/DayCountConventions.html#x3_03
            If D1 = last day of the month, then change D1 to 30.
            If D2 = last day of the month, then change D2 to 30.
            */
            if ( calctm(t[0], 1).tm_mon != M1 ) {
                D1 = 30;
            }
            if ( calctm(t[1], 1).tm_mon != M2 ) {
                D2 = 30;
            }
            break;
        case 4:
            /*
            30E+/360 ISDA
            http://www.eclipsesoftware.biz/DayCountConventions.html#x3_04
            If D1 = 31, then change D1 to 30.
            If D2 = 31, then change M2 to the next month and change D2 to 1.
            */
            if ( D1 == 31 ) {
                D1 = 30;
            }
            if ( D2 == 31 ) {
                t[1] = calctm(t[1], 1);
                Y2 = t[1].tm_year;
                M2 = t[1].tm_mon;
                D2 = t[1].tm_mday;
            }
            break;
    }

    return (D2 - D1) + 30 * (M2 - M1) + 360 * (Y2 - Y1);
}

double yearfrac(char date1[8], char date2[8], unsigned int freq, int basis) {
    int Y1, Y2, M1, M2, D1, D2, period = 0, Nnl = 0, Nly = 0, N = 0, L = 365;
    double result;
    struct tm t[3];
    t[0] = totm(date1);
    t[1] = totm(date2);
    Y1 = t[0].tm_year;
    Y2 = t[1].tm_year;
    M1 = t[0].tm_mon;
    M2 = t[1].tm_mon;
    D1 = t[0].tm_mday;
    D2 = t[1].tm_mday;

    switch ( basis ) {
        case 0:
            result = days(date1, date2, basis) / 360.0;
            break;
        case 1:
            result = days(date1, date2, basis) / 360.0;
            break;
        case 2:
            result = days(date1, date2, basis) / 360.0;
            break;
        case 3:
            result = days(date1, date2, basis) / 360.0;
            break;
        case 4:
            result = days(date1, date2, basis) / 360.0;
            break;
        case 5:
            /*
            Act/Act (ISDA)
            http://www.eclipsesoftware.biz/DayCountConventions.html#A_01
            This convention splits the accrual period into that portion in a leap year and that in a non-leap year.
            You include the first date in the period and exclude the ending one.
            Fact = Nnl in non-leap year / 365 + Nly in leap year / 366
            */
            while ( comptm(t[0], t[1]) != 1 ) {
                if ( leapyear(t[0].tm_year + 1900) ) {
                    Nly++;
                } else {
                    Nnl++;
                }
                t[0] = calctm(t[0], 1);
            }
            result = Nnl / 365.0 + Nly / 366.0;
            break;
        case 6:
            /*
            Act/Act (ICMA)
            http://www.eclipsesoftware.biz/DayCountConventions.html#A_02
            This is the method used for US Treasury Notes and Bonds. The US Treasury expresses the calculation as:
                AI = CR * ( {N / JulianDays(Date1, Date3) } / Fr).
            This captures the ideas that all days in any given period (but not necessarily in different periods)
            accrue the same amount and that all coupon payments are equal.
            Date1 is the previous coupon date before the current settlement Date2.
            Date3 is the next coupon date after the current settlement Date2.
            */
            t[2] = t[0];
            t[2].tm_mon += 12 / (int) freq;
            mktime(&t[2]);
            while ( comptm(t[0], t[1]) != 1 ) {
                N++;
                t[0] = calctm(t[0], 1);
            }
            period = N;
            while ( comptm(t[1], t[2]) != 1 ) {
                period++;
                t[1] = calctm(t[1], 1);
            }
            result = (double) N / ((int) freq * period);
            break;
        case 7:
            /*
            Act/365 (Fixed)
            http://www.eclipsesoftware.biz/DayCountConventions.html#A_03
            */
            while ( comptm(t[0], t[1]) != 1 ) {
                N++;
                t[0] = calctm(t[0], 1);
            }
            result = N / 365.0;
            break;
        case 8:
            /*
            Act/360
            http://www.eclipsesoftware.biz/DayCountConventions.html#A_04
            */
            while ( comptm(t[0], t[1]) != 1 ) {
                N++;
                t[0] = calctm(t[0], 1);
            }
            result = N / 360.0;
            break;
        case 9:
            /*
            Act/365L
            http://www.eclipsesoftware.biz/DayCountConventions.html#A_05
            Den:
                If Fr = 1 (annual coupons)
                    If February 29 is in the range Date1 (exclusive) to Date3 (inclusive), then use 366.
                    Else use 365.
                Else
                    If Date3 is in a leap year, then use 366.
                    Else use 365.
            */
            t[2] = t[0];
            t[2].tm_mon += 12 / (int) freq;
            mktime(&t[2]);
            if ( freq == 1 ) {
                if ( t[0].tm_mon == 1 && t[0].tm_mday == 29 ) {
                    N++;
                    t[0] = calctm(t[0], 1);
                }
                while ( comptm(t[0], t[1]) != 1 ) {
                    N++;
                    if ( t[0].tm_mon == 1 && t[0].tm_mday == 29 ) {
                        L = 366.0;
                    }
                    t[0] = calctm(t[0], 1);
                }
                while ( comptm(t[0], t[2]) != 1 ) {
                    if ( t[0].tm_mon == 1 && t[0].tm_mday == 29 ) {
                        L = 366.0;
                    }
                }
            } else {
                if ( leapyear(t[2].tm_year + 1900) ) {
                    L = 366.0;
                }
                while ( comptm(t[0], t[1]) != 1 ) {
                    N++;
                    t[0] = calctm(t[0], 1);
                }
            }
            result = (double) N / L;
            break;
    }

    return result;
}
編譯
gcc day_count_convention.c -Wall -Wextra -pedantic -Wconversion -Wundef -Wshadow -o day_count_convention
執行
./day_count_convention
輸出 yearfrac 的結果,計算方式為 Act/365L
0.02185792

遠端控制動物機 (client 端)

基本上用 ubuntu 內建的 terminal server client 就可以了,但是裡面少了一個 VNC 模組,所以只要裝上就好了。
sudo apt-get install xtightvncviewer
transmission 可以直接用瀏覽器遠端操作大部功能,只要在裡面設定好要用哪個 port 就好了。

aMule 的部份稍微麻煩一點,一樣要設定 port,但是要用 aMule 專用的介面才能操作,名稱就叫 aMuleGUI;麻煩一點,但是可以操作的功能也比較多一點。
sudo apt-get install amule-utils-gui

2010-09-26

curl - C 語言的 url 工具

python 固然好用,但是有時也要用 C 寫一些東西,發現了 curl 這樣的 C library,可以抓網路上的檔案。

範例檔

要編譯需要安裝 libcurl3-dev (使用openssl) 或 libcurl4-dev (使用GnuTLS)
sudo apt-get install libcurl3-dev
編譯
gcc curl01.c -o curl01 -lcurl
執行
./curl01

2010-09-24

Glade - GTK+ GUI 介面編輯程式

GTK+ 雖然好用,但是要一行一行寫還是太麻煩,Glade 是一個建立 GUI 的好用程式,這樣就可以把心力集中在 libraries 開發就好,耶!

Totem 問題修正

Totem 是 ubuntu 預設的 player,可以網路播放 YouTube 跟 BBC podcast,也可以播放大部份的影音,但是有部份小問題。第一個是 mkv,由於找不到 H.264 Decoder,所以用 gstreamer0.10-ffmpeg;第二個是 BBC podcast 的清單不完整,裝上 libtotem-plparser-dev;其他的應該都是遇到有缺的,會自動尋找跟安裝。

2010-09-16

連結國外股票的權証

台灣真是一個奇妙的地方,明明沒有 GFW 卻好像資訊被封閉一樣,金融機構推出的金融產品就是一例,今天解釋一下,我如果要買這個權證,我會作啥研究。

首先是標的物,這次的都是在香港掛牌的,譬如 A50、富士康跟匯豐銀行。HKExnews披露易,相當於台灣的股市觀測站,但是有正體、簡體跟英文,一般說來,香港的英文翻譯都是比較正確跟通用的,有翻譯需求的可以參考。這裡可以找到財務報表跟公告,還有一些重大資訊。

再來可以去港交所看一下,投資服務中心→公司/證券資料,可以找到一些基本資料,包括每手多少股,譬如匯豐銀行是每手 400 股,如果有對沖交易的人應該需要。

然後就是股價表現了,yahoo finance 是一個選擇,不過我偏好 google finance,比較簡潔,資料也可較正確。跟台灣不同的是,香港的即時股價資訊是要錢的,所以免費的都會延遲 20 分鐘。

最後才是計算 warrant 定價何不合理。香港是全世界權証最發達的地方之一,所以可以找到完整的 term structure 來做定價參考,大型的權証發行機構也都有網站可以用。這裡介紹港交所的,產品及服務→證券產品→結構性產品→衍生權證→衍生權証搜尋,這裡可以找到相關標的所發行的權證,這有一個很重要的街貨比,就是市場上流通/總發行量,可以參考看看。

附註
看來台灣真是一個好混撈錢的地方,不但官方網站做的差,連業者的網站也很差,而且資訊揭露不用遵守啥規定,財報也不需要出英文版,之前有科技公司董事長內線交易,還用投資人的錢請律師,實在是坑殺散戶的寶地啊。

Acer L3600 上用耳麥

直觀上想應該是 plug&play,事實上不是。因為很多耳麥都是 USB 介面的,需要驅動程式,而這方面 ubuntu 還不夠完整,耳麥的硬體晶片可能也是一大問題,最近試了一個就只能在 MS 上用,後來發現如果用 3.5mm 的方式就可以解決了。

我先買一個 apple iphone 的耳麥,ebay 上只要 USD$2.99 (含運),再買一個轉接頭,USD$4.99,把他轉為耳機跟麥克風接頭,這樣就可以了。

其實這最大的好處就是,在美國可以用 google voice 打免錢的北美電話,哈哈。

2010-09-15

自製 XBRL 資料庫

台灣 XBRL 下載區

根據台灣官方機構的說法,2010 年 9 月 30 日前,需要將半年報的 XBRL 檔案交出來,以後也變成強制性的。這真是一項大福音,因為股市觀測站的資料實在錯誤不少,訪間的資料庫公司資料品質更差,而且官方的示範網站實在是做的不怎樣,既不快也不穩,選項也太少,所以自己做才是最好的。

在工具的選擇方面,一樣採用開源的,所以用 python3sqlite3

先檢查有問題的 XBRL 檔,其實只有 tw-gaap-ci-2371-2010Q1-cr.xml 要修正
xbrl-filter
#檢查有問題的 xml 檔
import glob
from lxml import etree

files = glob.glob('*.xml')

for i in files:
    print(i)
    xbrl = etree.parse(i)
    root = xbrl.getroot()
    ns = "{" + root.nsmap['-'.join(i.split('-')[0:3])] + "}*"
    print(ns)
再來就是轉檔
xbrl-convert
#轉檔
import glob
from lxml import etree
import sqlite3

files = tuple(sorted(glob.glob('*.xml')))
conn = sqlite3.connect('xbrldata.sqlite')
cur = conn.cursor()
#t for ticker, s for subject, d for date, v for value, g for gaap classification, q for quarterly financial statements
cur.execute("create table 'tw' (t integer, s text, d text, v integer, g text, q text, unique (t, s, d, v, g, q))")

for i in files:
    data = []
    if i[:5] == 'tifrs':
        quarter = i.split('-')[-1][:6]
        gaap = 'IFRS' + '-' + i.split('-')[3]
        ticker = i.split('-')[-2]
        if i.split('-')[-3] == 'cr':
            cr = '-cr'
        else:
            cr = ''
        xbrl = etree.parse(i)
        root = xbrl.getroot()
        ns = root.nsmap
        for n in ns:
            if n not in ['tifrs-notes', None, 'link', 'xbrli', 'xbrldt', 'xbrldi', 'iso4217']:
                for j in root.iterchildren(tag = "{" + ns[n] + "}*"):
                    data.append([ticker, j.tag.partition('}')[2]+cr, j.attrib['contextRef'], j.text.strip(), gaap, quarter])
    else:
        quarter = i.split('-')[4][:6]
        gaap = 'GAAP' + '-' + i.split('-')[2]
        ticker = i.split('-')[3]
        if len(i.split('-')) == 6:
            cr = '-cr'
        else:
            cr = ''
        xbrl = etree.parse(i)
        root = xbrl.getroot()
        ns = root.nsmap
        for n in ns:
            if n in ['-'.join(i.split('-')[0:3]), 'tw-gaap-ar']:
                for j in root.iterchildren(tag = "{" + ns[n] + "}*"):
                    if "OtherSupplementalInformation" in j.tag:
                        data.append([ticker, "OtherSupplementalInformation"+cr+"_"+j.find("{"+ns[n]+"}"+"ChineseAccount").text.strip()+"_"+j.find("{"+ns[n]+"}"+"EnglishAccount").text.strip(), j[0].attrib['contextRef'], j.find("{"+ns[n]+"}"+"Amount").text, gaap, quarter])
                    else:
                        if j.text != None:
                            data.append([ticker, j.tag.partition('}')[2]+cr, j.attrib['contextRef'], j.text.strip(), gaap, quarter])
    cur.executemany("insert or ignore into 'tw' (t, s, d, v, g, q) values (?, ?, ?, ?, ?, ?)", data)

conn.commit()
cur.close()
最後,證交所自己也是公開發行公司卻不出 XBRL,實在是雙重標準。

IFRS 後的年報與季報公告時間分別為 3/31、5/15、8/14、11/14。

2018.05.27 更新︰附上全部的 XBRL 檔,到 2018-Q1。

2010-09-14

好用的壓縮軟體 7-Zip

官網

壓縮率比 zip 高出 30% ~ 50%,而且是 open source。
壓縮支援︰7z, ZIP, GZIP, BZIP2, TAR
解壓縮檔支援︰ARJ, CAB, CHM, CPIO, DEB, DMG, HFS, ISO, LZH, LZMA, MSI, NSIS, RAR, RPM, UDF, WIM, XAR, Z

解壓縮到 temp
find -name "*.zip" -exec 7z e {} -otemp \;
以最高壓縮率壓縮成 7z
7z a -t7z -mx=9 xbrl.7z *.xml
壓縮成 zip
7z a -tzip xbrl.zip *.xml

2010-09-08

批次檔案處理 - 轉檔與刪除

將 BIG5 轉為 UTF8。
find -name "*.c" -exec iconv -f big5 -t utf8 {} -o {} \;
將目前目錄與子目錄下 .exe 的檔案全部移除。
find . -name "*.exe" -exec rm {} \;
find 也可以指定目錄,刪除 ~/Downloads/target/ 下所有 .exe 檔。
find ~/Downloads/target/* -name "*.exe" -exec rm {} \;
在目前的目錄,刪除大小在 2 bytes 到 5 bytes 的 txt。
find . -name "*.txt" -size +2c -a -size -5c -exec rm {} \;
也可以把 find 的 -exec 串接起來,譬如先 ls 再 rm。
find . -name "*.txt" -exec ls {} \; -exec rm {} \;

2010-08-28

字幕檔編輯 - gaupol

基本上除了 gedit 外,加上 gaupol 應該就夠了,可以編輯或平移 frame / sec,支援各種編碼轉換,也支援各種字幕檔格式轉換,很多動畫裡的字幕都是 ass,可以用這個軟體轉成 srt。這軟體在 ubuntu 的 repository 裡有,非常方便。

mkv 封裝與拆解

推薦用 MKVtoolnix,ubuntu 的 repository 就有,合併有 GUI (mkvmerge gui),但是拆解沒有,所以要用指令。

以 root 權限安裝。
apt-get install mkvtoolnix-gui
查詢結構。
mkvmerge -i source.mkv
去除 tags 與字幕並取出 video 與 audio 存成新檔,移除 Movie name,設定 track 0 為 und 語系,設定 track 1 為 eng 語系,設定 track order 為 video 與 audio。
mkvmerge -o new.mkv --no-subtitles --video-tracks 0 --audio-tracks 1 --no-track-tags --no-global-tags --language 0:und  --track-name 0: --default-track 0:yes --language 1:eng --track-name 1: --default-track 1:yes --title "" --track-order 0:0,0:1 source.mkv
拆解字幕(ID:3)。
mkvextract tracks source.mkv 3:target.srt

2010-08-26

Code::Blocks 安裝

Prerequirement︰build-essential, gdb, libwxgtk2.8-0, libwxgtk2.8-dev
libwxgtk需要用 apt.wxwidgets.org 的,因為 Lucid 的太舊。

直接從官網下載,切入目錄後全部安裝
sudo dpkg -i *.deb

這個是我近期用過最好的 IDE for C,Dev-C++ 已經很久很久沒更新了,而 Code::Blocks 最近越來越熱門,插件應該會越來越多,雖然我也不大用插件。另外,它也是多平台支援。

2010-08-22

BusyBox 與 GPL 授權再次贏得侵權訴訟

新聞

引文︰
對於這樣一個可能被廠商認知為不具重要性的議題,這種情況並不少見。這時候只有採取公開訴訟才能獲得回應。而截至目前為止,軟體自由法律中心在公開強制遵守 GPL 授權條款的執行上,有百分之百的成功紀錄。
大快人心,讓這些公司知道 GPL 不是紙老虎。

可笑的股息殖利率

最受不了的就是一大堆媒體發明一些奇怪的觀念,套句我朋友的話,不說話頂多讓我以為你是白痴,一說話讓我確定你是白痴。

首先,企業的獲利並不是穩定的,所以假設股利會穩定發放本來就是錯的,就連特別股都不一定可以穩定發放股利了。第二,股票的波動率跟債券的波動率也有一段落差,除了少數大型股的波動率在 15% 以下,大部分都在 30% 以上,而波動率較激烈的美國30年期公債也不過才 12% ~ 15%,所以這種比較是需要仔細計算的。第三,最爆笑的是,台灣證券交易所的網站上有股息值利率這一項,請問有人用今天的收盤價跟去年的股利來算的嗎?

以上可知,在台灣要做交易,需要創造話題,因為台灣人只重視短線跟議題熱度,跟大家講道理講理論只會被當外星人。

媒體跟散戶最愛的除權

基本上,沒有員工配股的除權就是股票分割,有員工配股的除權就是股東權益的減損,比分割更遭。

我認為這跟賭博的原理類似,公平的賭局應該是 50 / 50,譬如猜硬幣的正反面;如果連續出現10 次正面後,相信大部分的人都會認為下一次出現反面的機率比較大,事實上機率仍是 50%,就算出現 100 次正面也是一樣。除權後,公司的淨值、獲利等比例下降,除權後價格也因總市值不應改變而有同步調整,所以一切都沒改變。但是這樣就不好玩了,所以發明了填權這樣有趣的花招,我曾經看過一篇論文講的是除權前後的超額報酬,可惜的是,沒報法從全部的股票中選出有除權行情的股票,如果可以的話,那就可以做一個交易策略是專門做除權填權行情的。既然發生的機率與標的是不確定的,那為啥每年都可以這樣玩散戶混稿費?那就跟報導中樂透是一樣的道理,雖然樂透是負和賽局,每買一張 50 元的彩券就等於捐 15 ~ 20 元,但對賭徒來說,勝率不是可以用數學來計算的,所以只要努力報導特殊現象,還是可以引起話題。我知道的基金經理人也都是這類的人,都是在賭短線交易,但是會胡扯一大堆理由,所以這種人永遠只能靠騙人混飯吃,自己的錢是不大敢這樣玩的,所以基金每年換人也是合理的,事實上,不換人也是合理的,因為都差不多。如果把錢交到這些人手上,呵呵,自己想吧,不幸的是,全世界的基金都這樣。

2010-08-19

Pywin32 DDE

最近在找即時股價的資訊源,發現 Pywin32 這個偉大的 python module,可以抓本機 DDE server 中的資料,不過在 python3k 有點問題,希望下次改版能修正。

python 2.6.5 版抓康和全都賺
>>> import win32ui  #這個要先載入
>>> import dde  #目前版本是214
>>> s = dde.CreateServer()
>>> s.Create('MMSDDE')  #康和全都賺
>>> c1 = dde.CreateConversation(s)
>>> c1.ConnectTo('MMSDDE', 'FUSA')
>>> c1.Connected()  #測試是否連線成功
1
>>> c1.Request('WTX&.125')  #傳回大台指目前成交價;python3k 在這步會出錯。
'7886.00'
>>> c2 = dde.CreateConversation(s)
>>> c2.ConnectTo('MMSDDE', 'TWSE')  #因為一次只能連一個
>>> c2.Request('2330.125')  #如果沒有在報價視窗報過價,會傳回'-'
'59.90'

2010-08-17

用 Py3k 抓 Yahoo Finance 的資料

程式碼
#!/usr/bin/env python
#
#  Copyright (c) 2007-2008, Corey Goldberg (corey@goldb.org)
#
#  license: GNU LGPL
#
#  This library is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2.1 of the License, or (at your option) any later version.

#  Modified by Angelo
#  only compititable with Python 3


import urllib.request, urllib.parse, urllib.error


"""
This is the "yfq" module.

This module provides a Python API for retrieving stock data from Yahoo Finance.

sample usage:
>>> import yfq
>>> yfq.get_price('GOOG+APPL')
{'GOOG': '486.35', 'AAPL': '249.10'}
"""


def __request(symbol, stat):
    url = 'http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s' % (symbol, stat)
    return urllib.request.urlopen(url).read().decode().strip().strip('"')


def get_all(symbol):
    """
    Get all available quote data for the given ticker symbol.
    
    Returns a dictionary.
    """
    url = 'http://finance.yahoo.com/d/quotes.csv?s=%s&f=l1c1va2xj1b4j4dyekjm3m4rr5p5p6s7' % symbol
    temp = urllib.request.urlopen(url).readlines()
    keys = ['price', 'change', 'volume', 'avg_daily_volume', 'stock_exchange', \
        'market_cap', 'book_value', 'ebitda', 'dividend_per_share', \
        'dividend_yield', 'earning_per_share', '52_week_high', '52_week_low', \
        '50day_moving_avg', '200day_moving_avg', 'price_earnings_ratio', \
        'price_earnings_growth_ratio', 'price_sales_ratio', 'price_book_ratio', 'short_ratio']
    tkrs = symbol.split('+')
    data = {}
    for c in range(len(tkrs)):
        data[tkrs[c]] = dict(zip(keys, temp[c].decode().split(',')))
    return data


def get_price(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'l1').split('\r\n')))


def get_change(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'c1').split('\r\n')))


def get_volume(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'v').split('\r\n')))


def get_avg_daily_volume(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'a2').split('\r\n')))


def get_stock_exchange(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'x').split('\r\n')))


def get_market_cap(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'j1').split('\r\n')))


def get_book_value(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'b4').split('\r\n')))


def get_ebitda(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'j4').split('\r\n')))


def get_dividend_per_share(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'd').splir('\r\n')))


def get_dividend_yield(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'y').split('\r\n')))


def get_earnings_per_share(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'e').split('\r\n')))


def get_52_week_high(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'k').split('\r\n')))


def get_52_week_low(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'j').split('\r\n')))


def get_50day_moving_avg(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'm3').split('\r\n')))


def get_200day_moving_avg(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'm4').split('\r\n')))


def get_price_earnings_ratio(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'r').split('\r\n')))


def get_price_earnings_growth_ratio(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'r5').split('\r\n')))


def get_price_sales_ratio(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'p5').split('\r\n')))


def get_price_book_ratio(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 'p6').split('\r\n')))


def get_short_ratio(symbol):
    return dict(zip(symbol.split('+'), __request(symbol, 's7').split('\r\n')))


def get_historical_prices(symbol, start_date, end_date):
    """
    Get historical prices for the given ticker symbol.
    Date format is 'YYYYMMDD'

    Returns a nested list.
    """
    url = 'http://ichart.yahoo.com/table.csv?s=%s&' % symbol + \
        'd=%s&' % str(int(end_date[4:6]) - 1) + \
        'e=%s&' % str(int(end_date[6:8])) + \
        'f=%s&' % str(int(end_date[0:4])) + \
        'g=d&' + \
        'a=%s&' % str(int(start_date[4:6]) - 1) + \
        'b=%s&' % str(int(start_date[6:8])) + \
        'c=%s&' % str(int(start_date[0:4])) + \
        'ignore=.csv'
    days = urllib.request.urlopen(url).readlines()
    data = []
    for day in days:
        data.append(day[:-1].decode().split(','))
    return data

原版只能用在 2.X 版,我修改成可以用在 Python3K,但是不向前相容(廢話)。只有抓價格的部份,其他資料都問題蠻多的,全部的 tags 之前就寫過了。

抓目前股價
>>> import yfq
>>> yfq.get_price('GOOG+APPL')
{'GOOG': '486.35', 'AAPL': '249.10'}
抓歷史股價
>>> yfq.get_historical_prices('AMZN','20090629','20090630')
[['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Clos'], ['2009-06-30', '83.62', '84.92', '82.47', '83.66', '7984800', '83.6'], ['2009-06-29', '83.87', '84.20', '82.41', '83.03', '6270300', '83.0']]

Reference: Python - Yahoo Stock Quotes - Historical Pricing

Py3k and C library - 使用 ctypes

真的如官網說的,支援的 modules 比較少,如果不想花時間解決這些問題或修改,應該就用 2.X 吧。最近我就遇上這些問題,一大堆 modules 都不支援 python3k,雖然有些號稱未來會支援,但我不想等。

其實 python3k 的 ctypes 寫的很好,可以把 C library 整合進 python3k,加上 python 的即時編譯功能,看來以後可以先在 python 作實驗再去寫成 C。

解決方法如下︰引用 GSL
>>> from ctypes import *
>>> gslcblas = CDLL('libgslcblas.so.0',mode=RTLD_GLOBAL)    #引用libgslcblas動態檔第0版
>>> gsl = CDLL('libgsl.so.0')    #引用libgsl動態檔第0版
>>> func1 = gsl.gsl_cdf_gaussian_P    #設定引用>>> gsl_cdf_gaussian_P
>>> func1.restype = c_double    #引用的函數預設都是傳回c_int
>>> func1(c_double(0.2), c_double(1))
0.579259709439103

另外,也支援 pointer 與 C 變數定義,看來大有可為。

2010-08-15

在網頁顯示數學式子 - MathJax - 適用全部瀏覽器

最新版是 1.0,還好我之前都是用 LaTex 寫的,更改幅度不大,希望這是 webkit 正式支援前最後一次換 library。
PS
很可惜,Chrome 後來還是有問題,暫時先用 FireFox 看,MathJax 也沒釋出新版,懶得改了。

Yahoo Finance download 說明

yahoo finance 提供全球股市資訊,十年指標公債歷史利率,今日交叉匯率,可以直接對 server 送出指令要求回傳,所以對於想要作資料分析可說是很方便。不過由於 tags 繁多,所以我整理好作為參考。

傳回 2330.tw 跟 0005.hk 的名稱與股價 (last trade)
http://finance.yahoo.com/d/quotes.csv?s=2330.tw+0005.hk&f=nl1

傳回 2330.tw 的歷史股價,2010/01/04 ~ 2010/08/15
http://ichart.finance.yahoo.com/table.csv?s=2330.TW&a=00&b=4&c=2010&d=07&e=15&f=2010&g=d&ignore=.csv

附註
其實很多欄位都是錯的,包括還原後的股價;google finance 雖然都是對的,但是資料類別較少,而且只有美國的可以下載。

Reference
http://www.gummy-stuff.org/Yahoo-data.htm

2010-08-13

債券養券如何為券商票券商銀行賺錢

這玩意兒說穿了比權証更不值錢,主要是根據流動性偏好理論,利率通常是短低長高,所以就有了交易空間。

養券,又叫做附買回交易 (repo),指的是約定一定的期間以一定的價格交易擔保品,到期後再以約定的另一個價格買回。常見的如以下交易,一億的本金以 0.30% 跟券商做附買回交易,天期 30 天,所以到期可以拿到 100,000,000 X 0.30% X 30 / 365 = 24,657 元的利息加上一億本金。客戶的風險主要有兩個,第一個是交易對手風險,第二個是擔保品風險。而券商的風險是債券評價的風險,因為債券跟股票一樣,也是有起伏的,不過券商跟銀行通常都是拿冷門券去養券,所以評價風險不大。

至於券商跟銀行賺多少呢,假如這個券是 1.60% 的成本買進,會計科目是持有到期,券商就賺了 1.60% - 0.30% = 1.30%,金額大約是 100,000,000 X 1.30% X 30 / 365 = 106,849 元。另外的好處是,由於券商通常只配給面額九成的券作為擔保品,所以還多收了一千萬的現金,呵呵。

看起來好像不多?事實上有些券商票券商銀行養了數百億的券,有不少還是以前高利率時買來的,因為會計制度的問題,所以一直沒有以公平市價來評價,所以變成了細水長流的生意;而且有些高票面利率的券,百元價動輒 13X 元,如果用市價來配,手上多出的現金就更多了,好像豬公一樣越養越肥。

至於是誰會作這樣的附買回交易?手上現金很多的人,債券型基金,貨幣型基金,銀行,壽險,上市公司,族繁不及備載,台灣這幾年低利環境下,遊資多的誇張,央行 NCD 還有好幾兆,呵呵呵。

權証如何為券商賺錢

一言以蔽之,普通選擇權的關鍵在波動率,當多頭市場來臨時,投資人紛紛踴躍進場,尤有甚者,加大槓桿賭一把,這時券商的新金融商品部就會推出認購權證,也就是一種買權。

由於對衍生性商品的認識不足,一般投資人並不十分明白選擇權的特性,事實上,時至今日,除了專門負責定價與避險的人,今日的金融機構對選擇權的了解還是不太夠,所以也不明白為啥賣權證給散戶可以賺錢,或者,其實避險交易不當,還少賺了很多該賺的錢。

舉個例子,一個股票從 20 元漲到 40 元,過去半年的波動率為 65%,但是最近交易很熱絡,券商順勢以波動率 95% 賣出認購權證 20,000 單位,時間為 9 個月,履約價 55 元,用 Black-76 模型算出 (r=0, b=0),理論價是 8.71 元,所以券商總共收了 8.71 X 1,000 X 20,000 = 174,200,000 元的權利金。一年後,發現其實這段期間的波動率是 70%,所以當然選擇權應該是 5.28元,可知 95% -70% = 25% 這段便是券商多收的,假設交易員都很乖照表操課避險,應該要賺的是 8.71 X 1,000 X 20,000 - 5.28 X 1,000 X 20,000 = 68,600,000 元。比這個數字多,那才是交易員為公司賺的,其他的都是因為通路、公司招牌跟無知散戶貢獻的。

上面這個論述應該很多人心裡會不服氣,畢竟既得利益者是很難檢討自己的,所以會說又不是都按理論來,呵呵。其實那更簡單,那就跑實測吧,反正已經過去了,簡單的很。而且券商一年可以發幾十檔,有的落在常態分配右邊,有的在左邊,加加減減其實是差不多。

這幾年台灣的券商在這塊陸續都快玩爛了,散戶雖然還是不很了解,但也知道有鬼;反倒是一些小規模的券商剛拿到發行執照,還在宰殺客戶,嗯嗯,到一定程度後,散戶也不會買單了。香港這玩意也玩爛了,叫渦輪 (warrant),所以後來搞了牛熊證,據說台灣今年會有。

個股選擇權事實上是更好的替代品,只是程式交易需要做的更人性化,像美國這樣的法人市場,活絡的也只有少數個股,如果在以散戶為主的市場,能推出 user-friendly 的介面,相信個股選擇權應該可以擺脫冷淡的交易。

附註
1. sell-side 的單位通常都會有績效獎金,是按絕對金額抽成的。
2. 權證在台灣是列為【有價證券】,只要簽【風險預告書】就可以用一般戶頭買賣,但是不能信用交易,所以不能放空。

債券風險分析

$$D = \displaystyle\frac{{B'}}{-B} = \displaystyle\frac{\sum\frac{C_{t}t}{(1+r)^{t}}}{B} = \displaystyle\frac{\sum\frac{C_{t}t}{(1+r)^{t+1}}}{\sum\frac{C_{t}}{(1+r)^{t}}}$$
$$M = \displaystyle\frac{D}{1+\frac{r}{n}}$$
$$C = \displaystyle\frac{1}{B}\displaystyle\frac{\partial^2 B}{\partial r^2} = M^{2}-\displaystyle\frac{M}{\partial r} = \sum \displaystyle\frac{C_{t}t(t+1)}{(1+r)^{t+2}}$$

\(D\)︰存續期間 (Macaulay duration)
\(M\)︰修正存續期間 (Modified duration)
\(C\)︰曲度 (Convexity)

前兩個可以用 gnumeric 計算,函數分別為 duration,mduration,convexity 就沒辦法了。

還有一個實務上最常用的 DV01 或稱 PV01,指的是殖利率變動 1bp 時,債券價格的變動;由於債券價格跟值利率是曲線關係,所以當變動不大時,可以忽略少許的誤差,事實上,當交易員概算時就會這樣算,譬如變動 20bp 時,就會用變動 1bp 時的變化乘以 20。

附註︰
1bp = 1 basis point = 0.01%

2010-08-12

Black-Scholes 選擇權風險分析

$$\begin{align}
delta_{call} &= \displaystyle\frac{\partial C}{\partial S}\\
&= e^{(b-r)T}N(d_{1})
\end{align}$$
$$\begin{align}
delta_{put} &= \displaystyle\frac{\partial P}{\partial S}\\
&= -e^{(b-r)T}N(-d_{1})
\end{align}$$
$$\begin{align}
gamma &= \displaystyle\frac{\partial^2 C}{\partial S^2} = \displaystyle\frac{\partial^2 P}{\partial S^2}\\
&= \frac{e^{(b-r)T}n(d_{1})}{S\sigma \sqrt{T}}
\end{align}$$
$$\begin{align}
vega &= \displaystyle\frac{\partial C}{\partial \sigma} = \displaystyle\frac{\partial P}{\partial \sigma}\\
&= Se^{(b-r)T}n(d_{1})\sqrt{T}\\
&= Se^{-rT}n(d_{2})\sqrt{T}
\end{align}$$
$$\begin{align}
theta_{call} &= \displaystyle\frac{\partial C}{\partial T}\\
&= \frac{-Se^{(b-r)T}n(d_{1})\sigma}{2\sqrt{T}}\\
& -(b-r)Se^{(b-r)T}N(d_{1})\\
& -rXe^{-rT}N(d_{2})
\end{align}$$
$$\begin{align}
theta_{put} &= \displaystyle\frac{\partial P}{\partial T}\\
&= \frac{-Se^{(b-r)T}n(d_{1})\sigma}{2\sqrt{T}}\\
& +(b-r)Se^{(b-r)T}N(-d_{1})\\
& +rXe^{-rT}N(-d_{2})
\end{align}$$
$$\begin{align}
rho_{call}(b\neq0) &= \displaystyle\frac{\partial C}{\partial r}\\
&= TXe^{-rT}N(d_{2})
\end{align}$$
$$\begin{align}
rho_{put}(b\neq0) &= \displaystyle\frac{\partial P}{\partial r}\\
&= -TXe^{-rT}N(-d_{2})
\end{align}$$
$$\begin{align}
rho_{call}(b=0) &= \displaystyle\frac{\partial C}{\partial r}\\
&= -TC
\end{align}$$
$$\begin{align}
rho_{put}(b=0) &= \displaystyle\frac{\partial P}{\partial r}\\
&= -TP
\end{align}$$
$$\begin{align}
carry_{call} &= \displaystyle\frac{\partial C}{\partial b}\\
&= TSe^{(b-r)T}N(d_{1})
\end{align}$$
$$\begin{align}
carry_{put} &= \displaystyle\frac{\partial P}{\partial b}\\
&= -TSe^{(b-r)T}N(-d_{1})
\end{align}$$
$$d_{1} = \frac{ln(\frac{S}{X})+(b+\frac{\sigma^{2}}{2})T}{\sigma \sqrt{T}}$$
$$d_{2} = d_{1}-\sigma \sqrt{T}$$

\(C\)︰買權(call)
\(P\)︰賣權(put)
\(n\)︰常態分配的機率密度函數(probability density function of general normal distribution)
\(N\)︰累加常態分配函數(cumulative normal distribution function)
\(S\)︰現貨價格(spot price)
\(X\)︰履約價格(strike price)(exercise price)
\(r\)︰無風險利率(risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本(cost of carry)
\(T\)︰離到期日還有多久,單位是年
\(\sigma\)︰波動率(volatility),單位是%

這些gnumeric全部都有,分別是opt_bs_delta,opt_bs_gamma,opt_bs_vega,opt_bs_theta,opt_bs_rho,opt_bs_carry,各自的意義全寫在式子了。

外匯選擇權定價

其實只是Black-Scholes的一種應用而已。

$$
C = e^{-r_{f}T}S_{0}N(d_{1})-e^{-r_{d}T}XN(d_{2})$$
$$P = e^{-r_{d}T}XN(-d_{2})-e^{-r_{f}T}S_{0}N(-d_{1})$$
$$d_{1} = \frac{ln(\frac{S_{0}}{X})+(r_{d}-r_{f}+\frac{\sigma^{2}}{2})T}{\sigma \sqrt{T}}$$
$$d_{2} = d_{1}-\sigma \sqrt{T}$$

\(C\)︰買權 (call)
\(P\)︰賣權 (put)
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S_{0}\)︰現貨價格 (spot price)
\(X\)︰履約價格 (strike price)(exercise price)
\(r_{d}\)︰本國無風險利率 (domestic risk-free rate),通常會用相同天期的公債殖利率
\(r_{f}\)︰外國無風險利率 (foreign risk-free rate),通常會用相同天期的公債殖利率
\(T\)︰離到期日還有多久,單位是年
\(\sigma\)︰波動率 (volatility),單位是 %

舉例,現在 TWD/USD=32,履約價 34,期間九個月,美元九個月期國庫券 0.8%,台幣九個月 NCD=0.5%,假設未來九個月 TWD/USD 波動率為 4%,用gnumeric計算,

因為是用美金報價,所以
\(r_{d}\) = 0.8%
\(r_{f}\) = 0.5%
\(b\) = \(r_{d}\) - \(r_{f}\) = 0.8% - 0.5% = 0.3%

opt_bs(call_put_flag, spot, strike, time, rate, volatility, cost of carry)
opt_bs("call", 32, 34, 0.75, 0.8%, 35%, 0.3%) = 0.02156

一千萬美金的合約可以收大約 21.56 萬美金,折合台幣約 690 萬,是不是覺得很爽?其實喜歡收權利金的公司都是收少了,因為台灣的銀行大部分都不會報買價跟賣價,所以很多企業都是沒概念,加上作公司財務的人通常數學都比較弱,這門銀行買賣選擇權的行業變成了一個暴利行業。事實上 CMENASDAQ 現在都有掛牌的 currency option,就跟台指選擇權一樣,透過交易所交易,免除交易對手風險 (企業通常都要跟銀行簽 ISDA,有的還要 CSA,計算代理人是銀行),而且價格透明,買賣價報價窄,流動性佳,現在連韓圜都有了,台灣這樣搞實在是叫銀行躺著賺,甚至是躺著 A。

台灣這些大公司其實收付款都是美金,我認為根本就不需要換回台幣,只要留一小小部份付薪水就夠了。今年 USD/EUR 大幅走低,TWD/USD 又走高,八月底財報一定很有趣,哈哈。我很想問那些愛玩外匯的公司,很多跨國性大公司在多個國家掛牌用不同必別交易,換作你要怎麼避險?

附註︰
ISDA = International Swaps and Derivatives Association Master Agreement
CSA = Credit Support Annex

ubuntu 上的好用軟體 - sage

這個軟體其實我幾年前就看過,不過最近發現實在有長足的進步。

首先,notebook 介面做的很好,個人覺得比 Wolfram Mathematica 還好,尤其是眼睛不好或需要長時間看螢幕的人。其次,可以架 server,介面就是用 notebook;如果只想用客戶端,則可以直接申請一個帳號用;我發現有很多學校都有架一個作由教學用途,sage 官網上的第一預備站就是韓國人架的。事實上,我覺得最方便的是,在 MathML 成熟前,已經有了一個地方可以直接作數學交流。第三,我這次會重新再考慮它主要是代數運算跟微積分,雖然他用的是 Maxima,但是 sage 的操作介面是 Python;R 雖然很快,但是沒有代數運算。Python 雖然有 sympy,不過還在發展中,它的長期目標是用 C 全部改寫,所以還是先不要用在重要的地方,等長期計畫完成,sage 應該也會因此受益。第四,支援 LaTex 語法,這應該會是研究人員最重視的部份之一吧,以後只要寫一次,放網頁、寫論文、計算,統統搞定。

安裝步驟︰下載後解壓縮,切換到目錄
./sage
啟動notebook server並在瀏覽器打開
notebook()

我建議台灣的教育單位可以架一個 sage server,因為這實在會有莫大的方便。

2010-08-10

Black-Scholes 選擇權定價

$$C = e^{(b-r)T}SN(d_{1})-e^{-rT}XN(d_{2})$$
$$P = e^{-rT}XN(-d_{2})-e^{(b-r)T}SN(-d_{1})$$
$$d_{1} = \frac{ln(\frac{S}{X})+(b+\frac{\sigma^{2}}{2})T}{\sigma \sqrt{T}}$$
$$d_{2} = d_{1}-\sigma \sqrt{T}$$

\(C\)︰買權 (call)
\(P\)︰賣權 (put)
\(N\)︰累加常態分配函數 (cumulative normal distribution function)
\(S\)︰現貨價格 (spot price)
\(X\)︰履約價格 (strike price)(exercise price)
\(r\)︰無風險利率 (risk-free rate),通常會用相同天期的公債殖利率
\(b\)︰持有現貨產生的收益或倉儲成本 (cost of carry)。
\(T\)︰離到期日還有多久,單位是年
\(\sigma\)︰波動率 (volatility),單位是 %

假設現在有一個買權,現貨價格 60 元,履約價格 70 元,離到期還有 0.6 年,無風險利率是 0.5%,假設未來 0.6 年的波動率是 35%,用 gnumeric 計算。

opt_bs(call_put_flag, spot, strike, time, rate, volatility, cost of carry)
opt_bs("call", 60, 70, 0.6, 0.5%, 35%, 0) = 3.0934

cost_of_carry = 0,因為持有股票沒有複利,存在保證金帳戶的錢也沒有利息,所以是 0。

最後,excel 沒有這個 function,只能自己寫;google spreadsheet 也沒有。

債券價格計算

$$B=\sum\frac{C_{t}}{(1+r)^{t}}$$

\(B\)︰這個就是所謂含息價 (dirty price)。
\(C_{t}\)︰各期現金流量 (cash flow),最後一期要加上本金。
\(r\)︰殖利率 (yield),就是平常看到 X.XX% 那東西。
\(t\)︰折現因子,單位是年。

gnumeric 可以簡單解決這問題,但是很多人會弄錯,哈。因為會發現有個叫做 price 的 function,直接輸入就會得出除息價 (clean price),事實上交割的金額是含息價 (dirty price),也就是上面的那個式子,所以要加上從上次付息日到交割日的利息,俗稱前手息。

excel 的函數說明寫的很爛,我建議直接看英文的,因為中文的翻譯錯的相當離譜。

舉一個例子,2010/8/10 交割,2016/6/10 到期,票面利率 2.00%,以殖利率 2.50% 成交,票面金額 100 元。

除息價
price("2010/8/10", "2016/6/10", 2.00%, 2.50%, 100, 1, 1) = 97.313826
前手息
accrint(couppcd("2010/8/10", "2016/6/10", 1, 1), coupncd("2010/8/10", "2016/6/10", 1, 1), "2010/8/10", 2.00%, 100, 1, 1) = 0.334247
含息價
97.313826 + 0.334247

Redemption = 100 是因為換手並沒有懲罰條款,frequency = 1 指的是一年付利息一次,basis = 1 是指交易日計算方式,台灣是 actual / actual,所以是 1。

但是如果把它套到台灣的公債市場,就會發現有一點不一樣。台灣的公債面額是五千萬,所以有人會想把含息價 x 500,000,得出快速結果。通常可以得到正確答案,但是有時後會少一塊錢,因為根據台灣的櫃檯買賣中心公佈的計算方式,是把每一條現金流量折現再全部加起來,但是應計利息四捨五入至整數位,所以差距就這樣發生了。

其實應該要有一個 function 叫做 dirty price 才對,因為直接折現出來就是 dirty price,而且 duration 跟 convexity 都要微分,不知道當初設計的人怎麼想的。

2010-08-08

在 ubuntu 安裝 apache2

在 ubuntu 10.04 Lucid Lynx 下十分簡單,只要兩個套件,apache2 跟 libapache2-mod-php5,就好了,其他相依的套件都會自動抓;另外,用 python 開發也越來越流行,只要多裝一個 libapache2-mod-python 就好了。

啟動 web server
sudo /etc/init.d/apache2 start
預設的開發資料夾︰/var/www/

ubuntu 與無線網卡

基本上,ubuntu 裝好後,大部分的硬體都可以正常運作,有線網卡當然沒有問題,最容易出現問題的是無線網卡。官方支援的無線網卡可以看這邊,詳細閱讀文件後,可以發現 Intel 晶片的支援度最好,尤其是較新的 Linux 核心,都已經整合了 iwlwifi。其次推薦的是 Atheros 晶片,其中不少也已經整合進 Linux 核心。另外還推薦一家 Ralink,雷凌科技,沒錯,就是那家在台灣證交所上市的公司,這家的無線網路晶片據說是低價版,不過事實是如果你要買 USB 無線網卡,最方便買到的大概就是它,從這張表看來,需要到官網自行下載並 compile,可能對新手會有點困難。

前一陣子,我幫我的桌上型電腦裝了一塊 DWA-547,果然一開機就抓到,無痛解決。真正麻煩的是我另外一台 Accer L3600,看起來像是桌機,事實上裡面都是筆電的規格,而被 ubuntu 支援的 USB 無線網卡又少,有一張可以無痛安裝,TP-LINK TL-WN821N,不過會隨機掛掉,且目前原廠說無法可解。所以只好上網去買一張 mini-pci 的網卡,就算是 Intel 最新晶片 Intel WiFi Link 5300 也只要 USD 2X 元就有,另外還要買內接式的天線,要買三條線的版本,據說很多筆電內部只接了兩條線,訊號強度有差,而且中間那條才是 802.11n。裝好後,ubuntu 有抓到,但是無法選擇啟動,輸入 'rfkill list',發現 'hard blocked: yes',原來是要用硬體啟動,也就是一般筆電上有一顆開關無線網卡的按鈕。上網找資料,發現原來只要把 pin 20 弄短路就好了,方法是用絕緣膠帶貼在那個 pin 就好了,重開,果然正常了。附上 pin 定義文件,有需要的自己看。

2010-08-03

在網頁顯示數學式子

我指的當然不是用圖片檔來顯示,那樣太笨了,我指的是終極的解決辦法。我心目中的終極解決是這樣子,可以用 LaTex 語法輸入,也可以直接複製該式子,可以直接在網頁顯示而不需要額外插件。很可惜,目前不存在這樣的方案。

第一種是透過 google chart api formulas 顯示數學式子圖片,雖然還是圖片檔,但是語法很簡單,直接輸入網址即可,網址的後半段是 LaTex 語法。缺點是圖片檔,優點是 browser 不用插件。第二種是透過 javascript,ASCIIMathML,缺點是沒有支援 MathML 的 browser 就不能正確顯示,如 chrome,根據google 表示,因為 chrome 用的是 webkit 引擎,所以不能支援,一旦新的 webkit 支援 MathML 就好了,優點是 LaTex 支援語法,且這個 javascript 還支援向量畫圖。第三個也是插件,TeX The World for Chromium,缺點當然是只有 chrome 能看,優點是三者中使用最方便的。

W3C 認為的最佳方法是 MathML,原生可以支援的 browser 有三個,M$ IE 要插件,其中 W3C 官方的 Amaya 當然支援,不過 Amaya 真的很難用,又慢,這陣子 W3C 又在規劃 MathML 3.0,希望這個陣痛期趕快過。目前可能還是 firefox 最適合 MathML。

最後,server side 的解決方法當然是很好,不過現在自己架站的人實在太少了,免費的 blog 一大堆,google app engine 也是免費,不過這些都不支援 server side 的解決方案,還是只能從上面三類方案選一種。

ubuntu 上的好用軟體 - Gnumeric Spreadsheet

他是一個跟 MS EXCEL 很像的軟體,不過有三大特色︰free, fast, accurate。前兩個就不用說了,精確方面真的是很不錯,舉個簡單的例子,統計中的標準常態分配函數 normsdist,EXCEL 到了 2007 版才能精確到小數點 15 位,之前都只能到 6 位。事實上,我檢查了一下他的程式碼,發現很多都是從 R 來的,難怪快又準。另外,他也是 Gnome Office 的成員,所以長期發展不會有問題,可以安心使用。

推薦這軟體最大的用意其實是他的 functions 很完整,有一大堆 EXCEL 沒有的功能。最方便的是有很多內建的選擇權公式,而且內部是用 C 語言寫的,相信對有需要的人應該是如天降甘霖吧。我大致檢查過了,應該都是正確的。

這軟體有兩個主要缺點,第一個當然就是沒有 script 語言,EXCEL 之所以強大,事實上得益於 VBA 不少,而且 EXCEL 也是 MS 花最多時間心力的一個軟體,前後相容性做的真的是很好,2007 版在直接抓網頁進入欄位更是一大進步,而且還不需要用到 VBA,傳統上可是要 php(or python) + XML(or HTML) parser + SQL。我看官網上長期計畫要導入script 語言,我猜應該會是 python 吧。第二個其實不是這軟體的問題,就是沒辦法連external DDE,看到前面有很多選擇權公式可以用的人可能心裡涼一半了,哈哈。其實 EXCEL+VBA 也沒那麼廢,我試過大約可以同時跑一百個選擇權的計算而不會lag,從用牛頓法算出 implied volatility (這個最耗 CPU ),到delta,gamma,vega,Theta,所以還是堪用啦,只是如果要玩得專業 (嗯,大部分從業人員跟教授都不是很專業),你就會覺得太慢了。

2010.08.12 更新︰已經可以用 Python plugin 了,也可以用 Python 定義函數,然後直接在 Gnumeric 中使用。官網上的說明有點問題,函數的範例直接看 plugins 中的 Python Functions。

2011.04.04 更新︰官網說 vba 勝出,python 等語言要放在(更)長期計畫。

ubuntu 上的好用軟體 - AbiWord

看名稱就知道是跟 MS word 類似的軟體,不過速度快很多,少用的東西都不見了,所以相當簡潔。它也是 Gnome Office 計畫的一個成員,所以後續發展沒有問題。輸出的檔案格式也相當豐富,常見的.doc,.pdf,.html,.txt 都有,其他像是.LaTex,.ps 也有,當然還有很多罕見的格式。另外這軟體既然是 open source,所以各平台都有。

看到上面有支援 Latex,所以想當然會支援 LaTex 數學語法,從 Incert→Equation→from LaTex 就可以用 LaTex 語法輸入數學式子,由於是向量字型,所以放大後也不會有鋸齒,對於常常需要用到數學式子的人應該是一大吸引力吧。

至於轉碼問題,這是他的弱項,ubuntu 上我都是用 iconv 指令來轉,所以不成問題。MS 上我就不知了,印象中好像有不少線上轉碼的工具,google 一下應該很多。

2010-07-21

遠端 P2P 設定 (server 端)

既然有了 24 小時不關機的省電動物機,接下來的當然是如何遠端控制它,喜歡 VNC 的,這篇可以跳過了。

Transmission 設定方面,Preferences → Web → Enable web client 打勾。然後在同一畫面的 Addresses 增加 Client 端的 IP,允許 Client 端操作 Server 端。接下來就可以在guest 端用 browser 直接輸入 http://動物機IP:port 來遠端執行。

aMule 設定方面,Preferences → Remote Controls → Accept external connections 打勾,設定密碼,就完成了。

Acer Revo R3610 動物機 + HTPC

既然是動物機,當然是要低耗電為主,所以 ATOM 是首選。我買的這台 R3610 配備的是 N330,Linux 系統,2GB DDR800 SDRAM (筆電規格),由於記憶體不貴,所以我把它加到了 4GB,總共也不到一萬元,不過因為 BIOS 寫的有問題,因此只能抓到 3.2GB 左右,國外討論區有人說要打電話給 Acer 抗議到他們願意處理為止,這點子不錯。這台機器還有一個好處,就是 ION 晶片,可以硬解1080P影片,所以可以直接放在電視機旁邊,直接用它來看影片。據說看 1080P 時才耗27 watts,27 X 24 X 30 = 19440,開機一個月才用 20 度電。

下面簡單介紹怎麼設定動物機以及看 1080P 影片。作業系統我選擇 Ubuntu 10.04,統統用預設的就可以全部裝好,應該不用 15 分鐘吧。Ubuntu 開機後,無線網路跟 ION 都沒有裝好,我這台的無線網路晶片是 Ralink 3090,可以去官網抓回去自己 compile,不過這邊已經有好心人做好 debian 檔了。至於 ION 晶片,加入 VDPAU PPAUbuntu-X PPA,然後裝好 SMPlayer 後,全系統 update,就完成全部的硬體安裝了。要用 VLC 需要加入 Cutting Edge Multimedia設定,我個人偏好用 VLC。

接下來還要做一點 SMPlayer 設定,Options → Preferences → General → Video → Output driver 選 vdpau,Options → Preferences → Subtitles → Fonts and colors → Font 選 WenQuanYi Micro Hei (當然你可以選其他的,不過這個 UTF8 向量字型是免費的而且有正體跟簡體) (另外,文泉驛的書寫方式是跟台灣教育部的寫法有出入),這樣就設定好 1080P 的 player 了。

最後是 P2P 軟體,Transmission 是預設的,所以只要再加上 aMule 就好了。

PS
最好是用外接硬碟來當 P2P 硬碟,萬一硬碟壞了,這台小機器看起來蠻難拆的。

開張

這個部落格主要紀錄一些我的雜記跟感想,所以範圍可能較大,當然一切力求正確,有啥建議與指教也請不吝指教留言。