碎碎念
心心念念的量化決策念叨了好久炫惩,前段時(shí)間終于把excel版的決策模板做出來了,但是一遍遍手動(dòng)錄入市價(jià)數(shù)據(jù)太繁瑣,這周利用閑暇學(xué)習(xí)python,終于寫出了自己的第一段量化決策代碼嫁艇。
沒有圖的道理都是耍流氓,話不多說弦撩,上圖步咪!
平臺(tái)選擇
前期簡單了解了一下,目前國內(nèi)主流的量化平臺(tái)如下:
- 優(yōu)礦(Uqer)
- 萬礦(Wind Quant)
- 聚寬(JoinQuant)
- BigQuant
- 文華財(cái)經(jīng)
- 同花順Mind Go
- 米筐(RiceQuant)
- 掘金量化
優(yōu)礦是最早做的益楼,但是近一年社區(qū)沒那么活躍了歧斟;
萬礦依托國內(nèi)最強(qiáng)大的金融數(shù)據(jù)端wind提供數(shù)據(jù)支持;
聚寬社區(qū)挺活躍的偏形,但是用了幾天感覺用戶體驗(yàn)不太好,尤其是新手接入這塊兒存在斷層觉鼻。
思慮再三俊扭,決定從萬礦入手,畢竟有wind的數(shù)據(jù)支持坠陈,數(shù)據(jù)可靠性還是很有保證的萨惑。
設(shè)計(jì)思路
小插曲
因?yàn)樯现芪鍎偨佑|python捐康,對(duì)這塊還不夠熟悉,加之對(duì)pandas庸蔼、numpy等數(shù)據(jù)操作庫的生疏解总,決定從excel開始構(gòu)建數(shù)據(jù),而非在python中從0開始捏數(shù)據(jù)姐仅。
之前設(shè)計(jì)的excel模板有些不適合代碼讀取后提取有用信息花枫,故做了簡單的整理改造,改造后各表結(jié)構(gòu)如下:
整體思路:
- 讀取excel掏膏,提取各表數(shù)據(jù)
- 根據(jù)'標(biāo)的池'表代碼劳翰,查詢各標(biāo)的最新 市價(jià)
- 結(jié)合'標(biāo)的持倉'表持倉數(shù),計(jì)算最新 持倉市值
- 根據(jù)持倉情況馒疹,計(jì)算 當(dāng)前倉位
- 結(jié)合當(dāng)前倉位佳簸、目標(biāo)倉位和'調(diào)倉參數(shù)'表的配置,計(jì)算 動(dòng)態(tài)倉位
- 根據(jù)調(diào)倉參數(shù)表的可分配資金和持倉市值計(jì)算 可分配價(jià)值
- 根據(jù)可分配價(jià)值和動(dòng)態(tài)倉位確定 目標(biāo)市值
- 再借此計(jì)算 價(jià)值偏移颖变、應(yīng)調(diào)倉數(shù) 和 調(diào)倉金額
代碼實(shí)現(xiàn)
- 引入萬礦依賴并建立連接
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 引入萬礦依賴并建立連接
from WindPy import *
w.start(show_welcome = False)
- 引入pandas依賴生均,用以數(shù)據(jù)處理
# 引入pandas依賴,用以數(shù)據(jù)處理
import pandas as pd
- 定義持倉處理函數(shù):獲取市價(jià)腥刹,計(jì)算最新持倉市值
# 處理持倉
def work_flow1(stockpool,positions):
codes=stockpool['代碼'].tolist()
# 獲取行情
error,prices=w.wsq(codes, 'rt_last', "func=DemoWSQCallback", usedf=True)
assert error ==0 , "API數(shù)據(jù)提取錯(cuò)誤马胧,ErrorCode={},具體含義請(qǐng)至幫助文檔附件《常見API錯(cuò)誤碼》中查詢肛走。".format(error)
# 行情數(shù)據(jù)處理:拼接市價(jià)漓雅、計(jì)算持倉市值
positions=pd.merge(positions,prices,left_on='代碼', right_index=True, how='left')
positions['市價(jià)']=positions.pop('RT_LAST')
positions['持倉市值'] = positions.apply(lambda r: round(r['市價(jià)'] * r['持倉數(shù)']),axis=1)
return positions
- 定義決策處理函數(shù):根據(jù)持倉情況和調(diào)倉配置,作出調(diào)倉決策
# 處理決策
def work_flow2(positions,param,decision):
market_cap = positions['持倉市值'].sum() # 持倉市值合計(jì)
step = param.loc[param['名稱'] == '調(diào)整步數(shù)']['值'].iloc[0] # 分步數(shù)
amt = param.loc[param['名稱'] == '當(dāng)次投入額']['值'].iloc[0] # 手頭現(xiàn)金
value_cap=market_cap+amt # 可支配價(jià)值
print('持倉市值合計(jì):%d朽色,可支配價(jià)值:%d' % (market_cap,value_cap))
def action(row):
pos = positions.loc[positions['代碼'] == row['代碼']].iloc[0]
row['當(dāng)前倉位'] = round(pos['持倉市值'] / value_cap, 4)
row['動(dòng)態(tài)倉位'] = round(row['當(dāng)前倉位'] + (row['目標(biāo)倉位'] - row['當(dāng)前倉位']) / step, 4)
# 目標(biāo)市值
tar_value = row['動(dòng)態(tài)倉位'] * value_cap
row['價(jià)值偏移'] = round((pos['持倉市值'] - tar_value) / tar_value, 4)
row['應(yīng)調(diào)倉數(shù)'] = round((tar_value - pos['持倉市值']) / pos['市價(jià)'], -2)
row['調(diào)倉金額'] = round(row['應(yīng)調(diào)倉數(shù)'] * pos['市價(jià)'], 2)
return row
decision=decision.apply(action,axis=1)
return decision
- 編排工作流并執(zhí)行
# 工作流
def work_flow():
# 定義文件路徑和表名
data_from='data/榜單應(yīng)用模板20200424.xlsx'
stockpool_sheet='標(biāo)的池'
positions_sheet='標(biāo)的持倉'
param_sheet='調(diào)倉參數(shù)'
decision_sheet='調(diào)倉決策'
# 讀取模板e(cuò)xcel
stockpool = pd.read_excel (data_from, sheet_name = stockpool_sheet)
positions = pd.read_excel (data_from, sheet_name = positions_sheet)
param = pd.read_excel (data_from, sheet_name = param_sheet)
decision = pd.read_excel (data_from, sheet_name = decision_sheet)
# 處理持倉數(shù)據(jù)
positions=work_flow1(stockpool,positions)
# 處理決策
decision=work_flow2(positions,param,decision)
print('完成工作流邻吞!')
return stockpool,positions,param,decision
# 執(zhí)行工作流
df=work_flow()
- 展示持倉情況
# 持倉
from WindCharts import *
# 數(shù)據(jù)顯示
WTable(data=df[1]).plot()
- 展示決策情況
# 決策結(jié)果
from WindCharts import *
# 數(shù)據(jù)顯示
WTable(data=df[3]).plot()
- 為了直觀地分析持倉分布,定義了柱狀圖和餅狀圖
# 持倉柱狀圖
import matplotlib.pyplot as plt
def draw_bar(positions):
names=positions['名稱'].tolist()
values=positions['持倉市值'].tolist()
plt.bar(names,values)
plt.xticks(rotation=90)
draw_bar(df[1])
# 持倉餅圖
import matplotlib.pyplot as plt
def draw_pie(positions):
positions=positions.loc[positions['持倉市值'] != 0,:].sort_values('持倉市值')
names=positions['名稱'].tolist()
values=positions['持倉市值'].tolist()
fig = plt.figure(facecolor='#f1f5f5')
ax=plt.axes([0,0,1.6,1.6])
patches,l_text,p_text=ax.pie(values,labels=names,autopct='%1.2f%%',startangle=90)
for t in l_text: t.set_size(20)
for t in p_text: t.set_size(18)
draw_pie(df[1])
Ending
項(xiàng)目地址:https://gitee.com/stephenshen/ark-quant/tree/master/first-quant
可以直接導(dǎo)入到萬礦
記得上傳數(shù)據(jù)表到指定位置
轉(zhuǎn)載請(qǐng)注明出處:http://www.reibang.com/p/b973a5f56213
謝謝~