請問小編自動交易中心問題

  •   696 
  • 最後發表   TM  2025 五月 05
TM 發文於   2025/04/28

請問原本策略再回測及盤前啟動都正常可以商品監控,但是剛剛盤中停止後啟動,出現大部分商品 1404,少部分商品是可以啟動。請問是否發行張數的資料有問題啊?

排序方式: 標準 | 最新
虎科大許教授 發文於   2025/04/28

交易腳本或警示腳本使用像是發行張數這種盤中還沒更新的欄位資料,會出現錯誤,改成GetField("發行張數(張)",“D”)[1]應該就可以。

TM 發文於   2025/04/28

謝謝教授!!!

我盤中試過 GetField("發行張數(張)",“D”)[1], 當時是有錯誤改[5]也錯,顯示的是缺少資料,現在收盤剛剛試教授給的GetField("發行張數(張)",“D”)[1] 又正常了

因為我是想算盤中的換手率請問用哪一種寫法比較好?

XQ給的換手率指標的寫法

if barfreq = "Tick" or barfreq = "Min"

then raiseruntimeerror("不支援此頻率");

if GetField("發行張數(張)") <> 0 then begin

value1 = volume / GetField("發行張數(張)") * 100;

plot1(value1,"週轉率(%)");

end else 

noplot(1);

我改成這樣來用

if barfreq = "Tick" or barfreq = "Min"

then raiseruntimeerror("不支援此頻率");

if GetField("發行張數(張)")[1] <> 0 then begin

Tuneoverratio = GetField("成交量", "D") / GetField("發行張數(張)")[1] * 100;

 

end;

 

還是我可以接用 Tuneoverratio = TurnOverRate(1); 比較好呢? 謝謝協助!!

虎科大許教授 發文於   2025/04/28

改成下列的寫法會比較好:

if GetField("發行張數(張)", "D")[1] <> 0 then begin

Tuneoverratio = GetField("成交量", "D") / GetField("發行張數(張)", "D")[1] * 100;

TM 發文於   2025/04/28

好的,受益良多,謝謝教授。

TM 發文於   2025/04/29

請問原本回測正常,盤前也都正常地監控,開盤後又出現資料不足地錯誤訊息,請問該怎麼處理啊?  已經改成 GetField("成交量", "D") / GetField("發行張數(張)", "D")[1] * 100; 了

附加文件

虎科大許教授 發文於   2025/04/29

應該是程式碼當中還有沒寫好的部份。

TM 發文於   2025/04/29

目前有用到的函數是這些,不知道那些跟盤中有關啊? 是否可以請教授幫忙指導一下是哪裡出問題? 建議可以怎麼調整? 剛學實在沒有頭緒,非常感謝!

// === 觸頂判斷 ===

// --------------------------------------------------------------------

variable: theHigh(0);             // 過去 Length 期內的最高價

variable: HighLowerBound(0);      // 頂部區間下界

variable: TouchRangeTimes(0);      // 期間中進入頂部區間的次數

 

theHigh = Highest(High[1], Length);               // 找到過去 Length 期內的最高價

HighLowerBound = theHigh * (100 - RangeRatio) / 100;  // 設定頂部區間下界

 

// 計算過去 Length 期內,股價進入頂部區間的次數

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

 

// 如果觸及頂部區間的次數達到設定值,且當前價格突破最高價,則觸發觸頂訊號

if TouchRangeTimes >= HitTimes and (GetField("AskPrice", "Tick") > theHigh or close > theHigh) then

    TouchTop = 1;

 

// === 周轉率計算 ===

// --------------------------------------------------------------------

if barfreq = "Tick" or barfreq = "Min" then

    raiseruntimeerror("不支援此頻率");  // 不支援 Tick 和 Min 頻率

if GetField("發行張數(張)", "D")[1] <> 0 then

begin

    Tuneoverratio = GetField("成交量", "D") / GetField("發行張數(張)", "D")[1] * 100;  // 計算周轉率

end;

 

// === 大戶買賣力金額計算 ===

// --------------------------------------------------------------------

value1 = GetField("賣出特大單金額", "D") + GetField("賣出大單金額", "D");  // 賣出大單金額

value2 = GetField("買進特大單金額", "D") + GetField("買進大單金額", "D");  // 買進大單金額

Largeaccountmoney = value2 - value1;  // 大戶買賣力金額

 

// === 取得報價資訊 ===

// --------------------------------------------------------------------

currentPrice = GetField("close");        // 取得當前收盤價

closePrice = CloseD(1);                   // 取得昨日收盤價

highToday = GetField("High", "D");         // 取得今日最高價

volume_ = GetField("成交量", "D");           // 取得今日成交量

 

// 計算近 5 日平均成交量

avgVolume5 = (GetField("Volume", "D")[1] + GetField("Volume", "D")[2] + GetField("Volume", "D")[3] + GetField("Volume", "D")[4] + GetField("Volume", "D")[5]) / 5;

highest120 = Highest(GetField("High", "D"), 120);   // 取得近 120 日最高價

increaseRate = (currentPrice - closePrice) / closePrice * 100;  // 計算漲幅

avgEntryPrice_ = FilledAvgPrice;                    // 取得平均進場價格

 

entryDate_ = FilledEntryDate;  // 取得進場日期

currentDate_ = Date;           // 取得當前日期

 

虎科大許教授 發文於   2025/04/29

你若友善一點,願意對所有變數進行宣告,再貼上來,也許可幫忙測試看看問題所在。

TM 發文於   2025/04/29

許教授不好意思喔,我以為問題在用的函數有問題所以放的是有用到的,我整個放上來請您幫忙看看有什麼地方有問題,再請您指點一下,謝謝您。

 // === 變數宣告 ===

// --------------------------------------------------------------------

var: TouchTop(0);           // 是否觸及頂部 (1: 是, 0: 否)

var: Tuneoverratio(0);      // 周轉率 (%)

var: Largeaccountmoney(0);   // 大戶買賣力金額 (元)

var: ConditionEntryTop(false);        // 進場條件:觸及頂部

var: ConditionEntryTuneover(false);   // 進場條件:周轉率足夠

var: ConditionEntryLargeAccount(false); // 進場條件:大戶資金流入

 

Vars:

    currentPrice(0),        // 目前成交價

    closePrice(0),          // 昨日收盤價

    highToday(0),           // 今日最高價

    volume_(0),             // 今日成交量

    avgVolume5(0),          // 近 5 日平均成交量

    highest120(0),          // 近 120 日最高價

    increaseRate(0),        // 漲幅 (%)

    holdingReturn(0),       // 持股報酬率 (%)

    entryDate_(0),          // 進場日期

    currentDate_(0),        // 當前日期

    avgEntryPrice_(0),      // 平均進場價格

    ConditionEntryPriceUp(false),       // 進場條件:價格上漲

    ConditionEntryHighBreak(false),     // 進場條件:突破高點

    ConditionEntryVolumeBreak(false),   // 進場條件:成交量突破

    ConditionEntryVolumeEnough(false),  // 進場條件:成交量足夠

    ConditionEntryNewHigh(false),      // 進場條件:創新高

    ConditionEntryTime(false),         // 進場條件:時間

    ConditionEntry1(false),            // 進場條件 1 (預留)

    ConditionEntry2(false),            // 進場條件 2 (預留)

    ConditionEntry3(false),            // 進場條件 3 (預留)

    ConditionEntryAll(false),          // 進場條件:所有條件滿足

    ConditionExitProfit(false),        // 出場條件:停利

    ConditionExitLoss(false),          // 出場條件:停損

    ConditionExitTime(false),          // 出場條件:時間到期

    ConditionHasPosition(false),      // 出場條件:持有部位

    ConditionExit1(false),             // 出場條件 1:停利

    ConditionExit2(false),             // 出場條件 2:停損

    ConditionExit3(false);             // 出場條件 3:持有超過兩天

 

// === 輸入參數 ===

// --------------------------------------------------------------------

input: HitTimes(3);    setinputname(1, "設定觸頂次數");       // 觸及頂部區間的次數

input: RangeRatio(1);  setinputname(2, "設定頭部區範圍寬度%");   // 頂部區間的寬度百分比

input: Length(20);     setinputname(3, "計算期數");          // 計算觸頂次數的期間

 

// === 初始化 ===

// --------------------------------------------------------------------

settotalbar(Length + 3);  // 設定回測總 Bar 數

 

// === 觸頂判斷 ===

// --------------------------------------------------------------------

variable: theHigh(0);             // 過去 Length 期內的最高價

variable: HighLowerBound(0);      // 頂部區間下界

variable: TouchRangeTimes(0);      // 期間中進入頂部區間的次數

 

theHigh = Highest(High[1], Length);               // 找到過去 Length 期內的最高價

HighLowerBound = theHigh * (100 - RangeRatio) / 100;  // 設定頂部區間下界

 

// 計算過去 Length 期內,股價進入頂部區間的次數

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

 

// 如果觸及頂部區間的次數達到設定值,且當前價格突破最高價,則觸發觸頂訊號

if TouchRangeTimes >= HitTimes and (GetField("AskPrice", "Tick") > theHigh or close > theHigh) then

    TouchTop = 1;

 

TM 發文於   2025/04/29

因為系統說超過6000字我分兩篇謝謝

// === 周轉率計算 ===

// --------------------------------------------------------------------

if barfreq = "Tick" or barfreq = "Min" then

    raiseruntimeerror("不支援此頻率");  // 不支援 Tick 和 Min 頻率

 

if GetField("發行張數(張)", "D")[1] <> 0 then

begin

    Tuneoverratio = GetField("成交量", "D") / GetField("發行張數(張)", "D")[1] * 100;  // 計算周轉率

end;

 

// === 大戶買賣力金額計算 ===

// --------------------------------------------------------------------

value1 = GetField("賣出特大單金額", "D") + GetField("賣出大單金額", "D");  // 賣出大單金額

value2 = GetField("買進特大單金額", "D") + GetField("買進大單金額", "D");  // 買進大單金額

Largeaccountmoney = value2 - value1;  // 大戶買賣力金額

 

// === 取得報價資訊 ===

// --------------------------------------------------------------------

currentPrice = GetField("close");        // 取得當前收盤價

closePrice = CloseD(1);                   // 取得昨日收盤價

highToday = GetField("High", "D");         // 取得今日最高價

volume_ = GetField("成交量", "D");           // 取得今日成交量

 

// 計算近 5 日平均成交量

avgVolume5 = (GetField("Volume", "D")[1] + GetField("Volume", "D")[2] + GetField("Volume", "D")[3] + GetField("Volume", "D")[4] + GetField("Volume", "D")[5]) / 5;

highest120 = Highest(GetField("High", "D"), 120);   // 取得近 120 日最高價

increaseRate = (currentPrice - closePrice) / closePrice * 100;  // 計算漲幅

avgEntryPrice_ = FilledAvgPrice;                    // 取得平均進場價格

 

// === 計算持股報酬率 ===

// --------------------------------------------------------------------

If avgEntryPrice_ <> 0 Then

Begin

    holdingReturn = (currentPrice - avgEntryPrice_) / avgEntryPrice_ * 100;  // 計算持股報酬率

End

Else

Begin

    holdingReturn = 0;  // 避免除以 0 錯誤

End;

 

entryDate_ = FilledEntryDate;  // 取得進場日期

currentDate_ = Date;           // 取得當前日期

 

// === 進場條件判斷 ===

// --------------------------------------------------------------------

ConditionEntryTop = TouchTop = 1;                            // 觸及頂部

ConditionEntryTuneover = Tuneoverratio >= 5;                   // 周轉率 >= 5%

ConditionEntryLargeAccount = Largeaccountmoney > 10000000;     // 大戶買超金額 > 1000 萬

ConditionEntryVolumeBreak = volume_ > avgVolume5 * 1.5;       // 成交量 > 近 5 日平均成交量 * 1.5

ConditionEntryVolumeEnough = volume_ >= 1000;                  // 成交量 >= 1000 張

 

// 所有進場條件都滿足

ConditionEntryAll = ConditionEntryTop and ConditionEntryTuneover and ConditionEntryLargeAccount and ConditionEntryVolumeBreak and ConditionEntryVolumeEnough;

 

// === 進場邏輯 ===

// --------------------------------------------------------------------

If ConditionEntryAll Then

Begin

    Buy(1, MARKET, label:="進場觸發");  // 以市價買進 1 張

    Alert("符合進場條件,已買進 1 張");      // 彈出警示訊息

End;

 

// === 出場條件判斷 ===

// --------------------------------------------------------------------

ConditionExitProfit = holdingReturn >= 5;  // 停利:持股報酬率 >= 5%

ConditionExitLoss = holdingReturn <= -1;   // 停損:持股報酬率 <= -1%

ConditionExitTime = entryDate_ < currentDate_ and currentDate_ - entryDate_ >= 2;  // 持有時間超過 2 天

ConditionHasPosition = Position > 0;      // 持有部位

 

ConditionExit1 = ConditionHasPosition and ConditionExitProfit;  // 停利出場

ConditionExit2 = ConditionHasPosition and ConditionExitLoss;   // 停損出場

ConditionExit3 = ConditionHasPosition and ConditionExitTime;   // 持有超過兩天出場

 

// === 出場邏輯 ===

// --------------------------------------------------------------------

If ConditionExit1 Then

Begin

    Sell(1, MARKET, label:="達到停利,出場");  // 以市價賣出 1 張

    Alert("持倉報酬率達到 5%,已賣出 1 張");      // 彈出警示訊息

End;

 

If ConditionExit2 Then

Begin

    Sell(1, MARKET, label:="達到停損,出場");  // 以市價賣出 1 張

    Alert("持倉報酬率低於 -1.5%,已賣出 1 張");     // 彈出警示訊息

End;

 

// 4/27 取消2天平倉條件

//If ConditionExit3 Then

//Begin

//    Sell(1, MARKET, label:="持倉超過兩日平倉");

//    Alert("持有超過 2 天,平倉已執行");

//End;

顯示更多回應 發表回覆
Close