Multicharts 函数

  • 函數(Function)
    • 定義(實作)函數
      • 新增一個函數腳本
      • 撰寫功能和編譯
      • 參數型別
    • 使用(呼叫)函數
      • Example
    • Passing By Value和Passing By Reference
      • Passing by value
      • Example
      • Passing by reference
      • Example
    • Reference

函數跟參數和變數一樣,可以想像成是一個容器,只是這個容器裡面放的不是數值,而是一連串的程式碼,當我們想要重複使用這段程式碼時,可以不用全部重寫一次,只需要使用函數名稱,程式在執行到函數名稱的時候,就會知道要去執行對應的程式碼。
通常會將常用到的功能寫成函數,這樣就不用每次同樣的計算或功能的都要重寫,只需要使用對應的函數名稱就可以了。

函數跟參數和變數一樣,也分成兩個階段:
第一個階段稱作定義(實作): 將想要當作函數使用的程式碼寫好和編譯。
第二個階段是使用(呼叫): 使用函數名稱和給予參數值,當程式執行到函數名稱時,就會代入參數值和執行對應的程式碼。

定義(實作)函數

新增一個函數腳本

PowerLanguage Editor->檔案->開新檔案->函數

Multicharts 函数

回傳類型就是型別,分成數值(數值型別)、TrueFalse(真假值型別)、字串(字串型別),詳見型別。
函數儲存進一步決定回傳類型是簡單數值(NumericSimple)還是時序數值(NumericSeries)、簡單真假值(TrueFalseSimple)還是時序真假值(TrueFalseSerise)、簡單字串(StringSimple)還是時序字串(StringSeries),詳見型別。

Multicharts 函数

撰寫功能和編譯

函數腳本除了參數(inputs)語法不一樣和多了回傳語法之外,其他的語法: 變數、分支、迴圈、陣列和註解都和訊號與指標腳本的寫法一樣。

函數的參數和訊號指標或指標腳本的參數不一樣,無法從Multicharts傳入參數值。在使用(呼叫)函數時,將數值傳入給函數的參數。

函數腳本寫好後需要進行編譯,編譯成功後,就可以使用自己寫的函數。

函數腳本的語法框架

[inputs: InputName1(InputType), InputName2(InputType)...;]
//Write Functionality

[FunctionName=ReturnValue;]

where
inputs: 宣告參數。
InputName: 參數的名稱。
InputType: 參數的型別,見下表 函數的參數型別
Functionality: 函數的功能。
FunctionName: 指示這個函數的回傳值為ReturnValue

參數型別

Numeric系列
NumericSimple 意義 宣告input型別是Numeric Simple。
宣告為Simple的參數,數值在每一根K棒都一樣,因此沒有歷史數值。
語法 Input: InputName(NumericSimple);
Example Input: Length(NumericSimple);
NumericSeries 意義 宣告input型別是Numeric Series。
宣告為Series的參數,數值會隨K棒可能不同,因此有歷史數值可以參照。
語法 Input: InputName(NumericSeries)
Example Input: Price(NumericSeries);
Numeric 意義 宣告input型別是Numeric。
傳入參數為NumericSimpleNumerisSeries
語法 Input: InputName(Numeric)
Example Input: Length(Numeric);
NumericRef 意義 宣告input型別是Passing by Reference Numeric。
傳入的參數值如果在函數中有被修改,函數執行結束後,參數值為修改值,見Passing by reference
語法 Input: InputName(NumericRef)
Example Input: BarCount(NumericRef);
NumericArray 意義 宣告input型別是Numeric Array。
傳入指定大小和維度的Numeric Array。
語法 Input: InputName[M1,M2,M3,etc.](NumericArray)
where
InputName – 參數的名稱。
– 陣列每個維度的最大索引值。
Example Input: Table[X,Y,Z](NumericArray);
X、Y、Z值為傳入的陣列的每個對應維度的最大索引值。
NumericArrayRef 意義 宣告input型別是Passing by Reference Numeric Array。
傳入指定大小和維度的Numeric Array。
傳入的參數值如果在函數中有被修改,函數執行結束後,參數值為修改值,見Passing by reference
語法 Input: InputName[M1,M2,M3,etc.](NumericArrayRef)
where
InputName – 參數的名稱。
– 陣列每個維度的最大索引值。
Example Input: Table[X,Y,Z](NumericArrayRef);
X、Y、Z值為傳入的陣列的每個對應維度的最大索引值。
String系列
StringSimple 意義 宣告input型別是String Simple。
宣告為Simple的參數,數值在每一根K棒都一樣,因此沒有歷史數值。
語法 Input: InputName(StringSimple)
Example Input: Name(StringSimple);
StringSeries 意義 宣告input型別是String Series。
宣告為Series的參數,數值會隨K棒可能不同,因此有歷史數值可以參照。
語法 Input: InputName(StringSeries)
Example Input: Messages(StringSeries);
String 意義 宣告input型別是String。
傳入參數為StringSimpleStringSeries
語法 Input: InputName(String)
Example Input: Name(String);
StringRef 意義 宣告input型別是Passing by Reference String。
傳入的參數值如果在函數中有被修改,函數執行結束後,參數值為修改值,見Passing by reference
語法 Input: InputName(StringRef)
Example Input: Message(StringRef);
StringArray 意義 宣告input型別是String Array。
傳入指定大小和維度的String Array。
語法 Input: InputName[M1,M2,M3,etc.](StringArray)
where
InputName – 參數的名稱。
– 陣列每個維度的最大索引值。
Example Input: MessageTable[X,Y,Z](StringArray);
X、Y、Z值為傳入的陣列的每個對應維度的最大索引值。
StringArrayRef 意義 宣告input型別是Passing by Reference String Array。
傳入指定大小和維度的String Array。
傳入的參數值如果在函數中有被修改,函數執行結束後,參數值為修改值,見Passing by reference
語法 Input: InputName[M1,M2,M3,etc.](StringArrayRef)
where
InputName – 參數的名稱。
– 陣列每個維度的最大索引值。
Example Input: CommentsTable[X,Y,Z](StringArrayRef);
X、Y、Z值為傳入的陣列的每個對應維度的最大索引值。
TrueFalse系列
TrueFalseSimple 意義 宣告input型別是TrueFalse Simple。
宣告為Simple的參數,數值在每一根K棒都一樣,因此沒有歷史數值。
語法 Input: InputName(TrueFalseSimple)
Example Input: Overnight(TrueFalseSimple);
TrueFalseSeries 意義 宣告input型別是TrueFalse Series。
宣告為Series的參數,數值會隨K棒可能不同,因此有歷史數值可以參照。
語法 Input: InputName(TrueFalseSeries)
Example Input: UpTrend(TrueFalseSeries);
TrueFalse 意義 宣告input型別是TrueFalse。
傳入參數為TrueFalseSimpleTrueFalseSeries
語法 Input: InputName(TrueFalse)
Example Input: Overnight(TrueFalse);
TrueFalseRef 意義 宣告input型別是Passing by Reference TrueFalse。
傳入的參數值如果在函數中有被修改,函數執行結束後,參數值為修改值,見Passing by reference
語法 Input: InputName(TrueFalseRef)
Example Input: Flag(TrueFalseRef);
TrueFalseArray 意義 宣告input型別是TrueFalse Array。
傳入指定大小和維度的TrueFalse Array。
語法 Input: InputName[M1,M2,M3,etc.](TrueFalseArray)
where
InputName – 參數的名稱。
– 陣列每個維度的最大索引值。
Example Input: FlagTable[X,Y,Z](TrueFalseArray);
TrueFalseArrayRef 意義 宣告input型別是Passing by Reference TrueFalse Array。
傳入指定大小和維度的TrueFalse Array。
傳入的參數值如果在函數中有被修改,函數執行結束後,參數值為修改值,見Passing by reference
語法 Input: InputName[M1,M2,M3,etc.](TrueFalseArrayRef)
where
InputName – 參數的名稱。
– 陣列每個維度的最大索引值。
Example Input: TrendTable[X,Y,Z](TrueFalseArrayRef);

使用(呼叫)函數

FunctionName(input1, input2, ...);

where
FunctionName: 要使用的函數名稱。
input: 呼叫函數時,要傳給參數的值,又稱作引數

Example

內建的函數: AerageFC
檔案->開啟檔案->函數(checkbox打勾)->AverageFC

inputs: 
	PriceValue( numericseries ), 
	Len( numericsimple ) ;                                                         
	                                     

AverageFC = SummationFC( PriceValue, Len ) / Len ;

AverageFC本身是函數實作,同時也呼叫另一個函數SummationFC完成實作功能。
AverageFC函數宣告兩個參數,一個叫PriceValuenumericseries型別,一個叫Lennumericsimple型別。
接著,呼叫SummationFC函數做計算,PriceValueLen作為引數傳給SummationFC的參數。
最後,AverageFC回傳SummationFC計算後的結果除以Len

Passing By Value和Passing By Reference

在呼叫函數時,放在參數位置、要傳入給參數的值稱作引數,引數傳給參數的方式分成Passing by valuePassing by reference兩種。

Passing by value

沒有Ref結尾的參數型別,引數傳給參數的方式用Passing By Value:
NumericSimple、NumericSeries、Numeric、NumericArray、StringSimple、StringSeries、String、StringArray、TrueFalseSimple、TrueFalseSeries、TrueFalse、TrueFalseArray。

用Passing by value的方式將引數的值傳給函數的參數時,函數的參數會有自己的記憶體位置,程式會將引數值複製和存到函數參數的記憶體位置,在函數中無法改變宣告為Passing By Value的參數值,如果嘗試改變Passing By Value的參數值,會造成compile error: Array, variable or refinput expected
如下範例: 引數值為12,存在記憶體0x1000位置,程式會將引數值12複製和存到函數參數的記憶體位置0x1004。

  Memory
   address value
引數–> 0x1000 12
函數的參數–> 0x1004 12

Example

swapByValFunc函數的參數ValueA(NumericSimple)ValueB(NumericSimple)Passing By Value,第6行和第7行嘗試改變ValueAValueB的值,造成compile error: Array, variable or refinput expected

函數: swapByValFunc

inputs: ValueA(NumericSimple),  ValueB(NumericSimple);
Print("In sawpFunc, before swap ValueA: ", ValueA, ", ValueB: ", ValueB);

temp = ValueA;
ValueA = ValueB; //compile error: Array, variable or refinput expected
ValueB = temp; //compile error: Array, variable or refinput expected

Print("In sawpFunc, after swap ValueA: ", ValueA, ", ValueB: ", ValueB);

Passing by reference

Ref結尾的參數型別,引數傳給參數的方式用Passing By Reference:
NumericRef、NumericArrayRef、StringRef、StringArrayRef、TrueFalseRef、TrueFalseArrayRef。

用passing by reference的方式將引數的值傳給函數的參數時,函數的參數是使用引數的記憶體位置,由於和引數存取同一個記憶體位置上的值,當改變函數的參數值時,也會改變引數值。
如下範例: 引數值為12,存在記憶體0x1000位置,函數的參數是使用引數的記憶體位置0x1000得到參數值12。

  Memory
   address value
引數–>
函數的參數–>
0x1000 12

Passing by reference最多的應用就是拿來當函數的輸出,由於PowerLanguage的函數語法,一個函數只有一個回傳值,因此一個函數只有一個輸出,當函數需要有多個輸出的情形時,就可以使用Passing by reference的方式。

Example

範例testSwapFunc訊號呼叫swapByRefFunc函數,swapByRefFunc會將輸入的ValueAValueB的值互換,因為swapByRefFunc的參數: ValueA(NumericRef)ValueB(NumericRef)Passing by reference,因此呼叫swapByRefFunc結束後,testSwapFuncValueAValueB會得到互換後的值。

呼叫Print來將ValueAValueB的值印出,從Output可以看到在呼叫swapByRefFunc函數後,ValueAValueB的值互相交換。

訊號: testSwapFunc

var: ValueA(12),  ValueB(34);

//ValueA:   12.00, ValueB:   34.00
Print("Before call swap, Func, ValueA: ", ValueA, ", ValueB: ", ValueB);

swapByRefFunc(ValueA, ValueB);

//ValueA:   34.00, ValueB:   12.00
Print("After call swap, Func, ValueA: ", ValueA, ", ValueB: ", ValueB);

函數: swapByRefFunc

inputs: ValueA(NumericRef),  ValueB(NumericRef);
var: temp(0);

//ValueA:   12.00, ValueB:   34.00Print("In sawpFunc, before swap ValueA: ", ValueA, ", ValueB: ", ValueB);
//swap ValueA and ValueB
temp = ValueA;
ValueA = ValueB;
ValueB = temp;
//ValueA:   34.00, ValueB:   12.00Print("In sawpFunc, after swap ValueA: ", ValueA, ", ValueB: ", ValueB);

Reference

https://www.multicharts.com/trading-software/index.php?title=Category:Declaration

https://www.multicharts.com/trading-software/index.php?title=Passing_values_to_and_from_a_function