COCO研究院

 找回密碼
 註冊
搜索
查看: 3834|回復: 4

[API] 傑克請問上次那個QM只有2行是要怎麼用阿?!

[複製鏈接]
發表於 18-8-1 14:25 | 顯示全部樓層 |閱讀模式
本帖最後由 ram 於 18-8-1 15:44 編輯

凡是進入到需要I/O的階段,使用結構總是少不了的必備技能

而不管是通訊,檔案存取,API調用...都算是I/O

上次令我嚇傻的那個QM化作C#長這樣,只有2行
  1. public static extern IntPtr dllCreateItemQuoteMemory(string DBName, string cpItemName, IntPtr vpStructData, int iStructSize);

  2. public static extern IntPtr dllGetItemQuoteMemory(string DBName, string cpItemName);
複製代碼
原始的API說明是這樣
  1. //--------------------------------------------------------------------------------------------------------
  2. /* Quote-Manager 功能 */        //須有支援的API版本才提供

  3. //fnDbfTCdll_CreateItemQuoteMemory ==> 產生一個商品所需的記憶體結構對應空間
  4. //        vpStructData : 可放好預設值,作為初值內容
  5. typedef DBFTCDLL_API void * (DBFTCDLLAPI *pWWXfunc_fnDbfTCdll_CreateItemQuoteMemory)(const char *cpDBName, const char *cpItemName, const void *vpStructData, int iStructSize);
  6. static char WWXfunc_fnDbfTCdll_CreateItemQuoteMemory[] = "_fnDbfTCdll_CreateItemQuoteMemory@16";//DLL中對應的API名稱

  7. //fnDbfTCdll_GetItemQuoteMemory ==> 取得商品記憶體結構對應空間
  8. typedef DBFTCDLL_API void * (DBFTCDLLAPI *pWWXfunc_fnDbfTCdll_GetItemQuoteMemory)(const char *cpDBName, const char *cpItemName);
  9. static char WWXfunc_fnDbfTCdll_GetItemQuoteMemory[] = "_fnDbfTCdll_GetItemQuoteMemory@8";//DLL中對應的API名稱
複製代碼

所以上次娶回的西夏婆可以這樣打扮

首先設計結構,就是自己想,需要怎樣的一筆紀錄來作資料保存

估阿估阿,擬下了這樣的內容,這裏就不收治裝費了
  1.     [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  2.     public struct PriceField20
  3.     {//固定大小為20 bytes的價位資料空間,為用於像是有小數點的市場選擇使用string以便忠於源汁源味
  4.         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
  5.         public string data;
  6.     }

  7.     [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  8.     public struct DataField32
  9.     {//固定大小為32 bytes的資料空間
  10.         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  11.         public string data;
  12.     }

  13.     [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  14.     public struct PQdataField
  15.     {//便於如買賣價量成對的設計
  16.         public PriceField20 price;
  17.         public Int32 qty;
  18.     }

  19.     [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  20.     public struct KDdataField
  21.     {//便於KD的應用設計
  22.         public Int32 timeKey;
  23.         public Int64 Volume;
  24.         public PriceField20 Refer;//參考價
  25.         public PriceField20 Open;//開
  26.         public PriceField20 High;//高
  27.         public PriceField20 Low;//低
  28.         public PriceField20 Close;//收
  29.     }

  30.     [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
  31.     public struct ItemDatas
  32.     {
  33.         public DataField32 Symbol;//存放來源的代碼

  34.         public DataField32 MySymbol;//自己要用的命名(可於第一次產生時依自己需求設計對應,例如下單的代碼)

  35.         public Int64 Volume;//總量
  36.         public PQdataField Last;//最新成交價和單量

  37.         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
  38.         public PriceField20[] aPrice;//可放多個(這裡是設20)價位資料,例如 參考價,開,高,低 ...

  39.         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  40.         public PQdataField[] aBestBuy;//最佳10檔買價量

  41.         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  42.         public PQdataField[] aBestSell;//最佳10檔賣價量

  43.         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  44.         public KDdataField[] aKD_Day;//可放最近10日的日線資料

  45.         //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1440)]
  46.         //public KDdataField[] aKD_Min;//可放一日的分線資料

  47.         public ItemDatas(string symbol) //建構,用於產生第一次的C#實體空間結構
  48.         {
  49.             Symbol.data = symbol;
  50.             MySymbol.data = "";
  51.             Volume = 0;
  52.             Last.price.data = "";
  53.             Last.qty = 0;
  54. //array的部分要比照前面的規劃new出所需的大小
  55.             aPrice = new PriceField20[20];
  56.             aBestBuy = new PQdataField[10];
  57.             aBestSell = new PQdataField[10];
  58.             aKD_Day = new KDdataField[10];
  59.             //aKD_Min = new KDdataField[1440];
  60.         }
  61.     }
複製代碼

再來有一個重點,腰要束緊才好看
  1.         // Initialize unmanged memory to hold the struct.
  2.         public static ItemDatas sItemDatas = new ItemDatas("(null)");//C#中為了SizeOf還是要建一個固定的比較方便
  3.         public static IntPtr pItemDatas = Marshal.AllocHGlobal(Marshal.SizeOf(sItemDatas));//可便於指標方式的操作(這個可以不用)
複製代碼

然後就看心情上下其手了,把上次要打DDE資料那邊這樣加料
  1.         public static void ItemProcessCallback(string DBName, string VarName, string Symbol, string NewValue, string OldValue)
  2.         {
  3.             DataCounting++;//程式啟動後資料更新次數

  4.             IntPtr PtrItem = dllGetItemQuoteMemory(DBName, Symbol);
  5.             if (PtrItem == IntPtr.Zero) //if (PtrItem.ToPointer() == null)
  6.             {//尚未存在,建立
  7.                 PtrItem = dllCreateItemQuoteMemory(DBName, Symbol, pItemDatas, Marshal.SizeOf(sItemDatas));//這裡pItemDatas不可以用null
  8.                 //PtrItem = dllCreateItemQuoteMemory(DBName, Symbol, IntPtr.Zero, Marshal.SizeOf(sItemDatas));
  9.                 if (PtrItem != IntPtr.Zero) //if (PtrItem.ToPointer() != null)
  10.                 {
  11.                     ItemDatas s = new ItemDatas(Symbol);
  12.                     s.aPrice[0].data = dllReturnString(dllGetCurrTagValue("422"));//Refer,昨收
  13.                     s.aPrice[1].data = dllReturnString(dllGetCurrTagValue("130"));//Open
  14.                     s.aPrice[2].data = dllReturnString(dllGetCurrTagValue("131"));//High
  15.                     s.aPrice[3].data = dllReturnString(dllGetCurrTagValue("132"));//Low
  16.                     //s.aPrice[4].data = dllReturnString(dllGetCurrTagValue("121"));//Last/trade
  17.                     s.Volume = Convert.ToInt64(dllReturnString(dllGetCurrTagValue("133")), 10);//Volume

  18.                     //... 這裡可以設計載入日線資料 ....

  19.                     // Copy the struct to unmanaged memory.
  20.                     Marshal.StructureToPtr(s, PtrItem, false);
  21.                 }
  22.             }
  23.             else
  24.             {
  25.                 ItemDatas s = (ItemDatas)Marshal.PtrToStructure(PtrItem, typeof(ItemDatas));//調出商品當前資料結構內容
  26.                 Int64 v = Convert.ToInt64(dllReturnString(dllGetCurrTagValue("133")), 10);//Volume
  27.                 if (v != s.Volume)
  28.                 {//有Tick
  29.                     if (v > s.Volume)
  30.                     {//確定總量是增加的才產生Tick, 否則視為修正而已
  31.                         s.Last.price.data = dllReturnString(dllGetCurrTagValue("121"));//Last/trade
  32.                         s.Last.qty = (Int32)(v - s.Volume);
  33.                         Console.WriteLine("Tick " + s.Symbol.data + " V: " + v + " Last: " + s.Last.price.data + "(" + s.Last.qty + ")");
  34.                     }
  35.                     s.Volume = v;//update
  36.                 }
  37.                 //沒有要抓變化就不用比對直接一率更新即可
  38.                 s.aPrice[0].data = dllReturnString(dllGetCurrTagValue("422"));//Refer,昨收
  39.                 s.aPrice[1].data = dllReturnString(dllGetCurrTagValue("130"));//Open
  40.                 s.aPrice[2].data = dllReturnString(dllGetCurrTagValue("131"));//High
  41.                 s.aPrice[3].data = dllReturnString(dllGetCurrTagValue("132"));//Low
  42.                 //s.aPrice[4].data = dllReturnString(dllGetCurrTagValue("121"));//Last/trade

  43.                 //成交價和舊的最佳買賣價比較產生內外盤, 只是概念表達,可以轉成數值作更多的判斷
  44.                 if (s.Last.price.data == s.aBestBuy[0].price.data)
  45.                 {//成交在買價(內盤)
  46.                 }
  47.                 else if (s.Last.price.data == s.aBestSell[0].price.data)
  48.                 {//成交在賣價(外盤)
  49.                 }

  50.                 //... 五檔更新 ... 省略, 看完這邊的示範應該都會自己寫了

  51.                 //... 這裡可以設計KD資料處理 .... 例如當日KD最新狀態 假設當日的放在 array 0
  52.                 s.aKD_Day[0].Refer.data = s.aPrice[0].data;//昨收
  53.                 s.aKD_Day[0].Open.data = s.aPrice[1].data;//Open
  54.                 s.aKD_Day[0].High.data = s.aPrice[2].data;//High
  55.                 s.aKD_Day[0].Low.data = s.aPrice[3].data;//Low
  56.                 s.aKD_Day[0].Volume = s.Volume;//日總量

  57.                 // Copy the struct to unmanaged memory.
  58.                 Marshal.StructureToPtr(s, PtrItem, false);
  59.             }
複製代碼

說明都在code中有提了,縮排對齊和顏料的部分就比較抱歉啦

大概以下重點:

1. 指標的部分,IntPtr怎麼判斷null

2. 如何將填好資料的結構存放於API中的記憶體(dllCreateItemQuoteMemory)

3. 調出資料(dllGetItemQuoteMemory)怎麼由指標變成結構內容

4. 老孫上場大鬧洞房,行情資料什麼都有,愛怎麼玩自己玩

其他請自己領悟囉~

當然,上面的程式碼怎麼表現還是要看一下avi感受西夏婆熱情

TickRealtime.rar (136.52 KB, 下載次數: 6, 售價: 1 金錢)
內容中左邊是XP x86版程式
右邊是遠端Win7 x64版程式


就跟MMORPG的道理一樣,程式那麼大動畫那麼炫都是假的,

其實就只是一點點數據跑來跑去而已,

然後依據數據撥放動畫撥放特效,再弄個CD不能跳過來拖你的時間

浪費了青春與生命也只是資料庫的幾欄數據跟別人不一樣而已,

一堆脫機外掛或內掛跑的比你勤,還能直接拋數據作弊,

就連安裝作業系統,也要弄出個無人職守,那麼弄程式自動化也一樣,

都已經知道要作什麼了還看什麼介面,瞎泌線圖根本廢物,

其實當你在等成交當訊號,抓買賣作訊號的人早先跑一步了

當你以為預掛好委託可以優先成交時,你只是委託簿上面人家參考的訊號而已...

所以訊號源真的超級重要的,策略和下單根本是其次

如果能放程式在券商後端收資料就好了

這裡放個觀測點,看有沒有懶人要直接收cs檔
Program.cs.rar (5.75 KB, 下載次數: 6, 售價: 1000 金錢)

厲害的可以專案自建,要不然得先有上次的專案才好收喔!
還是有人純觀賞?!


評分

參與人數 1金錢 +2 收起 理由
pocketman + 2 太強了

查看全部評分

發表於 18-8-2 08:17 | 顯示全部樓層
看了半天,沒有看到重點。直接貼到vs里,就可以執行嗎?
發表於 18-8-2 08:17 | 顯示全部樓層
看了半天,沒有看到重點。直接貼到vs里,就可以執行嗎?
 樓主| 發表於 18-8-7 09:38 | 顯示全部樓層
wujack 發表於 18-8-2 08:17
看了半天,沒有看到重點。直接貼到vs里,就可以執行嗎?

怎麼這麼古椎咧///  傑克

沒打碼的西夏婆裸在上面,行不行自己上了就知道啦!

然後都說很重要的要重複三遍

標題到內文已經五遍,現在再補一遍變成咑啵重要

當然是要有『上次』的付出,才能使用本次的招待阿

咯..咯...咯....


發表於 18-8-7 12:25 | 顯示全部樓層
難怪 我貼到vs里 都不能用…
您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

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

GMT+8, 24-11-20 11:23

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回復 返回頂部 返回列表
理財討論網站 |