傑克請問上次那個QM只有2行是要怎麼用阿?!
本帖最後由 ram 於 18-8-1 15:44 編輯凡是進入到需要I/O的階段,使用結構總是少不了的必備技能
而不管是通訊,檔案存取,API調用...都算是I/O
上次令我嚇傻的那個QM化作C#長這樣,只有2行
public static extern IntPtr dllCreateItemQuoteMemory(string DBName, string cpItemName, IntPtr vpStructData, int iStructSize);
public static extern IntPtr dllGetItemQuoteMemory(string DBName, string cpItemName);原始的API說明是這樣
//--------------------------------------------------------------------------------------------------------
/* Quote-Manager 功能 */ //須有支援的API版本才提供
//fnDbfTCdll_CreateItemQuoteMemory ==> 產生一個商品所需的記憶體結構對應空間
// vpStructData : 可放好預設值,作為初值內容
typedef DBFTCDLL_API void * (DBFTCDLLAPI *pWWXfunc_fnDbfTCdll_CreateItemQuoteMemory)(const char *cpDBName, const char *cpItemName, const void *vpStructData, int iStructSize);
static char WWXfunc_fnDbfTCdll_CreateItemQuoteMemory[] = "_fnDbfTCdll_CreateItemQuoteMemory@16";//DLL中對應的API名稱
//fnDbfTCdll_GetItemQuoteMemory ==> 取得商品記憶體結構對應空間
typedef DBFTCDLL_API void * (DBFTCDLLAPI *pWWXfunc_fnDbfTCdll_GetItemQuoteMemory)(const char *cpDBName, const char *cpItemName);
static char WWXfunc_fnDbfTCdll_GetItemQuoteMemory[] = "_fnDbfTCdll_GetItemQuoteMemory@8";//DLL中對應的API名稱
所以上次娶回的西夏婆可以這樣打扮
首先設計結構,就是自己想,需要怎樣的一筆紀錄來作資料保存
估阿估阿,擬下了這樣的內容,這裏就不收治裝費了{:4_186:}
public struct PriceField20
{//固定大小為20 bytes的價位資料空間,為用於像是有小數點的市場選擇使用string以便忠於源汁源味
public string data;
}
public struct DataField32
{//固定大小為32 bytes的資料空間
public string data;
}
public struct PQdataField
{//便於如買賣價量成對的設計
public PriceField20 price;
public Int32 qty;
}
public struct KDdataField
{//便於KD的應用設計
public Int32 timeKey;
public Int64 Volume;
public PriceField20 Refer;//參考價
public PriceField20 Open;//開
public PriceField20 High;//高
public PriceField20 Low;//低
public PriceField20 Close;//收
}
public struct ItemDatas
{
public DataField32 Symbol;//存放來源的代碼
public DataField32 MySymbol;//自己要用的命名(可於第一次產生時依自己需求設計對應,例如下單的代碼)
public Int64 Volume;//總量
public PQdataField Last;//最新成交價和單量
public PriceField20[] aPrice;//可放多個(這裡是設20)價位資料,例如 參考價,開,高,低 ...
public PQdataField[] aBestBuy;//最佳10檔買價量
public PQdataField[] aBestSell;//最佳10檔賣價量
public KDdataField[] aKD_Day;//可放最近10日的日線資料
//
//public KDdataField[] aKD_Min;//可放一日的分線資料
public ItemDatas(string symbol) //建構,用於產生第一次的C#實體空間結構
{
Symbol.data = symbol;
MySymbol.data = "";
Volume = 0;
Last.price.data = "";
Last.qty = 0;
//array的部分要比照前面的規劃new出所需的大小
aPrice = new PriceField20;
aBestBuy = new PQdataField;
aBestSell = new PQdataField;
aKD_Day = new KDdataField;
//aKD_Min = new KDdataField;
}
}
再來有一個重點,腰要束緊才好看
// Initialize unmanged memory to hold the struct.
public static ItemDatas sItemDatas = new ItemDatas("(null)");//C#中為了SizeOf還是要建一個固定的比較方便
public static IntPtr pItemDatas = Marshal.AllocHGlobal(Marshal.SizeOf(sItemDatas));//可便於指標方式的操作(這個可以不用)
然後就看心情上下其手了,把上次要打DDE資料那邊這樣加料
public static void ItemProcessCallback(string DBName, string VarName, string Symbol, string NewValue, string OldValue)
{
DataCounting++;//程式啟動後資料更新次數
IntPtr PtrItem = dllGetItemQuoteMemory(DBName, Symbol);
if (PtrItem == IntPtr.Zero) //if (PtrItem.ToPointer() == null)
{//尚未存在,建立
PtrItem = dllCreateItemQuoteMemory(DBName, Symbol, pItemDatas, Marshal.SizeOf(sItemDatas));//這裡pItemDatas不可以用null
//PtrItem = dllCreateItemQuoteMemory(DBName, Symbol, IntPtr.Zero, Marshal.SizeOf(sItemDatas));
if (PtrItem != IntPtr.Zero) //if (PtrItem.ToPointer() != null)
{
ItemDatas s = new ItemDatas(Symbol);
s.aPrice.data = dllReturnString(dllGetCurrTagValue("422"));//Refer,昨收
s.aPrice.data = dllReturnString(dllGetCurrTagValue("130"));//Open
s.aPrice.data = dllReturnString(dllGetCurrTagValue("131"));//High
s.aPrice.data = dllReturnString(dllGetCurrTagValue("132"));//Low
//s.aPrice.data = dllReturnString(dllGetCurrTagValue("121"));//Last/trade
s.Volume = Convert.ToInt64(dllReturnString(dllGetCurrTagValue("133")), 10);//Volume
//... 這裡可以設計載入日線資料 ....
// Copy the struct to unmanaged memory.
Marshal.StructureToPtr(s, PtrItem, false);
}
}
else
{
ItemDatas s = (ItemDatas)Marshal.PtrToStructure(PtrItem, typeof(ItemDatas));//調出商品當前資料結構內容
Int64 v = Convert.ToInt64(dllReturnString(dllGetCurrTagValue("133")), 10);//Volume
if (v != s.Volume)
{//有Tick
if (v > s.Volume)
{//確定總量是增加的才產生Tick, 否則視為修正而已
s.Last.price.data = dllReturnString(dllGetCurrTagValue("121"));//Last/trade
s.Last.qty = (Int32)(v - s.Volume);
Console.WriteLine("Tick " + s.Symbol.data + " V: " + v + " Last: " + s.Last.price.data + "(" + s.Last.qty + ")");
}
s.Volume = v;//update
}
//沒有要抓變化就不用比對直接一率更新即可
s.aPrice.data = dllReturnString(dllGetCurrTagValue("422"));//Refer,昨收
s.aPrice.data = dllReturnString(dllGetCurrTagValue("130"));//Open
s.aPrice.data = dllReturnString(dllGetCurrTagValue("131"));//High
s.aPrice.data = dllReturnString(dllGetCurrTagValue("132"));//Low
//s.aPrice.data = dllReturnString(dllGetCurrTagValue("121"));//Last/trade
//成交價和舊的最佳買賣價比較產生內外盤, 只是概念表達,可以轉成數值作更多的判斷
if (s.Last.price.data == s.aBestBuy.price.data)
{//成交在買價(內盤)
}
else if (s.Last.price.data == s.aBestSell.price.data)
{//成交在賣價(外盤)
}
//... 五檔更新 ... 省略, 看完這邊的示範應該都會自己寫了
//... 這裡可以設計KD資料處理 .... 例如當日KD最新狀態 假設當日的放在 array 0
s.aKD_Day.Refer.data = s.aPrice.data;//昨收
s.aKD_Day.Open.data = s.aPrice.data;//Open
s.aKD_Day.High.data = s.aPrice.data;//High
s.aKD_Day.Low.data = s.aPrice.data;//Low
s.aKD_Day.Volume = s.Volume;//日總量
// Copy the struct to unmanaged memory.
Marshal.StructureToPtr(s, PtrItem, false);
}
說明都在code中有提了,縮排對齊和顏料的部分就比較抱歉啦{:4_90:}
大概以下重點:
1. 指標的部分,IntPtr怎麼判斷null
2. 如何將填好資料的結構存放於API中的記憶體(dllCreateItemQuoteMemory)
3. 調出資料(dllGetItemQuoteMemory)怎麼由指標變成結構內容
4. 老孫上場大鬧洞房,行情資料什麼都有,愛怎麼玩自己玩
其他請自己領悟囉~
當然,上面的程式碼怎麼表現還是要看一下avi感受西夏婆熱情
內容中左邊是XP x86版程式
右邊是遠端Win7 x64版程式
就跟MMORPG的道理一樣,程式那麼大動畫那麼炫都是假的,
其實就只是一點點數據跑來跑去而已,
然後依據數據撥放動畫撥放特效,再弄個CD不能跳過來拖你的時間
浪費了青春與生命也只是資料庫的幾欄數據跟別人不一樣而已,
一堆脫機外掛或內掛跑的比你勤,還能直接拋數據作弊,
就連安裝作業系統,也要弄出個無人職守,那麼弄程式自動化也一樣,
都已經知道要作什麼了還看什麼介面,瞎泌線圖根本廢物,
其實當你在等成交當訊號,抓買賣作訊號的人早先跑一步了
當你以為預掛好委託可以優先成交時,你只是委託簿上面人家參考的訊號而已...{:4_163:}
所以訊號源真的超級重要的,策略和下單根本是其次
如果能放程式在券商後端收資料就好了{:4_115:}
這裡放個觀測點,看有沒有懶人要直接收cs檔
厲害的可以專案自建,要不然得先有上次的專案才好收喔!
還是有人純觀賞?!{:4_85:}
看了半天,沒有看到重點。直接貼到vs里,就可以執行嗎? 看了半天,沒有看到重點。直接貼到vs里,就可以執行嗎? wujack 發表於 18-8-2 08:17
看了半天,沒有看到重點。直接貼到vs里,就可以執行嗎?
怎麼這麼古椎咧///傑克
沒打碼的西夏婆裸在上面,行不行自己上了就知道啦!
然後都說很重要的要重複三遍
標題到內文已經五遍,現在再補一遍變成咑啵重要
當然是要有『上次』的付出,才能使用本次的招待阿
咯..咯...咯....{:4_162:}
難怪 我貼到vs里 都不能用…
頁:
[1]