交易命令系統(tǒng)2.0


數(shù)據(jù)庫

1. 股票賬戶表

tbl_stockaccount

字段 類型 默認(rèn)值 說明
uuid varchar(36) 主鍵
aliasname varchar(255) 別名
accountcode varchar(36) 交易用戶ID
password varchar(36) 交易用戶密碼
brokerage varchar(36) virtual 券商 fake:假的 virtual:虛擬的
type varchar(36) normal 類型 normal:普通 try:試練操盤手 trade:操盤手
exchangerate double(11,2) 0 交易手續(xù)費
followid varchar(36) 跟隨交易用戶ID
status int(3) 0 當(dāng)前狀態(tài) 0:正常 2:異常

2. 交易命令歷史表 每日一張表

tbl_commandhistoryYYYYMMDD

字段 類型 默認(rèn)值 說明
uuid varchar(36) 主鍵
stockaccountid varchar(36) 賬戶ID
stockcode varchar(6) 股票代碼
type varchar(20) 類型 buy:買入 sell:賣出
scale double(11,9) 0 比例 買入交易金額占余額比例 賣出股票數(shù)量占持倉比例
balance double(11,3) 0 交易前余額
holdcount int(11) 0 交易前持倉
count int(11) 0 交易數(shù)量
status int(3) 0 當(dāng)前狀態(tài) 0:正常 2:異常
pid varchar(36) 父命令I(lǐng)D
dir varchar(36) 所在文件夾 組ID
error varchar(255) 錯誤信息
starttime varchar(20) 操作開始時間
endtime varchar(20) 操作結(jié)束時間
operatetime varchar(20) 開始執(zhí)行時間
operateduration int(11) 0 執(zhí)行時長
totalduration int(11) 0 執(zhí)行總時長

接口

Servlet

1. 開啟股票賬戶

/servlet/openstockaccount
此接口需要先到虛擬交易所開戶,才可以使用

Request:
{
        "aliasname":"lichen",         //別名 英文中文手機號
        "password":"12345678",        //密碼 6~20位 任意
        "accountcode":"qwertyuioasdfghjkzxcvbnm",  //交易所用戶ID
        "brokerage":"virtual",        //券商
        "type":"normal",              //類型    normal:普通  try:試練  trade:操盤手
        "exchangerate":"2.5"          //交易費率
}
Response:
{
        "statusCode":"000000",
        "result":{
            "uuid":"dsaf6d87sfa89sdf7asdfhasdilfakds",
            "aliasname":"lichen",
            "password":"1a2bc3d4e5f6g7h8i9j0k",
            "accountcode":"qwertyuioasdfghjkzxcvbnm",
            "brokerage":"virtual",
            "exchangerate":"2.5",
            "type":"normal",
            "status":"0",
            "followid":""
         }
}

2. 關(guān)閉股票賬戶

/servlet/closestockaccount

Request:
{
        "stockaccountid":"dsaf6d87sfa89sdf7asdfhasdilfakds", //賬戶ID
}
Response:
{
        "statusCode":"000000",
        "result":"ok"
}

3. 修改密碼

/servlet/changepassword
此接口 需要先到虛擬交易所修改后,這里才能生效

Request:
{
        "stockaccountid":"dsaf6d87sfa89sdf7asdfhasdilfakds", //賬戶ID
        "password":"12345678",        //密碼 6~20位 任意
}
Response:
{
        "statusCode":"000000",
        "result":{
            "uuid":"dsaf6d87sfa89sdf7asdfhasdilfakds",
            "aliasname":"lichen",
            "password":"1a2bc3d4e5f6g7h8i9j0k",
            "accountcode":"qwertyuioasdfghjkzxcvbnm",
            "brokerage":"virtual",
            "exchangerate":"2.5",
            "type":"normal",
            "status":"0",
            "followid":""
         }
}

4. 修改類型

/servlet/changetype

Request:
{
        "stockaccountid":"dsaf6d87sfa89sdf7asdfhasdilfakds", //賬戶ID
        "type":"try",              //類型    normal:普通  try:試練  trade:操盤手
}
Response:
{
        "statusCode":"000000",
        "result":{
            "uuid":"dsaf6d87sfa89sdf7asdfhasdilfakds",
            "aliasname":"lichen",
            "password":"1a2bc3d4e5f6g7h8i9j0k",
            "accountcode":"qwertyuioasdfghjkzxcvbnm",
            "brokerage":"virtual",
            "exchangerate":"2.5",
            "type":"try",
            "status":"0",
            "followid":""
         }
}

5. 跟隨操盤手

/servlet/followtrader
此賬戶需要是 普通賬戶,并且跟隨的操盤賬戶需要是試練或者操盤手

Request:
{
        "stockaccountid":"234jk32khi2u4wejfq432nrkew23jknk", //賬戶ID
        "password":"12345678",                               //密碼 6~20位 任意
        "followid":"dsaf6d87sfa89sdf7asdfhasdilfakds",       //跟隨操盤賬戶ID
}
Response:
{
        "statusCode":"000000",
        "result":{
            "uuid":"234jk32khi2u4wejfq432nrkew23jknk",
            "aliasname":"xiaoming",
            "password":"1a2bc3d4e5f6g7h8i9j0k",
            "accountcode":"kmfjo3m2f98dsn4iund8s4nijruvh2",
            "brokerage":"virtual",
            "exchangerate":"2.5",
            "type":"normal",
            "status":"0",
            "followid":"dsaf6d87sfa89sdf7asdfhasdilfakds"
         }
}

6. 解除跟隨操盤手

/servlet/unfollowtrader

Request:
{
        "stockaccountid":"234jk32khi2u4wejfq432nrkew23jknk", //賬戶ID
        "password":"12345678",                               //密碼 6~20位 任意
}
Response:
{
        "statusCode":"000000",
        "result":{
            "uuid":"234jk32khi2u4wejfq432nrkew23jknk",
            "aliasname":"xiaoming",
            "password":"1a2bc3d4e5f6g7h8i9j0k",
            "accountcode":"kmfjo3m2f98dsn4iund8s4nijruvh2",
            "brokerage":"virtual",
            "exchangerate":"2.5",
            "type":"normal",
            "status":"0",
            "followid":""
         }
}

7. 買入股票

/servlet/buystock

Request:
{
        "stockaccountid":"dsaf6d87sfa89sdf7asdfhasdilfakds", //賬戶ID
        "password":"12345678",                        //密碼 6~20位
        "stockcode":"601988",                         //股票代碼
        "count":"1000"                                //買入數(shù)量
        "execute":"true",                             //是否真實執(zhí)行
}
Response:
{
        "statusCode":"000000",
        "result":{
            "stockaccountid":"dsaf6d87sfa89sdf7asdfhasdilfakds"
            "stockcode":"601988",
            "type":"buy",
            "price":"7.12",
            "count":"1000",
            "holdstockbefore":"0",
            "holdstockafter":"1000",
            "balancebefore":"46000",
            "balanceafter":"38862.2",
            "exchangeamount":"17.8",
            "stockamount":"7120",
            "totalamount":"7137.8"
        }
}

8. 買出股票

/servlet/sellstock

Request:
{
        "stockaccountid":"dsaf6d87sfa89sdf7asdfhasdilfakds", //賬戶ID
        "password":"12345678",                        //密碼 6~20位
        "stockcode":"601988",                         //股票代碼
        "count":"1000"                                //買入數(shù)量
        "execute":"true",                             //是否真實執(zhí)行
}
Response:
{
        "statusCode":"000000",
        "result":{
            "stockaccountid":"dsaf6d87sfa89sdf7asdfhasdilfakds"
            "stockcode":"601988",
            "type":"sell",
            "price":"7.12",
            "count":"1000",
            "holdstockbefore":"0",
            "holdstockafter":"1000",
            "balancebefore":"38862.2",
            "balanceafter":"45964.4",
            "exchangeamount":"17.8",
            "stockamount":"7120",
            "totalamount":"7102.2",
            "createtime":"2017-06-13 15:18:32"
        }
}

9. 統(tǒng)計數(shù)據(jù)

/servlet/commandcount

Request:
{
        "duration":"100",                         //間隔時間
        "samplerate":"2",                         //采樣率
}
Response:
{
        "statusCode":"000000",
        "result":{
            "stockaccountid":"dsaf6d87sfa89sdf7asdfhasdilfakds"
            "stockcode":"601988",
            "type":"sell",
            "price":"7.12",
            "count":"1000",
            "holdstockbefore":"0",
            "holdstockafter":"1000",
            "balancebefore":"38862.2",
            "balanceafter":"45964.4",
            "exchangeamount":"17.8",
            "stockamount":"7120",
            "totalamount":"7102.2",
            "createtime":"2017-06-13 15:18:32"
        }
}

Cache存儲結(jié)構(gòu)

|名稱|說明|結(jié)構(gòu)|
|:--|:--:|
|cachekey_stockaccount_uuid|賬戶集合|Map<uuid,StockAccountMap>|
|cachekey_stockaccount_accountcode|賬戶名集合|Map<accountcodeid, StockAccountMap >|
| cachekey_stockaccount_followid|跟隨賬戶集合|Map<followid, List<StockAccountMap>>|
|cachekey_stockdata_600189|股票信息|JSON|

數(shù)據(jù)算法

配置文件

配置項 默認(rèn)值 說明
TASK_THREADPOOL_SIZE 100 任務(wù)執(zhí)行者數(shù)量
REQUEST_TRADE_THREADPOOL_SIZE 10 http請求線程數(shù)量
REQUEST_TRADE_MAXCOUNT 100 單詞請求最大命令數(shù)量
IS_FAKE_TRADE false 是否使用假交易所
MAX_NEW_COMMAND_COUNT 最大新指令數(shù)量
TRADE_VIRTUAL_BASEURL 虛擬交易所地址
COMMAND_FILE_ROOT 指令文件夾

文件夾

hero 為父命令文件夾
每一個父命令均創(chuàng)建一個命令組文件夾,組文件夾名是每個小時做一個基礎(chǔ)名,后面跟著自增數(shù)列,每個文件夾中只有一個文件,就是操盤手的指令文件。
new 為命令文件夾
hero文件夾里面將父指令拷貝到new文件夾中,并通過查詢跟隨賬戶,為每一個跟隨賬戶創(chuàng)建指令文件。最后將hero中的父命令文件刪除。
這是一個命令放大器,如果被放大的命令太多,會導(dǎo)致inodes過大,所以在配置文件中指定了一個最大新指令數(shù)量。
dispatched 為分發(fā)文件夾
分發(fā)任務(wù)從new文件夾里獲得任務(wù),并移動到dispatched文件夾中,這些待執(zhí)行命令按照賬戶分別分配給了每個賬戶的執(zhí)行者,有單獨線程驅(qū)動執(zhí)行中進(jìn)行一步一步執(zhí)行。
執(zhí)行者總共有6步:

1. 獲取一個命令,并按照賬戶寫入命令文件(每天一個),將文件從`dispatched`移動到`process`中
2. 發(fā)送查詢請求,等待響應(yīng)
3. 獲得查詢結(jié)果,將查詢結(jié)果保存到命令對象中
4. 發(fā)送交易請求,等待響應(yīng)
5. 獲得交易結(jié)果,將交易結(jié)果保存到命令對象中
6. 事后處理,補寫賬戶命令文件,將文件寫入到`finished`中,并刪除`process`中的文件

database 為數(shù)據(jù)庫文件夾
將完成的命令,寫入到入庫文件中new.db,此文件所在的文件夾為每分鐘一個。當(dāng)數(shù)據(jù)庫準(zhǔn)備執(zhí)行時,將此文件改名為process.db
history 為數(shù)據(jù)庫歷史文件夾
入庫完成后,將process.db文件內(nèi)容寫入到歷史文件中,此文件每小時一個,并刪除process.db文件

new 為命令文件夾
dispatched 為分發(fā)文件夾
process 為執(zhí)行文件夾
finished 為完成文件夾
這4個文件夾結(jié)構(gòu)完全一致,分別代表任務(wù)所處階段。

文件夾示例

[-]/CacheFile/SyncCommand
    [-]hero
         [-]GID20160814165223_00000000009.cmd   #組ID
             [+]a1s23d3d4f5g6h76j87jk90.cmd       #操盤手命令
    [-]new
             [-]GID20160814165223_00000000007.cmd   #組ID
                   [+]a1s23d3d4f5g6h76j87jk90.cmd       #操盤手命令
                   [+]s23d4f5g6h7j8k9k8j7h6g5.cmd      #跟隨命令
                   [+]z12x3c4v5b6n78m8mn7b6.cmd      #跟隨命令
                   [+]4c3xz28u7y6t5r4e3w2q3e.cmd      #跟隨命令
             [-]GID20160814165223_00000000008.cmd   #組ID
                   [+]a1s23d3d4f5g6h76j87jk90.cmd       #操盤手命令
                   [+]s23d4f5g6h7j8k9k8j7h6g5.cmd      #跟隨命令
                   [+]z12x3c4v5b6n78m8mn7b6.cmd      #跟隨命令
                   [+]4c3xz28u7y6t5r4e3w2q3e.cmd      #跟隨命令
    [-]dispatched
             [-]GID20160814165223_00000000005.cmd   #組ID
                   [+]z12x3c4v5b6n78m8mn7b6.cmd      #跟隨命令
                   [+]4c3xz28u7y6t5r4e3w2q3e.cmd      #跟隨命令
            [-]GID20160814165223_00000000006.cmd   #組ID
                   [+]a1s23d3d4f5g6h76j87jk90.cmd       #操盤手命令
                   [+]s23d4f5g6h7j8k9k8j7h6g5.cmd      #跟隨命令
                   [+]z12x3c4v5b6n78m8mn7b6.cmd      #跟隨命令
    [-]process
            [-]GID20160814165223_00000000005.cmd   #組ID
                   [+]a1s23d3d4f5g6h76j87jk90.cmd       #操盤手命令
                   [+]s23d4f5g6h7j8k9k8j7h6g5.cmd      #跟隨命令
            [-]GID20160814165223_00000000006.cmd   #組ID
                   [+]4c3xz28u7y6t5r4e3w2q3e.cmd      #跟隨命令
    [-]database
            [-]201608141622.cmd       #每分鐘一個文件夾
                  [+]process.db        #正在入庫的文件
            [-]201608141623.cmd       #每分鐘一個文件夾
                   [+]new.db      #待入庫的文件
            [-]201608141624.cmd       #每分鐘一個文件夾
                   [+]new.db      #待入庫的文件
    [-]history
            [+]2016081415.cmd       #每小時一個文件
            [+]2016081416.cmd       #每小時一個文件

技巧

線程使用技巧

當(dāng)處于高頻HTTP發(fā)送的時候,有兩種解決方案:

1.使用單線程異步請求
做一個任務(wù)隊列,和請求類列表(回調(diào)使用),然后單線程來獲得隊列中任務(wù),制作成請求,調(diào)用異步請求,并將請求ID作為Attribute傳出,在異步獲得結(jié)果后,取出請求ID以及結(jié)果,在請求類列表中找到指定的請求,將結(jié)果作為參數(shù)去調(diào)用回調(diào)方法。

此方案優(yōu)點: 寫法簡單明了 缺點:單線程調(diào)用
注意: 異步請求

2.使用多線程同步請求
做指定線程數(shù)量的線程池,和任務(wù)執(zhí)行實例,做一個請求任務(wù)隊列,然后單線程來獲得一個執(zhí)行類,判斷是否是空閑,并讓線程池啟動執(zhí)行類,執(zhí)行類啟動后,從任務(wù)列表中獲取任務(wù),制作成請求,調(diào)用同步請求,獲得結(jié)果后,將結(jié)果作為參數(shù)去調(diào)用請求的回調(diào)方法。

此方案優(yōu)點: 多線程調(diào)用 可以指定若干執(zhí)行實例,由線程池控制執(zhí)行線程數(shù) 缺點:結(jié)構(gòu)復(fù)雜,不便于維護
注意:在線程池執(zhí)行任務(wù)前,需要先判斷線程是否運行,這里防止多任務(wù)進(jìn)入單線程,將前任務(wù)覆蓋。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容