日入上萬,Jack 年入百萬?
老讀者應(yīng)該知道,我炒股兩年多了。
從最開始的基金,到后來的股票,金額一直不大,最多就加到30萬。
漲勢(shì)最好的時(shí)候,差不多每天能有個(gè)近萬的浮盈,偶爾還有過浮盈近兩萬的時(shí)候。

自從今年2月份,股市開啟困難模式后,這樣的好日子就到頭了。
年初,大幾萬的浮盈,也折損了大半,再加上今年計(jì)劃要用到大錢,身體被掏空的那種。

股市投資這塊就保守了很多,基本固定在10萬左右的低倉位,重在參與了。
一直有讀者想看我理財(cái)類的文章,最開始應(yīng)允下來,后來仔細(xì)想了想。
你說,我一個(gè)技術(shù)類博主,寫理財(cái),那不是不務(wù)正業(yè)嗎?
況且,我也不是學(xué)金融出身的,雖然憑運(yùn)氣在股市賺過一些小錢,但畢竟咱不是專業(yè)的,不敢亂指揮。
最近突然轉(zhuǎn)念一想,理財(cái)+技術(shù),這個(gè)路子我倒是可以。
我很喜歡學(xué)新知識(shí),不僅僅局限于計(jì)算機(jī)技術(shù),時(shí)刻保持一顆好奇心,什么都想學(xué)點(diǎn)。
正好,近期打算出一篇量化交易的視頻,探討探討人工智能技術(shù),在投資股市這件事上的應(yīng)用。
學(xué)著學(xué)著,我發(fā)現(xiàn),這里面的水挺深,量化交易,并沒有我想像的那么好做,要學(xué)的知識(shí)有點(diǎn)多。
上周末,我花費(fèi)了一天的時(shí)間,算是剛剛?cè)雮€(gè)門。
今天,先整理分享下,量化交易的基礎(chǔ)知識(shí),為視頻做個(gè)熱身。
量化交易
量化交易就是,借助現(xiàn)代統(tǒng)計(jì)學(xué)和數(shù)學(xué)的方法,利用計(jì)算機(jī)技術(shù)來進(jìn)行交易的證券投資方式。
主要涵蓋的知識(shí)點(diǎn)如下:

數(shù)學(xué)、編程、金融、算法都得懂,哪里不會(huì)補(bǔ)哪里就行。
量化平臺(tái)
抓數(shù)據(jù),寫策略,在線交易,如果自己一個(gè)人來做,成本太高,不利于初期的學(xué)習(xí)。
我調(diào)研了一些量化分析平臺(tái),可以幫助我們聚焦到學(xué)習(xí)量化交易的策略學(xué)習(xí)上。
我覺得可以用來入門的平臺(tái)有:
聚寬 vnpy
量化交易的平臺(tái)有很多,比如掘金、米筐、優(yōu)礦等。
但適合入門的,可以直接看這聚寬和vnpy。
聚寬的社區(qū)比較活躍,有不少技術(shù)教程,適合新手入門。
https://www.joinquant.com/study
這里的知識(shí)點(diǎn),就有不少可以學(xué)習(xí),同時(shí)還有很多大佬分享自己的策略。
vnpy推薦的原因在于它是開源的,可以系統(tǒng)學(xué)習(xí)如何構(gòu)建一個(gè)量化交易系統(tǒng)。
https://github.com/vnpy/vnpy
如果想自己實(shí)現(xiàn)一個(gè)量化交易的框架,可以從這里參考很多代碼。
小試牛刀
聚寬量化交易平臺(tái)的使用,比較簡(jiǎn)單。
我們以這個(gè)平臺(tái)為例,講解一個(gè)簡(jiǎn)單的量化策略。
我們回歸問題的本質(zhì),買股票無非兩點(diǎn):
買哪支股票 何時(shí)買,何時(shí)賣
1、買哪支股票
投資者,選股票,最直接的就是看財(cái)務(wù)報(bào)表。
至少是包括資產(chǎn)負(fù)債表、損益表、現(xiàn)金流量表,這三表。
這里的數(shù)據(jù)就太多了,每個(gè)表都有各種各樣的指標(biāo)。
這些指標(biāo)數(shù)據(jù),在量化交易里,叫因子。
我理解,就是我們機(jī)器學(xué)習(xí)中,常說的特征,每一個(gè)因子都可以算作一個(gè)維度的特征。
我們可以,利用這些已知的數(shù)據(jù),構(gòu)建多維的特征數(shù)據(jù),然后將它交給機(jī)器學(xué)習(xí)算法,讓算法判斷這只股票,值不值得購(gòu)買。
這又回到了,做算法的老生常談的問題,選擇哪些特征,去擬合數(shù)據(jù)。
妥了,特征工程走起。

這些最底層的特征,屬于一種基礎(chǔ)的因子。
在量化交易中,還可以根據(jù)這些數(shù)據(jù),計(jì)算出更“高維”的因子,即特征。
比如凈資產(chǎn)收益率,英文縮寫叫ROE。
凈資產(chǎn)收益率就是公司稅后利潤(rùn)除以凈資產(chǎn)得到的百分比率。
即,凈資產(chǎn)收益率=凈利潤(rùn)/凈資產(chǎn)
凈利潤(rùn),在利潤(rùn)表里,凈資產(chǎn),在資產(chǎn)負(fù)債表。
凈資產(chǎn)收益率反映股東權(quán)益的收益水平,用以衡量公司運(yùn)用自有資本的效率。
指標(biāo)值越高,說明投資帶來的收益越高。該指標(biāo)體現(xiàn)了自有資本獲得凈收益的能力。
凈資產(chǎn)收益率,就是通過一些“低維”的特征,計(jì)算出的“高維”的特征。
選股票,其實(shí)就是根據(jù)這些指標(biāo),選擇出,你認(rèn)為值得投資的股票。
為了簡(jiǎn)化策略,這里就簡(jiǎn)單的,單一的,利用這個(gè)凈資產(chǎn)收益率ROE,作為我們的價(jià)值選股思想的指標(biāo)。
簡(jiǎn)單暴力一點(diǎn),計(jì)算當(dāng)前所有股票的ROE,由大到小排序,選擇top10,作為我們的股票持倉。
2、何時(shí)買,何時(shí)賣
投資者,都想買在低點(diǎn),賣在高點(diǎn)。
10塊錢買,100塊賣,賺個(gè)差價(jià),賺了90。
這個(gè)問題的本質(zhì)就是:低買高賣。
但現(xiàn)實(shí)往往是殘酷的。

何時(shí)買,何時(shí)賣,在量化交易中,有個(gè)指標(biāo),阻力支撐相對(duì)強(qiáng)度,即RSRS。
了解,阻力支撐相對(duì)強(qiáng)度,首先要知道什么是阻力位和支撐位。
阻力位是指目標(biāo)價(jià)格上漲時(shí)可能遇到的壓力,即交易者認(rèn)為賣方力量開始反超買方,從而價(jià)格難以繼續(xù)上漲或從此回調(diào)下跌的價(jià)位;
支撐位則是交易者認(rèn)為買方力量開始反超賣方,從而止跌或反彈上漲的價(jià)位。
阻力支撐相對(duì)強(qiáng)度是一種阻力位與支撐位的運(yùn)用方式,它不再把阻力位與支撐位當(dāng)做一個(gè)定值,而是看做一個(gè)變量,反應(yīng)了交易者對(duì)目前市場(chǎng)狀態(tài)頂?shù)椎囊环N預(yù)期判斷。
我們按照不同市場(chǎng)狀態(tài)分類來說明支撐阻力相對(duì)強(qiáng)度的應(yīng)用邏輯:
市場(chǎng)在上漲牛市中:
如果支撐明顯強(qiáng)于阻力,牛市持續(xù),價(jià)格加速上漲 如果阻力明顯強(qiáng)于支撐,牛市可能即將結(jié)束,價(jià)格見頂
市場(chǎng)在震蕩中:
如果支撐明顯強(qiáng)于阻力,牛市可能即將啟動(dòng) 如果阻力明顯強(qiáng)于支撐,熊市可能即將啟動(dòng)
市場(chǎng)在下跌熊市中:
如果支撐明顯強(qiáng)于阻力,熊市可能即將結(jié)束,價(jià)格見底 如果阻力明顯強(qiáng)于支撐,熊市持續(xù),價(jià)格加速下跌
每日最高價(jià)和最低價(jià)是一種阻力位與支撐位,它是當(dāng)日全體市場(chǎng)參與者的交易行為所認(rèn)可的阻力與支撐。一個(gè)很自然的想法是建立最高價(jià)和最低價(jià)的線性回歸,并計(jì)算出斜率。即:
當(dāng)斜率值很大時(shí),支撐強(qiáng)度大于阻力強(qiáng)度。在牛市中阻力漸小,上方上漲空間大;在熊市中支撐漸強(qiáng),下跌勢(shì)頭欲止。
當(dāng)斜率值很小時(shí),阻力強(qiáng)度大于支撐強(qiáng)度。在牛市中阻力漸強(qiáng),上漲勢(shì)頭漸止;在熊市中支撐漸松,下方下跌空間漸大。
RSRS指標(biāo)的計(jì)算,有兩種方法,第一種方法是直接將斜率作為指標(biāo)值,第二種方法是在斜率基礎(chǔ)上進(jìn)行標(biāo)準(zhǔn)化。
以第二種方法為例,RSRS斜率標(biāo)準(zhǔn)分指標(biāo)擇時(shí)策略如下:
取前M日的RSRS斜率時(shí)間序列。(M = 600) 計(jì)算當(dāng)日RSRS斜率的標(biāo)準(zhǔn)分:
其中,為前M日的斜率均值,為前M日的標(biāo)準(zhǔn)差。
若大于,則全倉買入;若小于,則賣出平倉。
其中,。
小試牛刀
OK,買哪支股票,以及何時(shí)買,何時(shí)賣,這兩個(gè)問題解決了,我們就可以開始寫代碼了。
這里需要先掌握,聚寬的使用方法,以及一些api。
這部分比較簡(jiǎn)單,直接平臺(tái)的官方手冊(cè)就行。
編寫如下代碼:
'''
策略思路:
選股:財(cái)務(wù)指標(biāo)選股
擇時(shí):RSRS擇時(shí)
持倉:有開倉信號(hào)時(shí)持有10只股票,不滿足時(shí)保持空倉
'''
# 導(dǎo)入函數(shù)庫
import statsmodels.api as sm
from pandas.stats.api import ols
# 初始化函數(shù),設(shè)定基準(zhǔn)等等
def initialize(context):
# 開啟動(dòng)態(tài)復(fù)權(quán)模式(真實(shí)價(jià)格)
set_option('use_real_price', True)
# 過濾掉order系列API產(chǎn)生的比error級(jí)別低的log
# log.set_level('order', 'error')
set_parameter(context)
### 股票相關(guān)設(shè)定 ###
# 股票類每筆交易時(shí)的手續(xù)費(fèi)是:買入時(shí)傭金萬分之三,賣出時(shí)傭金萬分之三加千分之一印花稅, 每筆交易傭金最低扣5塊錢
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
## 運(yùn)行函數(shù)(reference_security為運(yùn)行時(shí)間的參考標(biāo)的;傳入的標(biāo)的只做種類區(qū)分,因此傳入'000300.XSHG'或'510300.XSHG'是一樣的)
# 開盤前運(yùn)行
run_daily(before_market_open, time='before_open', reference_security='000300.XSHG')
# 開盤時(shí)運(yùn)行
run_daily(market_open, time='open', reference_security='000300.XSHG')
# 收盤后運(yùn)行
#run_daily(after_market_close, time='after_close', reference_security='000300.XSHG')
'''
==============================參數(shù)設(shè)置部分================================
'''
def set_parameter(context):
# 設(shè)置RSRS指標(biāo)中N, M的值
#統(tǒng)計(jì)周期
g.N = 18
#統(tǒng)計(jì)樣本長(zhǎng)度
g.M = 1100
#首次運(yùn)行判斷
g.init = True
#持倉股票數(shù)
g.stock_num = 10
#風(fēng)險(xiǎn)參考基準(zhǔn)
g.security = '000300.XSHG'
# 設(shè)定策略運(yùn)行基準(zhǔn)
set_benchmark(g.security)
#記錄策略運(yùn)行天數(shù)
g.days = 0
#set_benchmark(g.stock)
# 買入閾值
g.buy = 0.7
g.sell = -0.7
#用于記錄回歸后的beta值,即斜率
g.ans = []
#用于計(jì)算被決定系數(shù)加權(quán)修正后的貝塔值
g.ans_rightdev= []
# 計(jì)算2005年1月5日至回測(cè)開始日期的RSRS斜率指標(biāo)
prices = get_price(g.security, '2005-01-05', context.previous_date, '1d', ['high', 'low'])
highs = prices.high
lows = prices.low
g.ans = []
for i in range(len(highs))[g.N:]:
data_high = highs.iloc[i-g.N+1:i+1]
data_low = lows.iloc[i-g.N+1:i+1]
X = sm.add_constant(data_low)
model = sm.OLS(data_high,X)
results = model.fit()
g.ans.append(results.params[1])
#計(jì)算r2
g.ans_rightdev.append(results.rsquared)
## 開盤前運(yùn)行函數(shù)
def before_market_open(context):
# 輸出運(yùn)行時(shí)間
#log.info('函數(shù)運(yùn)行時(shí)間(before_market_open):'+str(context.current_dt.time()))
g.days += 1
# 給微信發(fā)送消息(添加模擬交易,并綁定微信生效)
send_message('策略正常,運(yùn)行第%s天~'%g.days)
## 開盤時(shí)運(yùn)行函數(shù)
def market_open(context):
security = g.security
# 填入各個(gè)日期的RSRS斜率值
beta=0
r2=0
if g.init:
g.init = False
else:
#RSRS斜率指標(biāo)定義
prices = attribute_history(security, g.N, '1d', ['high', 'low'])
highs = prices.high
lows = prices.low
X = sm.add_constant(lows)
model = sm.OLS(highs, X)
beta = model.fit().params[1]
g.ans.append(beta)
#計(jì)算r2
r2=model.fit().rsquared
g.ans_rightdev.append(r2)
# 計(jì)算標(biāo)準(zhǔn)化的RSRS指標(biāo)
# 計(jì)算均值序列
section = g.ans[-g.M:]
# 計(jì)算均值序列
mu = np.mean(section)
# 計(jì)算標(biāo)準(zhǔn)化RSRS指標(biāo)序列
sigma = np.std(section)
zscore = (section[-1]-mu)/sigma
#計(jì)算右偏RSRS標(biāo)準(zhǔn)分
zscore_rightdev= zscore*beta*r2
# 如果上一時(shí)間點(diǎn)的RSRS斜率大于買入閾值, 則全倉買入
if zscore_rightdev > g.buy:
# 記錄這次買入
log.info("市場(chǎng)風(fēng)險(xiǎn)在合理范圍")
#滿足條件運(yùn)行交易
trade_func(context)
# 如果上一時(shí)間點(diǎn)的RSRS斜率小于賣出閾值, 則空倉賣出
elif (zscore_rightdev < g.sell) and (len(context.portfolio.positions.keys()) > 0):
# 記錄這次賣出
log.info("市場(chǎng)風(fēng)險(xiǎn)過大,保持空倉狀態(tài)")
# 賣出所有股票,使這只股票的最終持有量為0
for s in context.portfolio.positions.keys():
order_target(s, 0)
#策略選股買賣部分
def trade_func(context):
#獲取股票池
df = get_fundamentals(query(valuation.code,valuation.pb_ratio,indicator.roe))
#進(jìn)行pb,roe大于0篩選
df = df[(df['roe']>0) & (df['pb_ratio']>0)].sort('pb_ratio')
#以股票名詞作為index
df.index = df['code'].values
#取roe倒數(shù)
df['1/roe'] = 1/df['roe']
#獲取綜合得分
df['point'] = df[['pb_ratio','1/roe']].rank().T.apply(f_sum)
#按得分進(jìn)行排序,取指定數(shù)量的股票
df = df.sort('point')[:g.stock_num]
pool = df.index
log.info('總共選出%s只股票'%len(pool))
#得到每只股票應(yīng)該分配的資金
cash = context.portfolio.total_value/len(pool)
#獲取已經(jīng)持倉列表
hold_stock = context.portfolio.positions.keys()
#賣出不在持倉中的股票
for s in hold_stock:
if s not in pool:
order_target(s,0)
#買入股票
for s in pool:
order_target_value(s,cash)
#打分工具
def f_sum(x):
return sum(x)
## 收盤后運(yùn)行函數(shù)
def after_market_close(context):
#得到當(dāng)天所有成交記錄
trades = get_trades()
for _trade in trades.values():
log.info('成交記錄:'+str(_trade))
#打印賬戶總資產(chǎn)
log.info('今日賬戶總資產(chǎn):%s'%round(context.portfolio.total_value,2))
#log.info('##############################################################')
左邊寫好代碼,輸入回測(cè)時(shí)間和金額就可以運(yùn)行了。

我直接回測(cè)了2010年1月到2020年1月效果,投資十年的收益:

直接起飛,初始資金50萬,賺了幾百萬,很穩(wěn)!

我又回測(cè)了2020年1月到2021年6月,一年半的收益:

跑輸大盤8.35%,不過也沒虧,年化率也能有個(gè)11.40%,還可以吧。
總結(jié)
這個(gè)策略,沒有用到歷史數(shù)據(jù),是根據(jù)當(dāng)前的一些指標(biāo)進(jìn)行決策的。
投資理財(cái),這方面的知識(shí),還是要學(xué)習(xí)的,不投資股市,買個(gè)銀行定期這些也挺好。
我們寒窗苦讀,一方面就是想學(xué)有所成,賺錢,過個(gè)舒服的生活。
學(xué)校教我們各種基礎(chǔ)知識(shí),唯獨(dú)很少直接地教我們,如何去賺錢,去理財(cái),管理自己的財(cái)富。
所以,自學(xué)吧。人生在于折騰,各種知識(shí)都學(xué)學(xué),挺好,挺有意思。
現(xiàn)在,雖然股市是困難模式,但是仍然有很多機(jī)會(huì),我們也可以利用這個(gè)時(shí)間,補(bǔ)充自己的知識(shí)。
年入百萬,對(duì)于現(xiàn)在的我來說,還是洗洗睡吧,夢(mèng)里什么都有。
本期硬核,喜歡的朋友,轉(zhuǎn)發(fā),點(diǎn)贊走一波,讓我瞧一瞧~
感興趣的人多,后面繼續(xù)出。
我是 Jack,我們下期見!

推薦閱讀
? 36525個(gè)日夜? AI算法,整新活? 計(jì)算機(jī)專業(yè)讀研三年,到底值不值
