請選擇 進入手機版 | 繼續訪問電腦版

COCO研究院

 找回密碼
 註冊
搜索
樓主: alexliou

[API] 群益API 2.13.5 C#實作

  [複製鏈接]
 樓主| 發表於 18-5-9 05:10 | 顯示全部樓層
lawlu 發表於 18-5-8 23:08
Alex大大

       另外這幾天早上測試時,發現一個問題,就是您程式的單量顏色,有時候會有幾筆單量 ...

因為你把兩件頻率不同的事情, 放在同一個update routine裡了
在OnNotifyTicks() 收pSKTick資料
在OnNotifyQuote() 收pSKStock 資料, 並更新報價表

試想, 事件發生為以下順序:
1. 收到大台Tick ===> 更新pSKTick
2. 收到小台Tick ===> pSKTick 變成最新收到的小台資料
3. 收到大台Quote ===> 更新pSKStock, 並以pSKStock, pSKTick 更新報價表
但此時的pSKTick卻是小台的資料, 因此顯示出的資料  是小台Tick 的成交序號與成交時間
4. 收到小台Quote
這次正確了, 顯示出小台的成交序號與時間

實際執行時, 1,2,3,4, 的發生順序可能每次都不一樣
因次就會有時正確顯示, 有時錯誤

解決方法是將update 成交序號與成交時間的工作, 放在 OnNotifyTicks() 裡


發表於 18-5-9 11:09 | 顯示全部樓層
      感謝Alex大,一大早撥冗回覆與建議

依照您的建議修改程式如下後,已經可以修正問題了,但因為是剛剛盤中修改程式後去測試的,有發現到一個問題如下紅框的地方,也就是2492華新科被分盤交易,當啟動程式期間並未有成交訊息時,一開始取的的序號及成交時間是別檔股票資料,待10:55:03有更新的交易資訊時,序號及成交時間才有update到正確的資訊,另外3661世芯科,也是啟動程式後,有一段空檔時間未成交,所以一開始顯示的序號及成交時間也是為0,待有新的成交資料後,才更新到正確的資料,想請教問題是出在哪個環節?謝謝您

   Private Sub skQ_OnNotifyTicks(sMarketNo As Short, sIndex As Short, nPtr As Integer, nTimehms As Integer, nTimemillismicros As Integer, nBid As Integer, nAsk As Integer, nClose As Integer, nQty As Integer, nSimulate As Integer) Handles skQ.OnNotifyTicks

        skQ.SKQuoteLib_GetTick(sMarketNo, sIndex, nPtr, pSKTick)
        OnUpDateTicks(pSKTick)

    End Sub

    Private Sub OnUpDateTicks(ByVal pTick As SKCOMLib.SKTICK)
        Dim strStockNo As String = pSKStock.bstrStockNo
        Dim drFind As DataRow = portfolioQuoteTable.Rows.Find(strStockNo)

        If drFind Is Nothing Then
            Try
                Dim myDataRow As DataRow = portfolioQuoteTable.NewRow()

                myDataRow("nPtr") = pSKTick.nPtr
                myDataRow("nTimehms") = pSKTick.nTimehms

                portfolioQuoteTable.Rows.Add(myDataRow)

            Catch ex As Exception

                Dim msg As String = ex.Message

            End Try

        Else

            drFind("nPtr") = pSKTick.nPtr
            drFind("nTimehms") = pSKTick.nTimehms

        End If

    End Sub
0809.jpg
 樓主| 發表於 18-5-9 12:12 | 顯示全部樓層
lawlu 發表於 18-5-9 11:09
感謝Alex大,一大早撥冗回覆與建議

依照您的建議修改程式如下後,已經可以修正問題了,但因為是剛剛 ...

有個問題上次沒提到你在OnNotifyTicks() 呼叫了 GetTick()
這是不需要的
OnNotifyTicks() 已經把 該Tick 的資料都用參數船回來了
不用再利用傳回的 sMarketNo, sIndex, nPtr 去把這這Tick 再Get 一次

不過這應該與這次的問題無關
這次所顯示的的Tick資訊是否屬於該股票的? 還是該股分盤交易前一盤的成交資訊
如果是後者, 那程式的Behavior 就是正確的

發表於 18-5-9 12:28 | 顯示全部樓層
         謝謝Alex大這麼快回覆:

此次問題,我把上面的敘述截圖用紅色及藍色框起來,當每一檔個股的Tick資料都有更新的時候,應該都是正確的,因為我有與嘉實資訊的成交明細去比對時間,但是主要的問題是一開始啟動程式後,最初抓到的那個Ticks資料,好像有問題,就詳如下圖的敘述,還請Alex大大幫忙解惑,謝謝您!感恩
2.jpg
 樓主| 發表於 18-5-9 14:21 | 顯示全部樓層
lawlu 發表於 18-5-9 12:28
謝謝Alex大這麼快回覆:

此次問題,我把上面的敘述截圖用紅色及藍色框起來,當每一檔個股的Tick資 ...

這應該是和群益API RequestTick()的Behavior 有關
當呼叫 RequestTicks() 時,
取決於是否為第一次呼叫
Server Return Ticks 的順序會不同

就我記憶所及:
若為首次呼叫, Server  會先把Historical Ticks 以 OnNotifyHistoricalTicks() 傳回
然後再以OnNotifyTicks() 依序傳 Live Ticks

若非首次呼叫, Server 會
1. 先傳首次呼叫時的最後一筆 Live Tick (OnNotifyTicks)
2. 接著傳Historical Tick (OnNotifyHistoricalTicks)
3. 再開始傳Live Ticks (OnNotifyTicks)
所以第一次OnNotifyTicks 所收到的第一筆資料, 可能不是當下的即時Tick

你可以 執行一下群益的範例檔, Check 看看到底是怎麼傳的


發表於 18-5-10 20:42 | 顯示全部樓層
本帖最後由 lawlu 於 18-5-10 20:47 編輯

         Alex大大您好:

  1. 昨天晚上測試夜盤台指期及小台指的成交序號及成交時間是否又出現彼此重疊覆蓋的情況,結果果真      發生問題經檢視後將datatable的PrimaryKey由 "caStockNo" = 股票代號,改成"sStockidx"=股票索引,
      如下:

        myDataTable.PrimaryKey = New DataColumn() {myDataTable.Columns("sStockidx")}

  2. 且update pSKTick在 OnNotifyTicks事件下,就能夠正常顯示所有的成交序號及成交時間了。

    Private Sub skQ_OnNotifyTicks(sMarketNo As Short, sIndex As Short, nPtr As Integer, nTimehms As Integer, nTimemillismicros As Integer, nBid As Integer, nAsk As Integer, nClose As Integer, nQty As Integer, nSimulate As Integer) Handles skQ.OnNotifyTicks

        skQ.SKQuoteLib_GetTick(sMarketNo, sIndex, nPtr, pSKTick)

       Dim drFind As DataRow = portfolioQuoteTable.Rows.Find(sIndex)

        If drFind Is Nothing Then
            Try
                Dim myDataRow As DataRow = portfolioQuoteTable.NewRow()

                myDataRow("nPtr") = pSKTick.nPtr
                myDataRow("nTimehms") = pSKTick.nTimehms

                portfolioQuoteTable.Rows.Add(myDataRow)

            Catch ex As Exception

                Dim msg As String = ex.Message

            End Try

        Else

            drFind("nPtr") = pSKTick.nPtr
            drFind("nTimehms") = pSKTick.nTimehms

        End If

    End Sub


    3. 早上進行正常測試時,卻在09:01時,出現無法顯示之前一直有問題的第一分K棒的高低點,經查發現        是因為PrimaryKey已由"caStockNo" = 股票代號,改成"sStockidx"=股票索引,而無法找到對應的
        datarow,rowFind=null的關係

    4. 想請問的是,有沒有辦法將我的商品清單裡的股票代號,轉換成對應的"sStockidx"=股票索引,或是
        有其他的方法能夠改善此一問題

        一直向你請教問題,真的是麻煩您了,謝謝您!感恩。



88.jpg
888.jpg
 樓主| 發表於 18-5-10 21:23 | 顯示全部樓層
lawlu 發表於 18-5-10 20:42
Alex大大您好:

  1. 昨天晚上測試夜盤台指期及小台指的成交序號及成交時間是否又出現彼此重疊覆 ...

DataTable 的key只能有一個
要match Key 欄位的值用Find
非Key欄位的值用Select
https://msdn.microsoft.com/en-us/library/y06xa2h1.aspx

或是呼叫 GetStockByNo() 用StockNo 取回 StockIndex的值
再用StockIndex  去 Find (假設DataTable 是以StockIndex為Key)
發表於 18-5-10 22:58 | 顯示全部樓層
             真的非常感謝Alex大的快速回覆:
    剛剛以大大建議的用GetStockByNo()取回sStockIdx的方式,成功的測試完成,可以在約定的時間顯示
    1分K棒高低點了,程式碼如下:


Case "22:43:00"

                For Each s As String In Stocks

                    skQ.SKQuoteLib_GetStockByNo(s.Trim(), pSKStock)
                    Dim strStockNo As String = pSKStock.sStockIdx
                    Dim rowFind As DataRow = portfolioQuoteTable.Rows.Find(strStockNo)

                    rowFind("nHigh_1K") = rowFind("nHigh")
                    rowFind("nLow_1K") = rowFind("nLow")

                Next







8888.jpg
發表於 18-5-12 11:19 | 顯示全部樓層
             Alex 大大您好:

  1. 因為想計算成交均價,所以先計算了累積成交金額,程式碼如下:

           drFind("nPtr") = pSKTick.nPtr
            drFind("nTimehms") = pSKTick.nTimehms
            drFind("nBid") = pSKTick.nBid / (Math.Pow(10, pSKStock.sDecimal))
            drFind("nAsk") = pSKTick.nAsk / (Math.Pow(10, pSKStock.sDecimal))
            drFind("nTickQty") = pSKTick.nQty
            drFind("mClose") = pSKTick.nClose / (Math.Pow(10, pSKStock.sDecimal))

            If m_nSimulateStock = 0 Then

                drFind("Amount") = (pSKTick.nQty * pSKTick.nClose) / (Math.Pow(10, pSKStock.sDecimal))

                AccumulatedPrice = AccumulatedPrice + drFind("Amount")


                drFind("AccuAmount") = AccumulatedPrice


                lbxR.Items.Add(Now & " " & AccumulatedPrice)

            End If



  2.但是早上測試時,因為已經收盤後,理當累積的成交金額只有最後一筆的成交金額2849,但是卻出現了有累加的動作,跑出69412,不知是何原因造成?

  3.小弟是程式初學者,所以可能邏輯常常有誤解,真的是麻煩您了,謝謝您!感恩。


888.jpg
 樓主| 發表於 18-5-12 11:40 | 顯示全部樓層
lawlu 發表於 18-5-12 11:19
Alex 大大您好:

  1. 因為想計算成交均價,所以先計算了累積成交金額,程式碼如下:

1.  這大概跟API  的Behavior 有關
我們預期API 在盤後只會傳送最後一筆成交資料
但實際運作時, 可能不只傳一筆資料

2. 建議你學習一下如何利用 Visual Studio IDE 來 Debug
建立 Break point, 交互運用F8與F5
這樣可以讓你更清楚 program的流程是怎麼跑的
https://docs.microsoft.com/en-us ... d-with-the-debugger
發表於 18-5-12 16:31 | 顯示全部樓層
本帖最後由 lawlu 於 18-5-12 16:39 編輯

            謝謝Alex大快速回覆與建議:

  1.本次遇到的問題,後來想到去年小弟使用excel vba寫群益API時,就出現了,您也幫忙解惑如下圖,並說明會取得2個tick資料

  2.經查嘉實報價軟體,2492華新科的最後兩筆資料如下圖,也與小弟的API報價資訊吻合
66.jpg
77.jpg
55.jpg
發表於 18-5-14 22:21 | 顯示全部樓層
本帖最後由 lawlu 於 18-5-14 22:22 編輯

           Alex大大您好,又來叨擾您問題了:

           累計成交價的程式碼,在單一檔報價時,可以正確的計算,但是若要求兩檔以上的報價,則會出現累計錯誤的情形,也就是說把其他檔的資料一起累計進去,彼此互相累計,因此一直爆增,我猜應該是這兩個 全域變數"AccumulatedQty",和 "AccumulatedPrice"宣告上的問題,想請問您,我應該如何修改才是正確的作法?

           謝謝您!感恩


            If m_nSimulateStock = 0 Then

                AccumulatedQty = AccumulatedQty + drFind("nTickQty")

                drFind("AccuQty") = AccumulatedQty            

                drFind("Amount") = (pSKTick.nQty * pSKTick.nClose) / (Math.Pow(10, pSKStock.sDecimal))

                AccumulatedPrice = AccumulatedPrice + drFind("Amount")

                drFind("AccuAmount") = AccumulatedPrice            

            End If



 樓主| 發表於 18-5-15 06:30 | 顯示全部樓層
lawlu 發表於 18-5-14 22:21
Alex大大您好,又來叨擾您問題了:

           累計成交價的程式碼,在單一檔報價時,可以正確 ...

在你的DataTable裡,你已為每檔股票都設了該股的累積欄位,
不用在新設變數了,
只需考慮initial condition 就好
發表於 18-5-16 06:58 | 顯示全部樓層
本帖最後由 lawlu 於 18-5-16 07:00 編輯
樓主| 發表於 18-5-15 06:30|
   
在你的DataTable裡,你已為每檔股票都設了該股的累積欄位,

          非常感謝Alex大的解答:

  1. 原來在  Private Function CreateStocksDataTable() As DataTable的階段,
      將initial condition設為0就可以了

                   myDataTable.Columns.Add("AccuAmount", GetType(Double))
                   myDataTable.Columns("AccuAmount").DefaultValue = 0

                   myDataTable.Columns.Add("AccuQty", GetType(Int32))
                   myDataTable.Columns("AccuQty").DefaultValue = 0

2. 另外想請教Alex大一個cellformatting的問題如下圖檔出現的說明
     此問題是我將判斷單量顏色的條件,改成由notifytick的成交價,
     及買價,賣價來判斷,但是卻出現無法執行的情況,想請問應該     如何修正才正確,謝謝您,感恩!



例外狀況.jpg
 樓主| 發表於 18-5-18 06:17 | 顯示全部樓層
本帖最後由 alexliou 於 18-5-18 06:18 編輯
lawlu 發表於 18-5-16 06:58
非常感謝Alex大的解答:

  1. 原來在  Private Function CreateStocksDataTable() As DataTable ...

由錯誤訊息判斷
應該是指 Cells('nBid')的值是null
從以前你貼出來的圖看起來
datagrid中的買價欄位應該是 unvisiable,  所以看不出此欄位值是否正確
這個欄位的值有和datatable的對應欄位 的link, 有設定正確嗎?
您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

手機版|Archiver|站長信箱|廣告洽詢|COCO研究院

GMT+8, 24-3-29 18:18

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回復 返回頂部 返回列表
理財討論網站 | AI繪圖AI超擬真美女AI beauty AI Stable DiffusionAI正妹AI Lookbook