Author Archives: 發財橘子

尋找那些先前大漲過,最近在休息的股票

來尋找那些先前大漲過,最近在休息的股票
正所謂春江水暖鴨先知,一檔股票如果兩天可以漲一成,代表有人真金白銀地押在這檔股票上,而且還願意追高,這種情況往往是有人知道了公司不為人知的利多,率先佈局。
但代誌不見得像這些有消息的人想的那麼簡單,有時候盤不好,或者短線獲利及解套的賣壓湧現,造成股價上去又下來,春鴨反而被套牢。
但如果春鴨掌握的消息是正確的,後來隨著消息面的更廣為人知,就會有更多的買盤進場,如果這個利多很大,股價也可能走一大趟多頭行情。
為了挑出這樣的股票,小弟寫了以下這個選股的腳本:

condition1=false;
settotalbar(100);
if countif(close>close[2]*1.1,20)=1
then condition1=true;//過去二十天內有一次兩天漲超過10%
if close*1.05<highest(close,20)//現在股價比20天來的低點低至少5%
and trueall(close<=close[1],2)//這兩天股價都持平或收黑
and highest(close,20)=highest(close,60)//近二十天來的高點跟近六十天來的高點一樣高,代表不是一路下跌的走勢,上次的急拉不是跌深反彈
and condition1
then ret=1;

我把這個選股腳本拿去挑股票,然後再把挑到的股票用策略雷達裡的火箭拉回,階梯式向上等即時盤中腳本來洗價
如果洗出來就代表這檔先前有急拉過的股票,在休息後又蓄勢待發,這種股票我就會列入觀察名單
附圖是一個很典型的例子。
先前大漲現在休息

大盤多空對策訊號

ls3
十九年前,我第一次到證券商研究部當研究員時,部門有三位同仁輪流負責解盤,但大家用的分析工具不一樣,對盤勢的看法常常今天A君說多,明天B君卻翻空。我去分公司時,常被虧說你們研究部像月亮,初一十五不一樣。
後來我跟他們三位老兄分別聊了一下,學景氣燈號的作法,把他們用的分析工具,在EXCEL上作了一個表,每個工具都給一分,用來計算大盤的多空燈號。

後來這件事因為小弟EXCEL功力太差,每次作出來的結果都沒有太大的參考性,加上我又被叫去自營部工作,所以也就無疾而終了。

XS上線後,我一直想再試試重編大盤景氣燈號,研究了一陣子,今天來跟大家報告我的研究結果。

我一共用了以下的數據來當判斷分數的標準
1.外資買賣超
2.投信買賣超
3.自營商買賣超
4.融資餘額
5.融券餘額
6.上漲量
7.外盤量
8.RSI
9.MACD
10.KD
11.DMI
12.主力買賣超
13.AR
14.ACC
15.TRIX
16.SAR
17.MA

每個數據我都訂了一個多頭條件,例如RSI我就訂5日RSI比10日RSI高且低於80

如果符合條件就加一分,然後每天歸零,重新計算,最後再取十日移動平均。
在語法上,寫法大致如下:

input:P1(30);setinputname(1,"先前法人未接觸天數");
variable: XData(0),YData(0),ZData(0),Z(0);
if currenttime > 180000 or currenttime < 083000 then Z =0 else Z=1;

XData = GetField("外資買賣超")[Z];
YData = GetField("投信買賣超")[Z];
ZData = GetField("自營商買賣超")[Z];

value6=GetField("上漲量");
value7=GetField("外盤量");
variable:count(0);
if date<>date[1]
then count=0;
if xdata>0
then count=count+1;

if ydata>0
then count=count+1;

if zdata>0
then count=count+1;

if value4-value4[1]<20000
then count=count+1;

if value5-value5[1]>20000
then count=count+1;

if value6/volume>0.00001
then count=count+1;

if value7/volume>0.5
then count=count+1;

value8=rsi(close,5);
value9=rsi(close,10);
if value8>value9 and value8<90
then count=count+1;

variable: Dif_val(0), MACD_val(0), Osc_val(0);
MACD(Close, 12, 26, 9, Dif_val, MACD_val, Osc_val);
if osc_val>0
then count=count+1;

value10=mtm(10);
if value10>0
then count=count+1;

variable:rsv1(0),k1(0),d1(0);
stochastic(9,3,3,rsv1,k1,d1);
if k1>d1 and k1<80
then count=count+1;

variable:pdi_value(0),ndi_value(0),adx_value(0);
DirectionMovement(14,pdi_value,ndi_value,adx_value);
if pdi_value>ndi_value
then count=count+1;

value12=GetField("主力買賣超張數");
value13=average(value12,5);
if value13>0
then count=count+1;

value14=ar(26);
value15=linearregslope(value14,5);
if value15>0
then count=count+1;

value16=acc(10);
if value16>0
then count=count+1;

value17=trix(close,9);
value18=trix(close,15);
if value17>value18
then count=count+1;
value19=SAR(0.02, 0.02, 0.2);
if close>value19
then count=count+1;

if average(close,5)>average(close,12)
then count=count+1;

value11=average(count,10);
plot1(value11);

最後的分數要取幾天的移動平均,用10天,原因是我一直覺得兩週是多空的一個循環。

另外我會這麼寫的原因是有點認為市場參與者都有觀察市場的方法,我把大家常用的方法列出來計算分數,當分數愈高代表愈多人使用的工具會建議偏多,反之亦然。

所以當分數從五分以下往上走,代表會有愈來愈多人使用的工具開始由空翻多。

也因此,這樣的方法用在小型股就會不大適用,因為參與者不是一般大眾,其多空太容易受特定勢力的左右。

GetField

在XQ量化平台上線之前,市場早有很多套程式語法可供交易者使用,但敢於宣稱這是最適合台灣人使用的程式交易語法,其原因就在於, 我們可以提供台灣市場獨有的欄位,供交易者來使用。
交易者在制定台股交易策略時,往往除了開高低收成交量之外,也想要試著用台股獨特的交易資料,籌碼,財務報表等等欄位,例如法人的進出資料, 來作為交易策略的運算基礎,為了讓交易者可以如願以償,XScript提供了Getfield語法,來協助交易者完成這樣的工作,這篇文章就是來介紹這套語法及其應用。
在撰寫腳本時,當您需要使用這些台股特有的欄位時,只要在編輯器中打一個英文字母g,不管大小寫,編輯器都會跳出一個如下面附圖中的視窗, 只要您選取getfield(插入),系統就會跳出一個選取欄位的視窗,讓您直接挑選要使用的欄位。


您只要選取其中一個欄位按插入鍵,系統就自動把這個欄位帶到您的腳本中,因此,您就不需要去記那個欄位的英文名字是什麼。
例如我們如果要取得今日的外資買賣超,我們的寫法可以如下 :

value1=Getfield("外資買賣超"); 其單位是張數

如果我們要取得前一日的外資買賣超,其寫法跟我們要取得前一日的收盤價是一樣的,也就是用中括號裡寫個1就可以,所以其寫法如下 :

value1=Getfield("外資買賣超")[1];

我們非常習慣用value1=getfield(“欄位名稱”)的語法來取得特定欄位的回傳值,
這裡的value1,您也可以使用自己命名的變數名稱。

那麼到底支援多少台股欄位呢?
上面那張圖所顯示的,當您輸入G來跳出那個選取欄位的對話框時,目前Getfield支援的欄位是屬於資料欄位及商品資訊欄位,在警示類的腳本與選股類的股本中,能使用的欄位也不一樣,先跟大家介紹警示能用的欄位,下面幾類,按下連結後,可以看到所有的欄位,以及欄位的說明及使用範例

價格

量能

籌碼

基本

事件

市場統計

期權

以上是在警示腳本中可以用Getfield語法取得的所有欄位

接下來我介紹只有在選股本中才能用的欄位,如果你要寫的是警示腳本,在那個對話框中就不會有這些欄位可以選用

價格

籌碼

基本

財務

事件

所有跟財務報表有關的欄位,都是要在選股腳本中才用得到

這麼多的欄位,在使用上,XScript建議的語法如下:

Value1=getfield(“tradevalue”)[1]

或是

value1=getfield(“成交金額”)[1]

這兩種方式都可以取得昨日成交金額。

舉個例子,如果要找前一日主力買超創120天來新高,且近三日主力都買超,成交量過500張,且今天上漲超過3%的股票,就可以寫成腳本如下

value1=GetField("主力買賣超張數")[1];
if value1=highest(value1,120)
and trueall(value1>0,3)
and volume>500
and close>close[1]*1.03
then ret=1;

透過getfield這樣的語法,我們可以把台股特有的欄位拿來加入運算,不過要提醒大家,這些資料的更新頻率並不一樣, 所以運用這些欄位的腳本,在設進階警示時,其腳本的頻率必須設定對。

 

Getquote

在實際交易的經驗裡,我們常常透過日,週,月線,去尋找值得留意的交易機會,但進場點,往往還是看盤中的價量表現才作決定。
例如我們可能會去尋找五日RSI與十日RSI黃金交叉的股票,但為了怕是假訊號,我們經常會等到這當股票當天開盤帶量開高後才進場交易。
在未提供跨頻率的語法之前,我們無法同時處理日線上的RSI黃金交叉,又同時處理日內的1分鐘線或5分鐘線帶量開高。
Xscript為了解決這個問題,特別提供一組語法,讓交易者可以直接在盤中把最新的成交價量及委買委賣張數,傳回腳本中來作運算, 這些可以即時取得的交易資料,我們統稱為即時欄位。
從下面的台積電分時走勢圖中,我們可以看到,一檔股票目前交易所即時揭示的交易資料,大約有以下幾項 :

gq1

最新的成交時間,買進價,賣出價,成交價,單量。
最近的五檔買進委託價及對應的委託量
最近的五檔賣出委託價及對應的委託量
對於這些即時的資料,djscript幫它們分別取了不同的欄位名稱,讓交易者可以加以使用,以下就是這些即時欄位在腳本上被引用時的名稱對照表 :

q_dailyopen 開盤(日)
q_dailyhigh 最高(日)
q_dailylow 最低(日)
q_dailyvolume 總量(日)
q_Refprice 參考價
q_AvgPrice 均價
q_last 成交
q_Bid 買進
q_Ask 賣出
q_BidAskFlag 內外盤
q_TickVolume 單量
q_PreTotalVolume 昨量
q_PriceChangeRatio 當日漲幅%
q_InSize 當日內盤量
q_OutSize 當日外盤量
q_BestBid1 買進1
q_BestBid2 買進2
q_BestBid3 買進3
q_BestBid4 買進4
q_BestBid5 買進5
q_BestAsk1 賣出1
q_BestAsk2 賣出2
q_BestAsk3 賣出3
q_BestAsk4 賣出4
q_BestAsk5 賣出5
q_BestBidSize 委買
q_BestAskSize 委賣
q_BestBidSize1 委買1
q_BestBidSize2 委買2
q_BestBidSize3 委買3
q_BestBidSize4 委買4
q_BestBidSize5 委買5
q_SumBidSize 總委買
q_BestAskSize1 委賣1
q_BestAskSize2 委賣2
q_BestAskSize3 委賣3
q_BestAskSize4 委賣4
q_BestAskSize5 委賣5
q_SumAskSize 總委賣
q_DailyUplimit 今日漲停價
q_DailyDownlimit 今日跌停價

在djscript的語法中,取得這些欄位的方式很簡單,那就是運用給定變數這樣的方式,例如 :
Value1=q_dailyopen 就可以取得今天的開盤價,跟Getfield一樣,在撰寫腳本時,只要在編輯器上打 一個英文字母 “g”(大小寫皆可), 就會跳出如下圖左方的小視窗,只要點選”getquote插入”,即會跳出右邊的視窗讓您選擇要使用的即時行情欄位。

gq2

如此一來,就不必把這些欄位的名稱背起來,畢竟,還蠻不好背的。
例如我們如果要尋找今天外盤量佔總成交量比重高的股票,我們就可以寫撰寫如下圖的腳本 :

gq3
在這個例子裡,我們用value1這個內建的變數來代表q_BidAskFlag這個即時的內外盤標示,這個標示的值等於1代表是外盤成交,-1代表是內盤成交。
有了getquote這樣的語法,除了這種內外盤比的數據之外,包括內盤量,外盤量,最佳買進五檔的買進賣出委託量等盤中即時的交易所提供資訊, 都可以拿來作運算,找出盤中價量異常的股票。
getquote算是Xscript在地化特色的一個語法。

變數

什麼是變數?
我們用input來指定一個參數的值,這個值被指定後就不會變,例如我們寫一個腳本如下 :

Input:days(10);
If (close –close[days])/close[days] > 0.1
Then ret=1;

我們用這個腳本來請電腦在股價跟十天前相比,漲幅超過一成時,通知我們,在這個腳本裡,days是一個參數, 我們指定它的值是10,電腦看到days時,會去查我們設的值是多少,當電腦發現我們把days設定為10時,接下來只要在看到 days的地方, 電腦都當它是10來作運算,所以參數的值在我們指定之後,在所有這個腳本的任何一何敘述式中,只要看到這個參數名稱,它的值都是不會變的。

但我們在寫腳本的時候,常常除了參數之外,也需要把算出來的數字,以一個名字來代表,以方便後續的撰寫,這個數字很可能會隨著回傳值的改變而改變。
例如我們我們可能常用range這個名詞來代表一根K棒的高低點落差,所以它的公式是range=high-low,這個range就是個變數, 當high是50,low是45時,range=50-45,這時候range的值是5,但當K棒的high的high變成51,low變成47時,這時候range=51-47, 這時候range的值就變成了4。

我們以前上數學課時,常常會用到y=x+1之類的式子,意思是y這個值會是多少,就看右邊的計算式而定,當x的值變了的時候, y就跟著變,這裡的y就是一個變數。

所以我們可以把變數看成是一個標示了名稱的盒子,放進去的內容隨時可以被換掉,但盒子的名稱沒有變。
變數的宣告

vr2

要完成一個變數在腳本上的作用,共有三步驟 :

1. 宣告

宣告的作用在於告訴電腦,這是一個變數,請把它當變數來看待。
它的語法是 :
Variable : 變數名稱(0);………0是一開始這變數的初始值,您也可以宣告它的初始值是5或者其他任何字。 變數除了可以是一個數值之外,它也可以是一個回傳是或非的布林值,所以您也可以宣告一個變數它的初始值是”是”
Variable:變數名稱(true);
由於我們常指定變數,因此,為了減少無謂的打字力氣,也可以在宣告時,用var替代variable。
例如我們可以用 var:range(0); 這代表我們告訴電腦,我宣告了一個變數,它的名字叫作range。
如果我們要宣告不只一個變數時,我們可以用以下的語法 :
Var:x1(0),x2(0),x3(0),x4(0);
用逗號來區別變數即可。

2. 指定

宣告完變數之後,我們要作的事情就是指定,就像把文件放到盒子裡的動作,我們必須指定變數的值是多少?
例如 :

Var:range(0);
Range=1;

又例如 :

Var:range(0);
Range=high-low;

3. 應用

接下來我們就可以把變數拿來作為腳本中很重要的一個元素,例如上面我們提到的最近三天震盪一天比一天大的陳述,就可以寫成 :

Var:range(0);
Range=high-low;
Range>range[1] and range[1]>range[2] and range[2]>rnage[3];

變數的資料格式
由於在腳本中,我們要處理的資料,其格式有如上圖的時間,文字,布林值及數字等四種,因此在變數的宣告時, 我們用不同的預設值,來告訴電腦我們宣告的變數格式。

1. 宣告數字變數

先前我們已經學到用 :
Variable:變數名稱(0);
這樣的方式來宣告這個變數的資料格式是數字,如果您不想花力氣作宣告,系統也提供了不需要事先宣告的變數供您使用, 這些變數的名稱是從value1到value99共99個不必宣告就能使用的變數
因此,你可以用AV20這個變數來代表收盤價的二十期移動平均,你可以這麼寫 :

VAR:AV20(0);
av20=average(close,20);

如果圖個方便,又不怕記不得變數代表的意思,也可以寫成 :

value1=average(close,20);

這樣您就不必經過宣告的動作也可以直接拿任何一個前面是value後面是阿拉伯字母1~99的變數來用就可以了。

2. 宣告字串變數

要宣告字串變數,可以把預設的字串直接用雙引號放在小括號中,
例如想宣告一個預設值為”我是一串文字”的字串 ,你可以這麼寫 :

Variable: x1 (“我是一串文字”);

電腦發現你宣告的變數預設值是一個字串,就知道這個變數是一個字串,所以如果這時候你寫出x1+1這樣的敘述式, 編譯的時候電腦會告訴你”+”左右兩邊的型態不同。

3. 宣告時間變數

要宣告時間變數時,由於XS中的時間跟日期,分別是六位數及八位數的數字,所以電腦一開始並無法從你的宣告中知道這個變數代表的是時間還是數字, 一開始會把它當數字,但當你拿這變數來用在時間函數上時,電腦會把它拿視為時間。所以如果您寫出以下的腳本 :

Var:x1(090000);
Var:x2(20131115);
Value1=x1+x2
If time>090000
Then print(value1);

這樣下去編譯時電腦是會過的,因為電腦把這兩個變數當成數字來處理。
但如果在使用的時候搭配的時間函數,電腦會把這數字按時間格式讀成特定的時間,例如091250就是早上九點十二分五十秒。
所以根據這樣的規則,我們可以把XS當成一個鬧鐘,例如我們希望電腦在九點半的時候提醒我,我們可以這麼寫:

VAR:X1(090000);
If timediff(time,x1,”m”)>30
Then ret=1;

Timediff是一個時間函數,可以用來計算兩個時間之間是差了多久,當電腦看到x1出現在timediff這個函數裡,它會把它視為是一個時間格式, 從的預設值就會被對應到其時間格式去。

4. 宣告布林值變數

要宣告布林值的變數,作法上只要預設值填上true或是false,電腦就知道你取的這個變數是個布林值的變數。宣告的格式如下 :

Variable:A1(True);

宣告A1這個變數是個布林值格式的變數,它的預設值為True

跟數值變數一樣,系統也提供了一組不必宣告就可以直接拿來用的變數名稱,由condition1一直到condition99。
condition1這樣的內建變數,在撰寫要符合多個條件時才觸發警示的腳本時,特別有用。

變數與參數的差異
作為一個初學者,我們常會不知道何時用input來宣告參數,何時用variable來宣告變數。
最直接的判斷方式,就是它的功用是什麼? 如果是用來指定一個絕對值,並且希望這個絕對值在您想要更動時, 不必進到腳本改動很多個地方(同一個值),那麼你需要的是用input來宣告參數。
但如果你需要的是用它來代表一串運算的結果,當運算結果改變時,這數值也會跟著改變,純粹是為了撰寫腳本時方便, 那麼你需要的是用variable來宣告變數。 例如以下的腳本 :

Input: X1(10); 設定X1這個參數的預設值是10
Input: X3(5); 設定X3這個參數的預設值是5
Var: X2(0); 設定一個變數X2,預設值是0
Var: X4(0); 設定一個變數X4,預設值是 0
X2=average(close,X1); 指定X2是以X1為天期的收盤價移動平均值
X4=average(close,X3); 指定X4是以X3為天期的收盤價移動平均值
If X4 cross over X2 then ret=1; 不同天期腳本出現黃金交叉時就觸發警示

以這個腳本來看,是當五日均線對十日均線出現黃金交叉時,電腦會觸發警示,如果我們想改成六日均線突破十二日均線時觸發警示, 那麼我們只要把X1的預設值改成12,把X3的預設值改成6就可以了。
從這個例子,我們應該就可以清楚的看到參數與變數的差別。

參數

我們在寫交易語法時,會用到一些常數, 如果我們直接把常數寫死在腳本中時,一旦要調整時, 要到腳本中去修改,這樣有時候不太方便,例如我如果寫了一個腳本想要找出收盤比前一天上漲5%以上的股票,但現在發現市場情況有些改變,想要改成上漲4%就出訊號,如果我必須進到編輯器裡去改,這時候如果程式寫的很長,要找到對的地方來改會很麻煩,改錯了,腳本就出錯了,這時候就可以用宣告參數的語法來處理,,讓我們直接在操作介面上就可以修改這個值,這個。

參數的宣告,用的語法如下:

input: length(5)

這代表我們在腳本上宣告了一個叫length的參數,這個參數系統內建的初始值為5

例如,我們要找跳空上漲1%的股票,原本我們會寫成 :
If Open/High[1]> 1+1/100
then ret=1;

但很可能改天我們會希望跳空上漲2%才通知我們,這時候怎麼辦呢? 我們可以把跳空上漲的百分比設成一個可以快速調整的參數, 使用者需要調整百分比時,只要更改這個數字即可,不必再進到腳本去修改數據。
例如上面的例子,就可以改寫成 :

input:no1(1);
If Open/Close[1]> 1+no1/100
then ret=1;

腳本如果改成這樣,當你要把跳空下跌超過1%改成2%時,只要調整參數值就行了。

我們也可以只宣告參數的型態,不需要一開始就給預設值,例如 :

input: length(numersimple) 代表這個參數是個簡單的數值
在設定參數時,我們用Input這樣的語法,不過如果我們參數設多了,就可能不記得那個參數是對應那個函數或那個指標, 這時候我們可以透過setinputname的語法,為每一個參數加上一段說明文字,它的語法如下:
Setinputname (n,”說明文字”);
在setinputname之後用小括號來包括兩個部份,n的部份代表的是第幾個參數,它的順序是按input語法在腳本中的先後順序而定, 要設定第一個input參數的說明文字時就填1,要說明第二個input就填2,以此類推。
在n的後面用逗點隔開說明文字,文字前後用雙引號來標示。請看以下的例子
input1

input2

透過setinputname的方式來設定參數名稱,當參數多的時候,就可以很清楚的看到每一個參數的名稱及其對應的內建值了,這時候要修改參數時就不會搞混了。

如果大家不想要這麼麻煩,也可以在input指令的預設值後面直接用雙引號來註明參數的名稱

例如 : input:priod(20,”計算期間”);

宣告參數是我們在撰寫腳本時,很常用的語法,大家務必要好好學會使用它。

函數

當我們有了開高低收成交量這些回傳值可以使用,也知道如何叫出時間序列上的每一根K棒來為我們利用來作運算之後, 很自然的,我們就可以計算出一個商品的其他有意義的數值。
例如 我們要計算五日移動平均,我們可以用以下腳本來表示 :

(close+close[1]+close[2]+close[3]+close[4])/5

所以如果要寫一個腳本是當股價突破五日移動平均時,請電腦通知我們,我們可以寫出以下的腳本 :

If close[1]<(close[1]+close[2]+close[3]+close[4]+close[5])/5 and close>(close+close[1]+close[2]+close[3]+close[4])/5
Then ret=1;

但在使用回傳值去運算一些數值時,如果我們就這麼平鋪直述的把運算過程寫出來,那麼當運算過程很繁複, 而我們要運算的次數又不只一次時,我們就會寫的很辛苦,而且很容易出錯。

例如上面的例子是五日移動平均,所以我們還可以close,close[1]…….的一直加上去,但如果是100日移動平均線, 那該怎麼辦呢?如果我們每次計算移動平均時,都得從第一根加到第n根再除以n,要是n大一點,那我們就會打字打到手酸。

所以在xscript上,我們加入一種叫作函數 的語法,這種語法讓我們可以把經常要計算的方法,用一個函數來表示, 例如5日收盤價的移動平均數我們可以直接寫成 average(close,5)
這樣上面的例子我們就可以改寫成 :

If average (close,5) [1] > close[1] and close > average (close,5)
Then ret=1;

在函數中,也不是收盤價才能拿來做為移動平均計算的價格,只要是每一根bar都會有的數值, 都可以拿來計算移動平均,連在這些回傳值基礎上計算出來的數值,也可以拿來用 。
函數的語法格式通常會有一個函數名稱,然後會有一個小括號,小括號裡頭會有回傳值(如上例中的close),會有一個或多個參數值(如上例中的5), 所以當您寫average(close,5)時,電腦知道您要的是收盤價的五期的移動平均值,如果您寫的是average(volume,100), 電腦會知道您要的是100期的移動平均量。

XS有把一些大家常用的運算方式都預先寫成函數,讓大家可以直接拿來使用,例如合計的概念,XS有提供一個 Summation的函數,它的語法是summation(價格,長度), 例如我們如果要算十日成交量的總合,我們可以寫成summation(volume,10),如果我們要計算最近五根K 棒的最高價平均,我們可以寫成

summation(high,5)/5

一百日均量,我們也可以寫成 :

Vlaue1=summation(volume,100)/100

其次,XS也把大家常用的指標做成函數,例如我們常用RSI,XS就也它預設成函數,所以如果你需要的是六日RSI突破十二日RSI,你只要直接寫 :

RSI (close,6) cross over RSI (close,12)

這樣就可以了。
另外有一種函數是用在兩個數值的比較的,這種函數後面不必帶回傳值及長度,直接把函數名稱擺在兩個數值中間就代表這兩個數值的關係, 我們在決定交易策略的時候,常會用到兩個專有名詞,一個叫黃金交叉 ,一個叫死亡交叉 。

黃金交叉的意思是有兩條線,當A線的前一個點比B線的前一個點低,但A 線的最近一點比B線的最近一點高,我們就稱為黃金交叉, 而其相反的情況就是死亡交叉,由於這兩種情況使用者實在太常用了,因此XS乾脆把這兩個都寫成預設的函數, 這種函數就是我們常說的黃金交叉及死亡交叉,這兩個函數的名稱分別為crossover 及crossunder。
在語法上如果A crossover B,代表A[1]<B[1]and A>B,也就是前一根K棒時,A值比B值低,但最近這根K棒時,A值已經變的比B值高, 也就是黃金交叉的意思,同樣的,如果A crossunder B,代表A[1]>B[1] and A < B 。
有了這兩個函數,上面的例子我們就可以寫成

RSI(close,6) crossover RSI(close,12)

一行敘述式就可以解決掉了。

換句話說,黃金交叉crossover的定義就是:
CrossOver = lineA > lineB and lineA[1] <= lineB[1];

而死亡交叉的話,我們用crossunder來表示 :
CrossUnder = lineA < lineB and lineA[1] >= lineB[1];

有了這兩個函數之後,當我們要寫兩個數值出現黃金交叉時,我們只要寫 A Crossover B就是A對 B出現黃金交叉, 相反的,當 A Crossunder B代表的就是A對B出現死亡交叉。
Crossunder與 Crossover串聯起來的這個述敘是一個邏輯判斷式,電腦會去判斷它是true還是false。
例如我們想要電腦在個股突破五日均線時發出警示,我們可以寫一個腳本如下:

If close crossover average(close,5)
Then ret=1;

當電腦在跑這個腳本時,如果引進來計算的商品符合close crossover average(close,5),也就是close crossover average(close,5), 這個敘述為true時,系統就會啟動觸發通知。
XS所支援的函數頗多,在腳本編輯器上的選單”說明”項下,有一個”使用說明”的選項,按這個選項或直接按F1,就可以直接連到說明的網頁。

輸出語法

在撰寫語法的過程中,我們一行行的寫著敘述式,希望電腦照著我們的意思,拿著開高低收成交量這些數據去運算,運算總會有個結果, 我們會希望電腦根據這個結果,幫我們做點什麼,這裡說的什麼,就是電腦運算中所謂的輸出。
在XS的語法裡,輸出的方式,除了透過交易語法,進行自動化交易之外,還有幾種輸出的功能,分別如下表 ,茲分述如下

07_輸出語法_1
output

一,PlotN

Plot是在自設指標的時候用的,當我們寫了一個腳本之後,腳本的最後輸出基本上是分兩大部份, 一種是根據腳本把一個數值畫成一個自訂的指標,另一種則是在數值符合某種情況時,請電腦通知我們某商品已符合某條件這樣的警示訊息。 Plot就是用來請電腦幫我們把某數值繪成指標的語法。
OUTPUT1

例如 :
我們如果要把每天的收盤價繪製成一條線
我們可以寫plot1(close);
我們也可以在要繪圖的數值後面用逗號及引號來加註這數值
我們可以寫plot1(close,”收盤價”)
如果要畫兩條線,我們可以一條用 plot1,另一條則是plot2
例如以下的範例,如果我們想要畫兩條線,一條呈現K棒的總長度,另一條顯示K棒的實體長度,我們可以寫下以下的腳本 :

OUTPUT2

然後幫這個腳本取名為 ”K棒長度”
這樣子我們在XQ技術分析的頁面中,就可以透過選取自訂指標的方式,選取K棒長度這個腳本來繪圖,然後您就會看到如以下的圖形, 所以透過腳本的撰寫,你可以算出各式各樣的數值,然後透過PlotN這樣的語法,把這些數值一條一條畫在XQ技術分析的自訂指標中。OUTPUT3

二,RetVal

除了繪圖之外,其實最常用的是把腳本應用在警示上,讓電腦在運算後符合某種條件時,發出通知訊號,我們總是希望電腦在股票符合什麼條件的時候通知我們,這時候就用得上這個語法。
它的語法格式如下 :
Retval=1 或 retval=0
我們可以簡寫為 :
ret=1 或ret=0
Retval是return value的簡寫,XS的語法設定當Retvalue=1時電腦會觸動警示,所以如果你希望台積電股價突破150元時電腦可以通知您,就可以寫出以下的腳本 :
If close>150 then ret=1;
If …….then ret=1; 是很標準的警示觸發條件的撰寫格式。

三,Print
除了繪圖及警示之外,有時為了撰寫腳本時的除錯,校對資料 或是研究用,我們需要輸出特定的數值,這時候就需要print這個語法,它的語法格式如下:

OUTPUT4

例如我們想知道電腦今天有沒有把最新成交的數據送進來,我們就可以寫出以下的腳本 :

Print(CurrentDate,Open,High,Low) // 輸出 日期 開盤價 最高價 最低價

然後當我們拿這腳本去用台積電執行腳本時,在XS程式的PRINT檔案夾中,會有一個test_2330.TW………的文字檔, 當你打開這個檔案時,會出現像下面附圖之類的文字
OUTPUT5
電腦依據你要求的PRINT指令,把日期及開盤,最高,最低都印了出來。
Print這個功能,主要是可以拿來作研究用,舉個例子 :
如果我們想知道用RSI黃金交叉來作為台積電的買進訊號,隔天上漲的機率高不高? 我們可以寫一個腳本 :
OUTPUT6
然後在進階警示清單的介面上,用台積電這檔股票去跑最近300筆資料,系統會在 sysjust/XQ2005/XS/Print的目錄底下, 跑出一個文字檔,如果用excel去打開,可以看到如下圖的一個表 :

OUTPUT7

這個表就是根據我們要求的print格式所列出來的三個欄位,最右邊那一欄就是符合前一日rsi黃金交叉條件的當天收盤價減前一日收盤價的值, 從這個表我們可以看得出來,在出現rsi黃金交叉之後的隔天,台積電股價並沒有太高的上漲機率,所以我們大概可以了解, 如果在rsi出現黃金交叉時隔天進場買台積電,並不會賺到錢。
Print的功能主要就是可以自己訂定輸出的格式,這對作研究及想要改進腳本的人,是個很有用的功能,特別是現在在python上有非常多人工智慧的套件,我們可以透過print的功能,把透過XS語法計算出來的數據,拿到Python平台的 AI套件上去訓練模型。

四,RaiseRun TimeError

在撰寫腳本時,有時候當數據如果錯誤時,程式會出現錯誤,例如當除數是零的時候,這時候電腦就很容易卡在那邊, 或者有些腳本只適合日線,如果用在分鐘線,就可能要算很久且出來的結果也不能用,這時候這個Raiseruntimeerror就是一個很好用的輸出語法, 可以馬上通知電腦中斷執行,這樣就不會出現電腦當機之類的意外情況。其語法格式如下:

OUTPUT8

這個語法是在raiseruntimeerror這個字的後面加一個小括號,然後把想要輸出的文字用雙引號寫下來, 放在括號裡,當條件符合的時候,電腦會輸出雙引號通知使用者。
例如當我們要寫一個只適用在一分鐘線的腳本時,我們第一行可以像下面這樣寫 :

if barfreq <> "Min" or barinterval <> 1 then RaiseRunTimeError ("請設定頻率為1分鐘");

這麼一來,如果頻率不是設定為1分鐘線時,電腦一讀到這一行就會直接中止執行這個腳本,這樣就可以避免電腦執行一個不適於其他頻率的腳本。
例如我們用五分鐘線在台積電這個檔股票執行上面那一行敘述,電腦就會出現以下的訊息
OUTPUT9

常數

有了回傳值,運算子及標點符號,就可以組成陳述式。
例如: 如果我們想在商品跳空開高時電腦要通知我們,我們可以寫下以下的陳述式 :

Open>high[1]

但今天的開盤價要比前一開高點跳空多少你覺得才是你要的呢? 1%? 2%
這時候我們可以把一些數字加進來,我們可以寫成 :

Open/high[1]>=1/100

這一行的陳述式就變成不只跳空開高,而且最少要開高1%,在這邊,我們的腳本引用了兩個阿拉伯數字,一個是”1”,一個是”100”, 這兩個數字,不管open是多少,也不管high是多少,1就是1,100就是100,這樣的數字我們稱之為常數 。Djscript讀得懂的常數除了阿拉伯數字之外, 另外就是true 跟false 這兩個邏輯上常被拿來使用的字詞。
所以學到這邊,我們可以用回傳值、運算子、符號及常數來組成一個陳述式,例如可以寫一行陳述式如下 :

(High-low)/(high[1]-low[1])>1

這一個陳述式的意思是今天的震盪區間比前一天大。
Constant 為常數,使用者無法變動,但是可以使用,就像1,1就是1,永遠不會變。

標點符號

在學會使用回傳值及運算子之後,要完成一個敘述式,還必須要用到一些標點符號,這樣才能完整的完成一個電腦看得懂的敘述式。
完整的標點符號及其用途分別如下,有些我們目前還用不著,例如宣告參數及變數所用的冒號,但先了解一下電腦看得懂的標點符號及其用途是有必要的, 因為電腦是很死板的,它是死腦筋,該在腳本出現的每個標點符號,少一個不行,多一個也不行。

作為腳本註解的標點符號
這當中要特別說明的是 // 及{ } 這兩個拿來當註解用的符號,// 代表的是在這個符號後面那一行的文字全部會被電腦給忽略, 所以可以拿來當註解,{ } 大引號則是不管出現在那裡,有多少行,只要出現了,在兩個引號中間的所有內容,電腦都忽略。
所以如果只是在一行敘述式後面加上說明可以用 // ,但如果是一整段的敘述式要請電腦不要讀的話用{ } 大引號比較方便。

只要是 // 以後的同一行文字數字電腦都忽略,可用來當一行敘述式的註解
如果把 // 放在一行敘述式的最前面,就算後面照著語法寫,電腦還是會忽略 。
如果我們嫌 // 的後面的文字太長,一行寫不下,換行時,如果前面不再加個 // ,電腦會視為這是一行新的敘述式,會去讀它 , 這時編譯時也會發生錯誤。

但如果我們用 { } , 在大引號中間的所有文字電腦都視為註解,編譯時就不會理會這中間的內容了。

到這邊已經學會基本的程式交易語法內容了,我們不妨試著寫出幾個腳本
例如 以下的這個 :

volume > volume[1] and
volume[1] > volume[2] and
close < close[1] and
close[1] < close[2] and
close < open and
close[1] < open[1] and
close[2] < open[2]

這樣的寫法要表達的是 :
1. 前日量小於昨日,而昨日小於今日
2. 收盤價是今日小於昨日,且昨日小於前日
3. 今日收黑,昨日收黑且前日亦收黑
再例如以下的這個腳本 :

Close=open and close=high
And (high-low)>(high[1]-low[1]*2

這就是江湖人稱的蜻蜓十字 :
蜻蜓十字線
蜻蜓十字線

要符合這樣的K線型態有幾個要素 :
1.收盤價等於開盤價且是當天最高點 close=open and close=high
2.最近一根bar的下影線是前一根bar 高低點的兩倍以上 (high[0]-low[0])>(high[1]-low[1] *2

回傳值,運算子及標點符號,是組成腳本的最基本元素,學到這裡,算是最基礎的語法結構我們都學完了。