Feed-API(AGVS)


投顧最常用的行情系統,不用一個一個商品訂閱, 然後什麼資料都有... 還真多!


透過Multi-DB稍微分類... 匯市,期貨,選擇權,國際指數,上市櫃股票,權證,興櫃 超過3萬多檔的國內商品一應俱全,還有領先指標!

3萬多檔的國內商品的Tick就這麼收齊完整了!! 找個熟悉的商品比對一下資料看看~

每天看超過10小時的戲劇台,這週心血來潮利用廣告空檔弄一下這個...
果然輕輕鬆鬆就完成了雛型,再來看需求性要什麼作什麼就更簡單了

台灣的市場還是來點繁體字比較有感覺,調整後也能直接搭配OBG格式轉碼進其他系統了

話說自動交易至少要有這樣水準的報價,不然投顧怎麼會都用這套是吧!
別在呆呆的弄一堆策略,弄來弄去只是單一商品在分析,怎麼玩的贏人家?
都說台指期的依據就是加權了... 加權指數的領先指標當然可以領先一步阿

而下單機至少就是要資料齊全才是! 不然收到訊號才發現缺東缺西然後東補西補,
lag個幾秒就凍鎂佻了,居然還有那種只是幾檔報價還會累格幾分幾十分的...那是要怎麼玩阿?!!
人家說輸在起跑點就是這個意思, 上面這個超過10年都沒進步的產品也能輕鬆勝出耶!

企業空轉的寫照大概就是說全新改版號稱更好的系統結果是比原本舊的還糟糕,
說穿了就是負責技術的變差了,改不動舊的就藉口作新的,管理階層又不懂,不懂就算了還要裝懂,
當然策略方向都不對,然後花了幾年才發現真的不行,但是頭洗下去了,死的也要說成活的...
更多失敗的案例更是為了省一點成本而虧了幾百倍營利...
有時真的很難理解國內那麼多套行情架構,不是慢就是缺(併)還有不穩定的問題...


下面是簡單的Feed-API相關程式碼(參考)

只需看 sprintf 和 fnPktEvFeeder_SendPacket

void pushFutCurItemData(void *vpItem)
{//期貨,選擇權
    char caBuffer[8192];
    char *cpBuf = caBuffer;
    L_OptCur_ItemData &item = *(L_OptCur_ItemData *)vpItem;//選擇權與期貨的格式都一樣
    if (item.key.PutCall)
    {//選擇權
        cpBuf = storeFutureSymbol(cpBuf, item.refkey);
        cpBuf += sprintf(cpBuf, "(%c%d)|CCCO", item.key.PutCall, item.key.Strike);
    }
    else
    {//期貨
        if (item.refkey.yr_mon)
        {//期貨
            cpBuf = storeFutureSymbol(cpBuf, item.refkey);
            cpBuf += sprintf(cpBuf, "|CCCF");
        }
        else
        {//現貨
            cpBuf += sprintf(cpBuf, "@r%Xi%X|CCC", item.refkey.route, item.refkey.index);
        }
    }

    if (cpBuf != caBuffer)
    {
        int i;
        L_OptCur_CurStatus &cur = item.data.cur;
        L_OptCur_CurDatas &dat = cur.datas;

        //填入所有想要的報價資料
        cpBuf += sprintf(cpBuf,
            ",92=%s,93=r%X,12=%d,13=%d"
            ",14=%d,6=%d,8=%d,10=%d"
            , cur.SymbolID, item.refkey.route, dat.SettlementPrice, dat.OpenInterest
            , dat.Reference, dat.Open, dat.High, dat.Low
        );
        if (dat.Open)
        {//填入Tick相關的資料
            cpBuf += sprintf(cpBuf,
                ",61=%d,22=%d,27=%d,23=%d"
                , (wwxTime.decimal_CurrTime((time_t *)&(dat.LastTime), true) * 1000), dat.LastPrice, dat.MatchTotalQty, dat.MatchQuantity
            );
        }
        //填入五檔買賣價量
        for (i = 0; i < 5; i++)
        {
            cpBuf += sprintf(cpBuf,
                ",%d=%d,%d=%d,%d=%d,%d=%d"
                , 100+i*2, dat.BuyPrice[i], 101+i*2, dat.BuyQuantity[i]
                , 200+i*2, dat.SellPrice[i], 201+i*2, dat.SellQuantity[i]
            );
        }

        cpBuf++;//含ZE
        fnPktEvFeeder_SendPacket('F', caBuffer, (cpBuf - caBuffer), false);
    }
}

void pushStkCurItemData(void *vpItem)
{//股市,權證
    char caBuffer[8192];
    char *cpBuf = caBuffer;
    L_XnCur_ItemData &item = *(L_XnCur_ItemData *)vpItem;
    L_XnCur_Keys &key = item.keys;
    L_CurStatus_Best5_Map *pBest5 = item.getBest5_Map();
    if (pBest5)
    {//有5檔欄位格式的商品
        int i;

        L_XnCur_CurStatus &cur = item.data.cur;
        L_CurStatus_Best5_unit &b5 = pBest5->best5;
        L_CurStatus_value_amount *spBuyData = b5.bs_data;
        L_CurStatus_value_amount *spSellData = &(b5.bs_data[5]);

        //產生商品全域完整代碼
        cpBuf += sprintf(cpBuf, "@t%X-%X", (key.type_uno.type & 0xFF), key.type_uno.uno);
        if (key.IsSTOCK_TYPE())
            cpBuf += sprintf(cpBuf, "|TSE");
        else if (key.IsOTC_TYPE())
            cpBuf += sprintf(cpBuf, "|OTC");
        else if (key.IsSUBS_TYPE())
            cpBuf += sprintf(cpBuf, "|SUBS");
        else
            cpBuf += sprintf(cpBuf, "|CVS");

        //填入所有想要的報價資料
        cpBuf += sprintf(cpBuf,
            ",92=%s,93=t%X"
            ",14=%d,6=%d,8=%d,10=%d"
            , key.id, key.type_uno.type
            , cur.ref, cur.open, cur.high, cur.low
        );
        if (cur.open)
        {//填入Tick相關的資料
            cpBuf += sprintf(cpBuf,
                ",22=%d,27=%d,23=%d"
                , cur.trade, cur.volume, cur.volinc
            );
        }
        //填入五檔買賣價量
        for (i = 0; i < 5; i++)
        {
            cpBuf += sprintf(cpBuf,
                ",%d=%d,%d=%d,%d=%d,%d=%d"
                , 100+i*2, spBuyData[i].value, 101+i*2, spBuyData[i].amount
                , 200+i*2, spSellData[i].value, 201+i*2, spSellData[i].amount
            );
        }

        cpBuf++;//含ZE
        fnPktEvFeeder_SendPacket('F', caBuffer, (cpBuf - caBuffer), false);
    }
    else if (key.type_uno.type == OCS_TYPE)
    {
        L_XnCur_CurStatusOCS &cur = item.data.ocs;

        //產生商品全域完整代碼
        cpBuf += sprintf(cpBuf, "@t%X-%X|OCS", (key.type_uno.type & 0xFF), key.type_uno.uno);

        //填入所有想要的報價資料
        cpBuf += sprintf(cpBuf,
            ",92=%s,93=t%X"
            ",14=%d,6=%d,8=%d,10=%d"
            ",18=%d,19=%d,20=%d,21=%d"
            , key.id, key.type_uno.type
            , cur.ref, cur.open, cur.high, cur.low
            , cur.buy, cur.buy_vol, cur.sell, cur.sell_vol
        );
        if (cur.open)
        {//填入Tick相關的資料
            cpBuf += sprintf(cpBuf,
                ",22=%d,27=%d,23=%d,13=%d"
                , cur.trade, cur.total_trade_vol, cur.trade_vol, cur.stock_vol
            );
        }

        cpBuf++;//含ZE
        fnPktEvFeeder_SendPacket('F', caBuffer, (cpBuf - caBuffer), false);
    }
}


同樣的,透過Feed-API可以把各種(商品,策略,指標)訊號打入系統,就能完整紀錄Tick轉成歷史資料,
如此可行成獨家衍生商品行情供應需求...
在系統下可以無窮變化將訊號變商品衍生更多指標成為訊號觸發更多連動,
不論多複雜的演算都能輕鬆瞬間完成!

而且都已經物連網時代了耶,訊號透過IP架構的Feed-API不但可以跨主機處理當然也遠比本地用.txt檔或DDE還快!
特殊的TCP通訊設計,不但速度媲美UDP,更能確保所有資訊完整不缺漏!!

Comments