You are on page 1of 22

XQ 量化交易平台上的型態學相關函數 - XQ 官方部落格

計算任意二個日期的走勢角度。回傳數值=Angle(日期 1,日期 2)

傳入二個參數:– 第一個參數是日期 1。 – 第二個參數是日期 2,需大於日期 1。

角度

從腳本中我們可以發現,angle 這個值的計算有兩個步驟

第一是先算出斜率_slope

斜率的算法是以最近一期收盤價除以計算起始期的開盤價減一當分子(也就是漲跌幅),以兩個日期的差當分母,
然後乘以 100。

第二是把斜率用 arcTangent 函數,把數值轉成角度。

由於 arcTangent 是利用已知直角三角形的對邊和鄰邊這兩條直角邊的比值求出其夾角大小的函數,用來算對邊
與鄰邊值的角度,所以算出來的角度就是這兩個區間的線段的上漲或下跌角度值。

當回傳數值大於 0 時,代表趨勢向上;當回傳數值小於 0 時,代表趨勢向下。

回傳值的數值絕對值愈大,代表這個線段的斜率愈陡。
V轉
突破區間高點 (Value1=nthhighest(2,high,5);)

input:period(20,"計算區間");

value2=nthhighest(1,high[1],period);//最高價

value3=nthhighest(2,high[1],period);//第二高價

value4=nthhighest(3,high[1],period);//第三高價

value5=nthhighestbar(1,high[1],period);//最高價距今幾根 bar

value6=nthhighestbar(2,high[1],period);//第二高價距今幾根 bar

value7=nthhighestbar(3,high[1],period);//第三高價距今幾根 barif

value6-value5>3 and value7-value6>3 //三個高點沒有連在一起,且是愈


來愈高
and
maxlist(value2,value3,value4)<minlist(value2,value3,value4)*
1.05 //三個高點相差不到 5%2425and close crosses over value2 //

創新高 then ret=1;


多次到頂而破的例子,用到的是 highest 及 highestbar 這兩個函數

input:HitTimes(4,"設定觸頂次數");

input:RangeRatio(1,"設定頭部區範圍寬度%");

input:Length(40,"計算期數");

If GetSymbolField("tse.tw"," 收 盤 價 ") >average(GetSymbolField("tse.tw"," 收 盤 價 "),10)

then begin

variable: theHigh(0); //找到過去其間的最高點

theHigh = Highest(High[1],Length);

value1=highestbar(high[1],length);

variable: HighLowerBound(0); // 設為瓶頸區間上界

HighLowerBound = theHigh *(100-RangeRatio)/100;

variable: TouchRangeTimes(0); //回算在此區間中 進去瓶頸區的次數 TouchRangeTimes

= CountIF(High[1] > HighLowerBound, Length-value1);

Condition1 = TouchRangeTimes >= HitTimes; Condition2 = close > theHigh;

condition3=close[length]*1.1<thehigh;

Ret = Condition1 and Condition2 and condition3 ;

end;
試著用程式來描述型態之一 見底強勢回昇

這張圖歸納起來,描述的概念有以下幾點

1.股價一再破底,低點愈來愈低。

2.跌到最低點後出現急拉,且高點突破上一波低點,並且漲幅超過前一波反彈高點的一半

3.拉回跌破前一波低點後立即以長紅棒再次突破前一波低點,此時是進場訊號

4.股價如果持續上漲且突破前一波高點,即為確認訊號

根據上述的條件,我寫的腳本如下

input:period(25);
var:h1(0),h2(0),low1(0),low2(0),low3(0),hb1(0),hb2(0),lowb1(
0),lowb2(0),lowb3(0);low1=lowest(close,period);//最低點

h1=highest(close,period);//最高點

lowb1=lowestbar(close,period);//最低點所在的 bar

hb1=highestbar(close,period);//最高點所在的 bar

low2=swinglow(close,period,3,3,2);//第二低點

lowb2=swinglowbar(close,period,3,3,2);//第二低點所在的 bar

low3=swinglow(close,period,3,3,3);//第三低點
lowb3=swinglowbar(close,period,3,3,3);//第三低點所在的 bar

h2=swinghigh(close,period,3,3,2);//第二高點

hb2=swinghighbar(close,period,3,3,2);//第二高點所在的位置

value1=h1-low1;//計算最後一波下跌的長度

value2=h2-low1;//計算第一波回昇的長度
if lowb2=nthmaxlist(1,hb1,hb2,lowb1,lowb2,lowb3)
and hb1=nthmaxlist(2,hb1,hb2,lowb1,lowb2,lowb3)
and lowb1=nthmaxlist(3,hb1,hb2,lowb1,lowb2,lowb3)

and hb2=nthmaxlist(4,hb1,hb2,lowb1,lowb2,lowb3)20//設定各高低點
的相對位置
and close[60]>value1*1.222//波段大跌 2 成以上

and value2>value1*0.524//回昇第一波要大於左頂到最低點的一半

and h2>low2//回昇第一波的高點要大於左底
and close cross over low2
then ret=1;

寫出來的腳本,可以出像下面這樣的股票

在 XS 編輯器搜尋書中所述的程式碼
在三週學會程式交易書籍中,有許多的程式碼範例。從 6.33/2.33 開始,我們有在 XS 編輯器中,內建書籍中的
程式碼,提供讀者直接搜尋,不必自行 Key 入書上所述的程式碼,以便大家學習,接下來為大家介紹如何在 XS
編輯器搜尋書籍中的程式碼。

首先,請大家先開啟 XScript 編輯器

進入到 XScript 編輯器的畫面後,進行如下圖(可點選滑鼠左鍵或右鍵另開頁面放大圖片)的操作步驟,就可以在


搜尋結果中,找到 XS 腳本與對應的書籍頁碼囉!

我們將以下述五個步驟,示範在 XS 編輯器中尋找第 259 頁大盤六度空間切割法的 XS 程式碼

1. 在功能列點選編輯
2. 選單中點選尋找所有文件
3. 在尋找目標文字方塊中,Key 入關鍵字:三週學會程式交易
4. 記得勾選所有文件
5. 按下尋找全部

執行完五個步驟後,跑出來的畫面如上圖,就能在搜尋結果(下方訊息視窗的搜尋結果)中,查看到第 259 頁大
盤六度空間切割法的 XS 腳本,最後再點選滑鼠左鍵兩下,就可以叫出此 XS 腳本的程式碼內容囉!

* 文末彩蛋

我們也在 XS 編輯器內建了一些交易點點滴滴提到的腳本,

故在尋找所有文件功能中,尋找目標的關鍵字換成文章標題,也可以找到對應的腳本唷!

例如:今天在交易點點滴滴看到了 上漲下跌家數差 RSI 指標 此篇文章,想在 XS 編輯器中搜尋對應的腳本,


就可以使用尋找所有文件功能,Key 入關鍵字:上漲下跌家數差 RSI 指標,就能在搜尋結果中找到對應的腳本
囉!

當 XS 遇到 AI~ 從特徵值的選取開始
第一檔用人工智慧操盤的 ETF AIEQ.US 上市後,受到媒體的瘋狂吹捧,說這檔 ETF 輕鬆就打敗華爾街,結果
從本週一起,這檔 ETF 就像吃了瀉藥一樣,跌破掛牌價,感覺用 AI 來操盤好像沒有那麼容易,但去年績效最好
的前十大避險基金,又有八檔是量化型基金,好像運用電腦及數據分析來操作才是王道,到底要怎麼正確看待
AI 在投資操作上的應用? 我想透過一系列的實際例子來跟大家分享,今天是第一篇,先跟大家談談程式交易跟
AI 的前世今生。

首先,先請大家看一個我曾分享過的指標腳本

1input:day(20);2input:ratio(30);3variable:count(0),x(0);4valu

e1=GetField("總成交次

數","D");5value2=average(value1,day);6value3=GetField("強弱指

標");7value5=GetField("外盤均量");

8value6=average(value5,day);9value7=GetField("主動買力");

10value8=average(value7,day);11value9=GetField("開盤委買");

12value10=average(value9,day);13value11=GetField("資金流向");

14value12=average(value11,day);15value13=countif(value3>1,day

);16value14=average(value13,day);//比大盤強天數

17value16=GetField("法人買張");1819count=0;20if

value1>value2*(1+ratio/100)21then count=count+1;22if

value13>value14*(1+ratio/100)//比大盤強的天數 23then

count=count+1;24if value5>value6*(1+ratio/100)25then

count=count+1;26if value7>value8*(1+ratio/100)27then

count=count+1;28if value9>value10*(1+ratio/100)29then

count=count+1;30if truerange> average(truerange,20)//真實波動

區間 31then count=count+1;32if truerange<>033then begin34if

close<=open35then36value15=(close-low)/truerange*10037else38v

alue15=(open-low)/truerange*100;//計算承接的力道 39end;40if

value15>average(value15,day)*(1+ratio/100)41then
count=count+1;42if volume<>043then

value17=value16/volume*100;//法人買張佔成交量比例 4445if

value17>average(value17,10)*(1+ratio/100)46then

count=count+1;4748if

value11>average(value11,10)*(1+ratio/100)49then

count=count+1;50x=0;51value18=summationif(close>=close[1]*1.0

2,x,5);52if value18>=2 53then count=count+1;//N 日來漲幅較大的天

數 54555657value19=GetField("融資買進張數");

58value20=GetField("融券買進張數");

59value21=(value19+value20);60value22=average(value21,day);61

if value21<value22*0.9 //散戶作多指標 62then

count=count+1;6364plot1(average(count,5),"股性綜合分數指標");

65plot2(3);

在這個腳本裡,我的作法是
1.先挑出一些我覺得會影響股價的特徵值,把這些數據叫出來

2.把這些數據取 20 日平均。

3.當最新一筆數字比 20 日平均值高出一定的比例時,就加一分

4.統計每一天這些特徵值合計得多少分

5.透過經驗法則,把這個指標寫成交易策略,然後透過回測去找出勝率最高的參數及適用的商品。

以上是一個常規的程式交易模型的開發過程。整個過程就像下面這張圖

在程式裡,我們安排在什麼情況下,該項特徵值的計分可以從 0 分變成 1 分,其次是每一個特徵值在合計分數


裡,是一樣重要的,所以加總分時沒有特別那個項目被加權,最後再把總分透過一個激發函數,決定當總分怎
麼變化時,預測市場會上漲。 接下來我們的作法是透過回測,去調各種參數,然後找出勝率最高的參數及應用
的商品。 這麼多年來,程式交易咱們都是這麼做的。

那麼人工智慧跟程式交易的差別在那呢?

人工智慧的作法是反過來,拿歷史資料來當樣本,去運算什麼參數組合下,預測的精準度最高,這樣的好處是,
我們只要找出有意義的特徵值,那個特徵值要如何計分,這些特徵值合在一起時,權重如何拿捏,都是拿歷史
資料來找出預測精準度最高的值。程式交易與人工智慧模型的差別就在這裡,可以讓,程式交易是人工智慧模
型的先期準備步驟,我們透過程式交易找出有意義的特徵值,這些特徵值要如何協同作出對未來行情的預測,
程式交易是給定參數後,跑回測去算勝率,人工智慧則是透過不斷的微調參數後找出預測精準度最高的那一組
參數。

以上大致是這兩者間求最佳參數的不同過程,接下來後面我再跟大家舉例人工智慧如何解上面這道題。

當 XS 遇到 AI 之 2~如何用 XS 來準備 Data


上一篇舉了一個例子,來說明過往的程式交易作法是把我們的操作邏 輯寫成腳本,把決策過程清楚的定義後,
拿歷史資料來回測看其勝率,再來決定這個策略要不要用? 要用到什麼商品? 在什麼情況下進場? 出場?,
所有的決策邏輯,用 and,or,not,xor 來判斷,一般我們稱為 rule base 的決策方式。今天我想舉實際的例子,
透過 XS 把我覺得會影響股價的因素列出來,準備足夠的樣本,然後用 Python 的 AI 模組,試著看看透過多層感
知器這樣的模型,能不能達到預測未來多空方向的效果。

首先,先來說明一下我的思維架構

我認為,人工智慧的演算過程,是用已知的 X1,X2,X3……….Xn,去建構一個函數,讓這個函數產出的 Yf,愈


接近真實的 Yt 愈好。

Yf=f(x1,x2……….xn)

min(Yf-Yt)

所以建構人工智慧的演算模型,一共有幾件事情要做

一,決定 x1,x2……….xn 等等的輸入特徵值

二,決定要找的答案是什麼?(也就是輸出值是什麼?),要預測的是什麼?

三,準備好可以讓電腦演算學習的資料

四,建構演算模型

五,決定衡量預測能力的標準

例如我想透過昨天收盤後的各種數據,想要預測今天某檔個股會不會比前一天上漲?

首先,要決定那些數據會影響隔天的行情?

在這個例子裡,我一共用了三種數據

1. 昨天跟大家介紹的股性相關數據,超過 20 天平均水準一定的比例就記為 1,不然就記為 0


2. K 棒本身開高低收的相對位置
3. 幾個常用技術分析數據的值

根據上述的作法,我用 XS 所寫的整理數據腳本如下

variable:v1(0),v2(0),v3(0),v4(0),v5(0),v6(0),v7(0),v8(0),v9(0),v10(0)
,v11(0),v12(0),v13(0),v14(0),v15(0),v16(0),v17(0),v18(0),v19(0),v20(0);

variable:v21(0),v22(0),v23(0),v24(0),v25(0),v26(0),v27(0),v28(0),v29(0),v30(0);

var:y(0);

//如果某個欄位表現異於平常就記為 1,不然就記為 0,以 0 跟 1 代表某股性的特徵值

input:day(20);

input:ratio(30);

variable:count(0),x(0);

value1=GetField("總成交次數","D");

value2=average(value1,day);

value3=GetField("強弱指標");

value5=GetField("外盤均量");

value6=average(value5,day);

value7=GetField("主動買力");

value8=average(value7,day);

value9=GetField("開盤委買");

value10=average(value9,day);

value11=GetField("資金流向");

value12=average(value11,day);

value13=countif(value3>1,day);

value14=average(value13,day);//比大盤強天數

value16=GetField("法人買張");

count=0;

if value1>value2*(1+ratio/100)

then v1=1

else v1=0;
if value13>value14*(1+ratio/100)//比大盤強的天數

then v2=1

else v2=0;

if value5>value6*(1+ratio/100)

then v3=1

else v3=0;

if value7>value8*(1+ratio/100)

then v4=1

else v4=0;

if value9>value10*(1+ratio/100)

then v5=1

else v5=0;

if truerange> average(truerange,20)//真實波動區間

then v6=1

else v6=0;

if truerange<>0

then begin

if close<=open

then

value15=(close-low)/truerange*100

else

value15=(open-low)/truerange*100;//計算承接的力道

end;

if value15>average(value15,day)*(1+ratio/100)

then v7=1
else v7=0;

if volume<>0

then value17=value16/volume*100;//法人買張佔成交量比例

if value17>average(value17,10)*(1+ratio/100)

then v8=1

else v8=0;

if value11>average(value11,10)*(1+ratio/100)

then v9=1

else v9=0;

x=0;

value18=summationif(close>=close[1]*1.02,x,5);

if value18>=2

then v10=1

else v10=0;

;//N 日來漲幅較大的天數

value19=GetField("融資買進張數");

value20=GetField("融券買進張數");

value21=(value19+value20);

value22=average(value21,day);

if value21<value22*0.9 //散戶作多指標

then v11=1

else v11=0;

if close*1.2<close[30]

then v12=1

else v12=0;
//把一根 K 棒開高低收四點彼此間的差異列成六個不同特徵值

v13=(close-open)/close*100;//漲跌幅

v14=(close-low)/close*100;//

v15=(high-close)/close*100;

v16=(high-low)/close*100;

v17=(high-open)/close*100;

v18=(open-low)/close*100;

//把股價單日漲幅是否有超過 2.5%當成一個特徵值

if close>close[1]*1.025

then v19=1

else v19=0;

//把近兩日合計漲跌幅視為一個特徵值

v20=close/close[2];

//把幾個常用的技術指標的計算結果也視為特徵值

variable:rsv1(0),k1(0),d1(0);

stochastic(9,3,3,rsv1,k1,d1);

v21=k1;

input: period(20,"計算區間");

value1=rateofchange(close,period);

//計算區間漲跌幅

value2=arctangent(value1/period*100);

//計算上漲的角度
v22=value2;

input: Length1(14, "期數"), Threshold(25, "穿越值");

variable: pdi_value(0), ndi_value(0), adx_value(0);

DirectionMovement(Length1, pdi_value, ndi_value, adx_value);

v23=pdi_value;

input: FastLength(12, "DIF 短期期數"), SlowLength(26, "DIF 長期期數"), MACDLength(9, "MACD 期數");

variable: difValue(0), macdValue(0), oscValue(0);

MACD(weightedclose(), FastLength, SlowLength, MACDLength, difValue, macdValue, oscValue);

v25=difvalue;

v26= momentum(close,10);

value6=rsi(close,12);

v27=value26;

v24=linearregslope(value26,6);

input:Length2(20); //"計算期間"

variable:u1(0),u2(0),u3(0),u4(0),u5(0),u6(0);

LinearReg(close, Length2, 0, u1, u2, u3, u4);

//做收盤價 20 天線性回歸

{u1:斜率,u4:預期值}

u5=rsquare(close,u4,20);//算收盤價與線性回歸值的 R 平方

v28=u5;

v29=u1;

value11=GetField("投信買賣超");

input:day1(8);

v30=countif(value11>0,day1);
//定義輸出的 Y 值

if close>close[1]

then y=1

else

y=0;

Print(file("C:\Users\lee\.spyder-py3\f301.log"),

numtostr(v1[1], 0), ",",

numtostr(v2[1], 0), ",",

numtostr(v3[1], 0), ",",

numtostr(v4[1], 0), ",",

numtostr(v5[1], 0), ",",

numtostr(v6[1], 0), ",",

numtostr(v7[1], 0), ",",

numtostr(v8[1], 0), ",",

numtostr(v9[1], 0), ",",

numtostr(v10[1], 0), ",",

numtostr(v11[1], 0), ",",

numtostr(v12[1], 0), ",",

numtostr(v13[1], 2), ",",

numtostr(v14[1], 2), ",",

numtostr(v15[1], 2), ",",

numtostr(v16[1], 2), ",",

numtostr(v17[1], 2), ",",

numtostr(v18[1], 2), ",",


numtostr(v19[1], 0), ",",

numtostr(v20[1], 2), ",",

numtostr(v21[1], 2), ",",

numtostr(v22[1], 2), ",",

numtostr(v23[1], 2), ",",

numtostr(v24[1], 2), ",",

numtostr(v25[1], 2), ",",

numtostr(v26[1], 2), ",",

numtostr(v27[1], 2), ",",

numtostr(v28[1], 2), ",",

numtostr(v29[1], 2), ",",

numtostr(v30[1], 2), ",",

numtostr(y,0));

6269
接下來我用的 Python 多層感知器模組的程式碼如下

import numpy as np
import pandas as pd

# 讀入 CSV 資料
df = pd.read_csv(‘f303.csv’)
df.head()

# 取所需的欄位資料
cols_2d = df[[‘v1′,’v2′,’v3′,’v4′,’v5′,’v6′,’v7′,’v8′,’v9′,’v10′,’v11’,
‘v12′,’v13′,’v14′,’v15′,’v16′,’v17′,’v18′,’v19′,’v20′,’v21’,
‘v22’, ‘v23’, ‘v24’, ‘v25’, ‘v26’, ‘v27’, ‘v28’, ‘v29′,’v30′,’yy’]]
cols_2d.head()

# 取 feature, X
X = cols_2d[[‘v1’, ‘v2’, ‘v3’, ‘v4’, ‘v5’, ‘v6’, ‘v7’, ‘v8’, ‘v9’, ‘v10’, ‘v11’,
‘v12’, ‘v13’, ‘v14’, ‘v15’, ‘v16’, ‘v17′,’v18′,’v19′,’v20′,’v21′,’v22′,’v23′,’v24′,’v25’,
‘v26’, ‘v27’, ‘v28’, ‘v29′,’v30’ ]]
X.head()

# 取 label, y
y = cols_2d[‘yy’]
y.head()

# 分訓練與測試資料
from sklearn.cross_validation import train_test_split

X_train_o, X_test_o, y_train, y_test = train_test_split(X, y, test_size = 0.3) # 80%訓練,

20%測試

# 確認分後的筆數
print(‘total:’, len(cols_2d), ‘train X:’, len(X_train_o), ‘test X:’, len(X_test_o), ‘train y:’,
len(y_train), ‘test y:’, len(y_test))
# 將 X 所有欄位進行正規化,將原數字壓到 0~1 之間的數字
from sklearn import preprocessing
minmax_scale = preprocessing.MinMaxScaler(feature_range = (0, 1))
X_train = minmax_scale.fit_transform(X_train_o)
X_test = minmax_scale.fit_transform(X_test_o)

X_train[:10]
X_test[:10]
# 建立 MLP(多重感知器)模型
from keras.models import Sequential
from keras.layers import Dense, Dropout

model = Sequential()

model.add(Dense(units = 120, input_dim = 30, kernel_initializer = ‘uniform’, activation =


‘relu’))
model.add(Dense(units = 100, kernel_initializer = ‘uniform’, activation = ‘relu’))
#model.add(Dropout(0.35))
model.add(Dense(units = 80, kernel_initializer = ‘uniform’, activation = ‘relu’))
#model.add(Dropout(0.35))
model.add(Dense(units = 70, kernel_initializer = ‘uniform’, activation = ‘relu’))
#model.add(Dropout(0.35))
model.add(Dense(units = 1, kernel_initializer = ‘uniform’, activation = ‘sigmoid’))

model.compile(loss = ‘binary_crossentropy’, optimizer = ‘adam’, metrics = [‘accuracy’])

train_history = model.fit(x = X_train, y = y_train, validation_split = 0.1, epochs = 30,


batch_size = 30, verbose = 2)

# 用測試資料預測
scores = model.evaluate(x = X_test, y = y_test)

# 預測準確率
scores[1]

透過這樣的運算,我們可以找到一組的參數,在用這些特徵值去預測隔日股價漲跌時的精
準度可以達到 66%
以上是跟大家透過舉例,介紹 XS 可以做為 人工智慧運算前整理特徵資料的平台,人工智

慧博大精深,要用人工智慧來作投資操作,有很多的關上要克服,XS 看來在特徵值的萃取
及測試資料的整理上可以幫得上忙

至於演算的部份,就只有靠我們自己努力繼續唸書了。

You might also like