MultiCharts | PowerLanguage語法教學 | CH8:函數(Function)

函數(Function)

函數跟參數和變數一樣,可以想像成是一個容器。
然而,這個容器不是用來存放值,而是用來存放一段旨在執行特定任務的程式碼。
它可以接受輸入參數,處理這些參數,並返回結果。
通常會將常用的功能寫成函數,這樣就不用每次同樣的計算或功能的都要重寫,只需要使用對應的函數名稱。

函數,跟參數和變數一樣,也分成兩個階段:

  • 第一個階段稱作定義(實作): 將想要當作函數使用的程式碼寫好和編譯。
  • 第二個階段是使用(呼叫): 使用函數名稱和提供參數給函數。

定義(實作)函數

新增一個函數腳本

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

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

撰寫功能和編譯

函數腳本的語法框架

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

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

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

寫完函數後,你需要編譯它:

  • 點擊編譯按鈕以編譯函數程式碼。
  • 如果沒有錯誤,你的函數,之後就可以在訊號或指標腳本中使用。

函數的參數型別

Numeric

Numeric
NumericSimple意義宣告input型別是Numeric Simple。
宣告為Simple的參數,數值在每一根K棒都一樣,因此沒有歷史數值。
語法Input: InputName(NumericSimple);
ExampleInput: Length(NumericSimple);
NumericSeries意義宣告input型別是Numeric Series。
宣告為Series的參數,數值會隨K棒可能不同,因此有歷史數值可以參照。
語法Input: InputName(NumericSeries)
ExampleInput: Price(NumericSeries);
Numeric意義宣告input型別是Numeric。
傳入參數為NumericSimpleNumerisSeries
語法Input: InputName(Numeric)
ExampleInput: Length(Numeric);
NumericRef意義宣告input型別是Passing by Reference Numeric。
Passing by reference:如果在函數中改變了參數的值,則引數的值也會隨之改變。
語法Input: InputName(NumericRef)
ExampleInput: BarCount(NumericRef);
NumericArray意義宣告input型別是Numeric Array。
語法Input: InputName[M1,M2,M3,etc.](NumericArray)
where
InputName – 參數的名稱。
– 一個輸入變數,代表傳入陣列的每個維度的最大索引值。
ExampleInput: Table[X,Y,Z](NumericArray);
X、Y、Z值為傳入的陣列的每個對應維度的最大索引值。
NumericArrayRef意義宣告input型別是Passing by Reference Numeric Array。
Passing by reference:如果在函數中改變了參數的值,則引數的值也會隨之改變。
語法Input: InputName[M1,M2,M3,etc.](NumericArrayRef)
where
InputName – 參數的名稱。
– 一個輸入變數,代表傳入陣列的每個維度的最大索引值。
ExampleInput: Table[X,Y,Z](NumericArrayRef);
X、Y、Z為傳入的陣列的每個對應維度的最大索引值。

String

String
StringSimple意義宣告input型別是String Simple。
宣告為Simple的參數,數值在每一根K棒都一樣,因此沒有歷史數值。
語法Input: InputName(StringSimple)
ExampleInput: Name(StringSimple);
StringSeries意義宣告input型別是String Series。
宣告為Series的參數,數值會隨K棒可能不同,因此有歷史數值可以參照。
語法Input: InputName(StringSeries)
ExampleInput: Messages(StringSeries);
String意義宣告input型別是String。
傳入參數為StringSimpleStringSeries
語法Input: InputName(String)
ExampleInput: Name(String);
StringRef意義宣告input型別是Passing by Reference String。
Passing by reference:如果在函數中改變了參數的值,則引數的值也會隨之改變。
語法Input: InputName(StringRef)
ExampleInput: Message(StringRef);
StringArray意義宣告input型別是String Array。
語法Input: InputName[M1,M2,M3,etc.](StringArray)
where
InputName – 參數的名稱。
– 一個輸入變數,代表傳入陣列的每個維度的最大索引值。
ExampleInput: MessageTable[X,Y,Z](StringArray);
X、Y、Z值為傳入的陣列的每個對應維度的最大索引值。
StringArrayRef意義宣告input型別是Passing by Reference String Array。
Passing by reference:如果在函數中改變了參數的值,則引數的值也會隨之改變。
語法Input: InputName[M1,M2,M3,etc.](StringArrayRef)
where
InputName – 參數的名稱。
– 一個輸入變數,代表傳入陣列的每個維度的最大索引值。
ExampleInput: CommentsTable[X,Y,Z](StringArrayRef);
X、Y、Z值為傳入的陣列的每個對應維度的最大索引值。

TrueFalse

TrueFalse
TrueFalseSimple意義宣告input型別是TrueFalse Simple。
宣告為Simple的參數,數值在每一根K棒都一樣,因此沒有歷史數值。
語法Input: InputName(TrueFalseSimple)
ExampleInput: Overnight(TrueFalseSimple);
TrueFalseSeries意義宣告input型別是TrueFalse Series。
宣告為Series的參數,數值會隨K棒可能不同,因此有歷史數值可以參照。
語法Input: InputName(TrueFalseSeries)
ExampleInput: UpTrend(TrueFalseSeries);
TrueFalse意義宣告input型別是TrueFalse。
傳入參數為TrueFalseSimpleTrueFalseSeries
語法Input: InputName(TrueFalse)
ExampleInput: Overnight(TrueFalse);
TrueFalseRef意義宣告input型別是Passing by Reference TrueFalse。
Passing by reference:如果在函數中改變了參數的值,則引數的值也會隨之改變。
語法Input: InputName(TrueFalseRef)
ExampleInput: Flag(TrueFalseRef);
TrueFalseArray意義宣告input型別是TrueFalse Array。
語法Input: InputName[M1,M2,M3,etc.](TrueFalseArray)
where
InputName – 參數的名稱。
– 一個輸入變數,代表傳入陣列的每個維度的最大索引值。
ExampleInput: FlagTable[X,Y,Z](TrueFalseArray);
X、Y、Z值為傳入的陣列的每個對應維度的最大索引值。
TrueFalseArrayRef意義宣告input型別是Passing by Reference TrueFalse Array。
Passing by reference:如果在函數中改變了參數的值,則引數的值也會隨之改變。
語法Input: InputName[M1,M2,M3,etc.](TrueFalseArrayRef)
where
InputName – 參數的名稱。
– 一個輸入變數,代表傳入陣列的每個維度的最大索引值。
ExampleInput: TrendTable[X,Y,Z](TrueFalseArrayRef);
X、Y、Z值為傳入的陣列的每個對應維度的最大索引值。

使用(呼叫)函數

FunctionName(input1, input2, ...);
  • 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

引數(Argument)

引數是呼叫函數時,放在函數參數位置,傳給函數使用的值。

引數傳給函數使用的機制有兩種:

  • Passing by Value
  • Passing by Reference

Passing by Value

沒有Ref結尾的參數型別,引數傳給函數的機制使用Passing By Value

使用Passing By Value機制的函數參數,在函數實作中不能改變參數的值。
如果嘗試在函數中改變參數的值,會造成compile error: Array, variable or refinput expected

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

使用Passing By Reference機制的函數參數,在函數實作中可以改變參數的值。
如果在函數中改變參數的值,則引數的值也會跟著改變。

Passing by reference的應用是讓函數有多個輸出。
因為原本的函數語法只有一個回傳值,所以一個函數只有一個輸出。
如果需要函數有多個輸出時,可以使用Passing by reference機制達成。

Example

函數: swapByRefFunc的參數ValueA(NumericRef)ValueB(NumericRef)Passing by Reference
函數: swapByRefFunc將參數ValueAValueB的值進行互換。
訊號: testSwapFunc呼叫PrintValueAValueB的值印出,可以看到在呼叫swapByRefFunc後,ValueAValueB的值互換了。

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

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

訊號: 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);

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

發佈留言