經(jīng)典的股票/期貨量化交易策略秽五,拿來(lái)即用的Python策略源碼(1)

聲明:本文策略源碼均來(lái)自掘金量化示例策略庫(kù),僅供參考瞬痘!

一、股票策略


1.多因子選股

# coding=utf-8

from__future__importprint_function, absolute_import, unicode_literals

importnumpyasnp

fromgm.apiimport*

frompandasimportDataFrame

'''

本策略每隔1個(gè)月定時(shí)觸發(fā),根據(jù)Fama-French三因子模型對(duì)每只股票進(jìn)行回歸板熊,得到其alpha值框全。

假設(shè)Fama-French三因子模型可以完全解釋市場(chǎng),則alpha為負(fù)表明市場(chǎng)低估該股干签,因此應(yīng)該買(mǎi)入津辩。

策略思路:

計(jì)算市場(chǎng)收益率、個(gè)股的賬面市值比和市值,并對(duì)后兩個(gè)進(jìn)行了分類(lèi),

根據(jù)分類(lèi)得到的組合分別計(jì)算其市值加權(quán)收益率、SMB和HML.

對(duì)各個(gè)股票進(jìn)行回歸(假設(shè)無(wú)風(fēng)險(xiǎn)收益率等于0)得到alpha值.

選取alpha值小于0并為最小的10只股票進(jìn)入標(biāo)的池

平掉不在標(biāo)的池的股票并等權(quán)買(mǎi)入在標(biāo)的池的股票

回測(cè)數(shù)據(jù):SHSE.000300的成份股

回測(cè)時(shí)間:2017-07-01 08:00:00到2017-10-01 16:00:00

'''

definit(context):

# 每月第一個(gè)交易日的09:40 定時(shí)執(zhí)行algo任務(wù)

schedule(schedule_func=algo, date_rule='1m', time_rule='09:40:00')

print(order_target_percent(symbol='SHSE.600000', percent=0.5, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long))

# 數(shù)據(jù)滑窗

context.date =20

# 設(shè)置開(kāi)倉(cāng)的最大資金量

context.ratio =0.8

# 賬面市值比的大/中/小分類(lèi)

context.BM_BIG =3.0

context.BM_MID =2.0

context.BM_SMA =1.0

# 市值大/小分類(lèi)

context.MV_BIG =2.0

context.MV_SMA =1.0

# 計(jì)算市值加權(quán)的收益率,MV為市值的分類(lèi),BM為賬目市值比的分類(lèi)

defmarket_value_weighted(stocks, MV, BM):

? ? select = stocks[(stocks.NEGOTIABLEMV == MV) & (stocks.BM == BM)]

market_value = select['mv'].values

? ? mv_total = np.sum(market_value)

mv_weighted = [mv / mv_totalformvinmarket_value]

stock_return = select['return'].values

# 返回市值加權(quán)的收益率的和

? ? return_total = []

foriinrange(len(mv_weighted)):

? ? ? ? return_total.append(mv_weighted[i] * stock_return[i])

? ? return_total = np.sum(return_total)

returnreturn_total

defalgo(context):

# 獲取上一個(gè)交易日的日期

last_day = get_previous_trading_date(exchange='SHSE', date=context.now)

# 獲取滬深300成份股

context.stock300 = get_history_constituents(index='SHSE.000300', start_date=last_day,

end_date=last_day)[0]['constituents'].keys()

# 獲取當(dāng)天有交易的股票

? ? not_suspended = get_history_instruments(symbols=context.stock300, start_date=last_day, end_date=last_day)

not_suspended = [item['symbol']foriteminnot_suspendedifnotitem['is_suspended']]

fin = get_fundamentals(table='tq_sk_finindic', symbols=not_suspended, start_date=last_day, end_date=last_day,

fields='PB,NEGOTIABLEMV', df=True)

# 計(jì)算賬面市值比,為P/B的倒數(shù)

fin['PB'] = (fin['PB'] **-1)

# 計(jì)算市值的50%的分位點(diǎn),用于后面的分類(lèi)

size_gate = fin['NEGOTIABLEMV'].quantile(0.50)

# 計(jì)算賬面市值比的30%和70%分位點(diǎn),用于后面的分類(lèi)

bm_gate = [fin['PB'].quantile(0.30), fin['PB'].quantile(0.70)]

? ? fin.index = fin.symbol

? ? x_return = []

# 對(duì)未停牌的股票進(jìn)行處理

forsymbolinnot_suspended:

# 計(jì)算收益率

close = history_n(symbol=symbol, frequency='1d', count=context.date +1, end_time=last_day, fields='close',

skip_suspended=True, fill_missing='Last', adjust=ADJUST_PREV, df=True)['close'].values

stock_return = close[-1] / close[0] -1

pb = fin['PB'][symbol]

market_value = fin['NEGOTIABLEMV'][symbol]

# 獲取[股票代碼. 股票收益率, 賬面市值比的分類(lèi), 市值的分類(lèi), 流通市值]

ifpb < bm_gate[0]:

ifmarket_value < size_gate:

? ? ? ? ? ? ? ? label = [symbol, stock_return, context.BM_SMA, context.MV_SMA, market_value]

else:

? ? ? ? ? ? ? ? label = [symbol, stock_return, context.BM_SMA, context.MV_BIG, market_value]

elifpb < bm_gate[1]:

ifmarket_value < size_gate:

? ? ? ? ? ? ? ? label = [symbol, stock_return, context.BM_MID, context.MV_SMA, market_value]

else:

? ? ? ? ? ? ? ? label = [symbol, stock_return, context.BM_MID, context.MV_BIG, market_value]

elifmarket_value < size_gate:

? ? ? ? ? ? label = [symbol, stock_return, context.BM_BIG, context.MV_SMA, market_value]

else:

? ? ? ? ? ? label = [symbol, stock_return, context.BM_BIG, context.MV_BIG, market_value]

iflen(x_return) ==0:

? ? ? ? ? ? x_return = label

else:

? ? ? ? ? ? x_return = np.vstack([x_return, label])

stocks = DataFrame(data=x_return, columns=['symbol','return','BM','NEGOTIABLEMV','mv'])

? ? stocks.index = stocks.symbol

columns = ['return','BM','NEGOTIABLEMV','mv']

forcolumnincolumns:

? ? ? ? stocks[column] = stocks[column].astype(np.float64)

# 計(jì)算SMB.HML和市場(chǎng)收益率

# 獲取小市值組合的市值加權(quán)組合收益率

? ? smb_s = (market_value_weighted(stocks, context.MV_SMA, context.BM_SMA) +

? ? ? ? ? ? market_value_weighted(stocks, context.MV_SMA, context.BM_MID) +

market_value_weighted(stocks, context.MV_SMA, context.BM_BIG)) /3

# 獲取大市值組合的市值加權(quán)組合收益率

? ? smb_b = (market_value_weighted(stocks, context.MV_BIG, context.BM_SMA) +

? ? ? ? ? ? market_value_weighted(stocks, context.MV_BIG, context.BM_MID) +

market_value_weighted(stocks, context.MV_BIG, context.BM_BIG)) /3

? ? smb = smb_s - smb_b

# 獲取大賬面市值比組合的市值加權(quán)組合收益率

hml_b = (market_value_weighted(stocks, context.MV_SMA,3) +

market_value_weighted(stocks, context.MV_BIG, context.BM_BIG)) /2

# 獲取小賬面市值比組合的市值加權(quán)組合收益率

? ? hml_s = (market_value_weighted(stocks, context.MV_SMA, context.BM_SMA) +

market_value_weighted(stocks, context.MV_BIG, context.BM_SMA)) /2

? ? hml = hml_b - hml_s

close = history_n(symbol='SHSE.000300', frequency='1d', count=context.date +1,

end_time=last_day, fields='close', skip_suspended=True,

fill_missing='Last', adjust=ADJUST_PREV, df=True)['close'].values

market_return = close[-1] / close[0] -1

? ? coff_pool = []

# 對(duì)每只股票進(jìn)行回歸獲取其alpha值

forstockinstocks.index:

x_value = np.array([[market_return], [smb], [hml], [1.0]])

y_value = np.array([stocks['return'][stock]])

# OLS估計(jì)系數(shù)

coff = np.linalg.lstsq(x_value.T, y_value)[0][3]

? ? ? ? coff_pool.append(coff)

# 獲取alpha最小并且小于0的10只的股票進(jìn)行操作(若少于10只則全部買(mǎi)入)

stocks['alpha'] = coff_pool

stocks = stocks[stocks.alpha <0].sort_values(by='alpha').head(10)

? ? symbols_pool = stocks.index.tolist()

? ? positions = context.account().positions()

# 平不在標(biāo)的池的股票

forpositioninpositions:

symbol = position['symbol']

ifsymbolnotinsymbols_pool:

order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print('市價(jià)單平不在標(biāo)的池的', symbol)

# 獲取股票的權(quán)重

? ? percent = context.ratio / len(symbols_pool)

# 買(mǎi)在標(biāo)的池中的股票

forsymbolinsymbols_pool:

? ? ? ? order_target_percent(symbol=symbol, percent=percent, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print(symbol,'以市價(jià)單調(diào)多倉(cāng)到倉(cāng)位', percent)

if__name__ =='__main__':

'''

? ? strategy_id策略ID,由系統(tǒng)生成

? ? filename文件名,請(qǐng)與本文件名保持一致

? ? mode實(shí)時(shí)模式:MODE_LIVE回測(cè)模式:MODE_BACKTEST

? ? token綁定計(jì)算機(jī)的ID,可在系統(tǒng)設(shè)置-密鑰管理中生成

? ? backtest_start_time回測(cè)開(kāi)始時(shí)間

? ? backtest_end_time回測(cè)結(jié)束時(shí)間

? ? backtest_adjust股票復(fù)權(quán)方式不復(fù)權(quán):ADJUST_NONE前復(fù)權(quán):ADJUST_PREV后復(fù)權(quán):ADJUST_POST

? ? backtest_initial_cash回測(cè)初始資金

? ? backtest_commission_ratio回測(cè)傭金比例

? ? backtest_slippage_ratio回測(cè)滑點(diǎn)比例

? ? '''

run(strategy_id='strategy_id',

filename='main.py',

? ? ? ? mode=MODE_BACKTEST,

token='token_id',

backtest_start_time='2017-07-01 08:00:00',

backtest_end_time='2017-10-01 16:00:00',

? ? ? ? backtest_adjust=ADJUST_PREV,

backtest_initial_cash=10000000,

backtest_commission_ratio=0.0001,

backtest_slippage_ratio=0.0001)

2.日內(nèi)回轉(zhuǎn)交易

# coding=utf-8

from__future__importprint_function, absolute_import, unicode_literals

try:

importtalib

except:

print('請(qǐng)安裝TA-Lib庫(kù)')

fromgm.apiimport*

'''

本策略首先買(mǎi)入SHSE.600000股票10000股

隨后根據(jù)60s的數(shù)據(jù)來(lái)計(jì)算MACD(12,26,9)線(xiàn),并在MACD>0的時(shí)候買(mǎi)入100股,MACD<0的時(shí)候賣(mài)出100股

但每日操作的股票數(shù)不超過(guò)原有倉(cāng)位,并于收盤(pán)前把倉(cāng)位調(diào)整至開(kāi)盤(pán)前的倉(cāng)位

回測(cè)數(shù)據(jù)為:SHSE.600000的60s數(shù)據(jù)

回測(cè)時(shí)間為:2017-09-01 08:00:00到2017-10-01 16:00:00

'''

definit(context):

# 設(shè)置標(biāo)的股票

context.symbol ='SHSE.600000'

# 用于判定第一個(gè)倉(cāng)位是否成功開(kāi)倉(cāng)

context.first =0

# 訂閱浦發(fā)銀行, bar頻率為1min

subscribe(symbols=context.symbol, frequency='60s', count=35)

# 日內(nèi)回轉(zhuǎn)每次交易100股

context.trade_n =100

# 獲取昨今天的時(shí)間

context.day = [0,0]

# 用于判斷是否觸發(fā)了回轉(zhuǎn)邏輯的計(jì)時(shí)

context.ending =0

defon_bar(context, bars):

bar = bars[0]

ifcontext.first ==0:

# 最開(kāi)始配置倉(cāng)位

# 需要保持的總倉(cāng)位

context.total =10000

# 購(gòu)買(mǎi)10000股浦發(fā)銀行股票

? ? ? ? order_volume(symbol=context.symbol, volume=context.total, side=PositionSide_Long,

? ? ? ? ? ? ? ? ? ? order_type=OrderType_Market, position_effect=PositionEffect_Open)

print(context.symbol,'以市價(jià)單開(kāi)多倉(cāng)10000股')

context.first =1.

day = bar.bob.strftime('%Y-%m-%d')

context.day[-1] = day[-2:]

# 每天的倉(cāng)位操作

context.turnaround = [0,0]

return

# 更新最新的日期

day = bar.bob.strftime('%Y-%m-%d %H:%M:%S')

context.day[0] = bar.bob.day

# 若為新的一天,獲取可用于回轉(zhuǎn)的昨倉(cāng)

ifcontext.day[0] != context.day[-1]:

context.ending =0

context.turnaround = [0,0]

ifcontext.ending ==1:

return

# 若有可用的昨倉(cāng)則操作

ifcontext.total >=0:

# 獲取時(shí)間序列數(shù)據(jù)

symbol = bar['symbol']

recent_data = context.data(symbol=symbol, frequency='60s', count=35, fields='close')

# 計(jì)算MACD線(xiàn)

macd = talib.MACD(recent_data['close'].values)[0][-1]

# 根據(jù)MACD>0則開(kāi)倉(cāng),小于0則平倉(cāng)

ifmacd >0:

# 多空單向操作都不能超過(guò)昨倉(cāng)位,否則最后無(wú)法調(diào)回原倉(cāng)位

ifcontext.turnaround[0] + context.trade_n < context.total:

# 計(jì)算累計(jì)倉(cāng)位

context.turnaround[0] += context.trade_n

? ? ? ? ? ? ? ? order_volume(symbol=context.symbol, volume=context.trade_n, side=PositionSide_Long,

? ? ? ? ? ? ? ? ? ? ? ? ? ? order_type=OrderType_Market, position_effect=PositionEffect_Open)

print(symbol,'市價(jià)單開(kāi)多倉(cāng)', context.trade_n,'股')

elifmacd <0:

ifcontext.turnaround[1] + context.trade_n < context.total:

context.turnaround[1] += context.trade_n

? ? ? ? ? ? ? ? order_volume(symbol=context.symbol, volume=context.trade_n, side=PositionSide_Short,

? ? ? ? ? ? ? ? ? ? ? ? ? ? order_type=OrderType_Market, position_effect=PositionEffect_Close)

print(symbol,'市價(jià)單平多倉(cāng)', context.trade_n,'股')

# 臨近收盤(pán)時(shí)若倉(cāng)位數(shù)不等于昨倉(cāng)則回轉(zhuǎn)所有倉(cāng)位

ifday[11:16] =='14:55'orday[11:16] =='14:57':

? ? ? ? ? ? position = context.account().position(symbol=context.symbol, side=PositionSide_Long)

ifposition['volume'] != context.total:

? ? ? ? ? ? ? ? order_target_volume(symbol=context.symbol, volume=context.total, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print('市價(jià)單回轉(zhuǎn)倉(cāng)位操作...')

context.ending =1

# 更新過(guò)去的日期數(shù)據(jù)

context.day[-1] = context.day[0]

if__name__ =='__main__':

'''

? ? strategy_id策略ID,由系統(tǒng)生成

? ? filename文件名,請(qǐng)與本文件名保持一致

? ? mode實(shí)時(shí)模式:MODE_LIVE回測(cè)模式:MODE_BACKTEST

? ? token綁定計(jì)算機(jī)的ID,可在系統(tǒng)設(shè)置-密鑰管理中生成

? ? backtest_start_time回測(cè)開(kāi)始時(shí)間

? ? backtest_end_time回測(cè)結(jié)束時(shí)間

? ? backtest_adjust股票復(fù)權(quán)方式不復(fù)權(quán):ADJUST_NONE前復(fù)權(quán):ADJUST_PREV后復(fù)權(quán):ADJUST_POST

? ? backtest_initial_cash回測(cè)初始資金

? ? backtest_commission_ratio回測(cè)傭金比例

? ? backtest_slippage_ratio回測(cè)滑點(diǎn)比例

? ? '''

run(strategy_id='strategy_id',

filename='main.py',

? ? ? ? mode=MODE_BACKTEST,

token='token_id',

backtest_start_time='2017-09-01 08:00:00',

backtest_end_time='2017-10-01 16:00:00',

? ? ? ? backtest_adjust=ADJUST_PREV,

backtest_initial_cash=2000000,

backtest_commission_ratio=0.0001,

backtest_slippage_ratio=0.0001)

3.指數(shù)增強(qiáng)

# coding=utf-8

from__future__importprint_function, absolute_import, unicode_literals

importnumpyasnp

fromgm.apiimport*

frompandasimportDataFrame

'''

本策略以0.8為初始權(quán)重跟蹤指數(shù)標(biāo)的滬深300中權(quán)重大于0.35%的成份股.

個(gè)股所占的百分比為(0.8*成份股權(quán)重)*100%.然后根據(jù)個(gè)股是否:

1.連續(xù)上漲5天 2.連續(xù)下跌5天

來(lái)判定個(gè)股是否為強(qiáng)勢(shì)股/弱勢(shì)股,并對(duì)其把權(quán)重由0.8調(diào)至1.0或0.6

回測(cè)時(shí)間為:2017-07-01 08:50:00到2017-10-01 17:00:00

'''

definit(context):

# 資產(chǎn)配置的初始權(quán)重,配比為0.6-0.8-1.0

context.ratio =0.8

# 獲取滬深300當(dāng)時(shí)的成份股和相關(guān)數(shù)據(jù)

stock300 = get_history_constituents(index='SHSE.000300', start_date='2017-06-30', end_date='2017-06-30')[0][

'constituents']

? ? stock300_symbol = []

? ? stock300_weight = []

forkeyinstock300:

# 保留權(quán)重大于0.35%的成份股

if(stock300[key] /100) >0.0035:

? ? ? ? ? ? stock300_symbol.append(key)

stock300_weight.append(stock300[key] /100)

context.stock300 = DataFrame([stock300_weight], columns=stock300_symbol, index=['weight']).T

print('選擇的成分股權(quán)重總和為: ', np.sum(stock300_weight))

subscribe(symbols=stock300_symbol, frequency='1d', count=5, wait_group=True)

defon_bar(context, bars):

# 若沒(méi)有倉(cāng)位則按照初始權(quán)重開(kāi)倉(cāng)

forbarinbars:

symbol = bar['symbol']

? ? ? ? position = context.account().position(symbol=symbol, side=PositionSide_Long)

ifnotposition:

buy_percent = context.stock300['weight'][symbol] * context.ratio

? ? ? ? ? ? order_target_percent(symbol=symbol, percent=buy_percent, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print(symbol,'以市價(jià)單開(kāi)多倉(cāng)至倉(cāng)位:', buy_percent)

else:

# 獲取過(guò)去5天的價(jià)格數(shù)據(jù),若連續(xù)上漲則為強(qiáng)勢(shì)股,權(quán)重+0.2;若連續(xù)下跌則為弱勢(shì)股,權(quán)重-0.2

recent_data = context.data(symbol=symbol, frequency='1d', count=5, fields='close')['close'].tolist()

ifall(np.diff(recent_data) >0):

buy_percent = context.stock300['weight'][symbol] * (context.ratio +0.2)

? ? ? ? ? ? ? ? order_target_percent(symbol=symbol, percent=buy_percent, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print('強(qiáng)勢(shì)股', symbol,'以市價(jià)單調(diào)多倉(cāng)至倉(cāng)位:', buy_percent)

elifall(np.diff(recent_data) <0):

buy_percent = context.stock300['weight'][symbol] * (context.ratio -0.2)

? ? ? ? ? ? ? ? order_target_percent(symbol=symbol, percent=buy_percent, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print('弱勢(shì)股', symbol,'以市價(jià)單調(diào)多倉(cāng)至倉(cāng)位:', buy_percent)

if__name__ =='__main__':

'''

? ? strategy_id策略ID,由系統(tǒng)生成

? ? filename文件名,請(qǐng)與本文件名保持一致

? ? mode實(shí)時(shí)模式:MODE_LIVE回測(cè)模式:MODE_BACKTEST

? ? token綁定計(jì)算機(jī)的ID,可在系統(tǒng)設(shè)置-密鑰管理中生成

? ? backtest_start_time回測(cè)開(kāi)始時(shí)間

? ? backtest_end_time回測(cè)結(jié)束時(shí)間

? ? backtest_adjust股票復(fù)權(quán)方式不復(fù)權(quán):ADJUST_NONE前復(fù)權(quán):ADJUST_PREV后復(fù)權(quán):ADJUST_POST

? ? backtest_initial_cash回測(cè)初始資金

? ? backtest_commission_ratio回測(cè)傭金比例

? ? backtest_slippage_ratio回測(cè)滑點(diǎn)比例

? ? '''

run(strategy_id='strategy_id',

filename='main.py',

? ? ? ? mode=MODE_BACKTEST,

token='token_id',

backtest_start_time='2017-07-01 08:50:00',

backtest_end_time='2017-10-01 17:00:00',

? ? ? ? backtest_adjust=ADJUST_PREV,

backtest_initial_cash=10000000,

backtest_commission_ratio=0.0001,

backtest_slippage_ratio=0.0001)

4.行業(yè)輪動(dòng)

# coding=utf-8

from__future__importprint_function, absolute_import, unicode_literals

importnumpyasnp

fromgm.apiimport*

'''

本策略每隔1個(gè)月定時(shí)觸發(fā)計(jì)算SHSE.000910.SHSE.000909.SHSE.000911.SHSE.000912.SHSE.000913.SHSE.000914

(300工業(yè).300材料.300可選.300消費(fèi).300醫(yī)藥.300金融)這幾個(gè)行業(yè)指數(shù)過(guò)去

20個(gè)交易日的收益率并選取了收益率最高的指數(shù)的成份股獲取并獲取了他們的市值數(shù)據(jù)

隨后把倉(cāng)位調(diào)整至市值最大的5只股票上

回測(cè)數(shù)據(jù)為:SHSE.000910.SHSE.000909.SHSE.000911.SHSE.000912.SHSE.000913.SHSE.000914和他們的成份股

回測(cè)時(shí)間為:2017-07-01 08:00:00到2017-10-01 16:00:00

'''

definit(context):

# 每月第一個(gè)交易日的09:40 定時(shí)執(zhí)行algo任務(wù)

schedule(schedule_func=algo, date_rule='1m', time_rule='09:40:00')

# 用于篩選的行業(yè)指數(shù)

context.index = ['SHSE.000910','SHSE.000909','SHSE.000911','SHSE.000912','SHSE.000913','SHSE.000914']

# 用于統(tǒng)計(jì)數(shù)據(jù)的天數(shù)

context.date =20

# 最大下單資金比例

context.ratio =0.8

defalgo(context):

# 獲取當(dāng)天的日期

? ? today = context.now

# 獲取上一個(gè)交易日

last_day = get_previous_trading_date(exchange='SHSE', date=today)

? ? return_index = []

# 獲取并計(jì)算行業(yè)指數(shù)收益率

foriincontext.index:

return_index_his = history_n(symbol=i, frequency='1d', count=context.date, fields='close,bob',

fill_missing='Last', adjust=ADJUST_PREV, end_time=last_day, df=True)

return_index_his = return_index_his['close'].values

return_index.append(return_index_his[-1] / return_index_his[0] -1)

# 獲取指定數(shù)內(nèi)收益率表現(xiàn)最好的行業(yè)

? ? sector = context.index[np.argmax(return_index)]

print('最佳行業(yè)指數(shù)是: ', sector)

# 獲取最佳行業(yè)指數(shù)成份股

symbols = get_history_constituents(index=sector, start_date=last_day, end_date=last_day)[0]['constituents'].keys()

# 獲取當(dāng)天有交易的股票

? ? not_suspended_info = get_history_instruments(symbols=symbols, start_date=today, end_date=today)

not_suspended_symbols = [item['symbol']foriteminnot_suspended_infoifnotitem['is_suspended']]

# 獲取最佳行業(yè)指數(shù)成份股的市值喘沿,從大到小排序并選取市值最大的5只股票

fin = get_fundamentals(table='tq_sk_finindic', symbols=not_suspended_symbols, start_date=last_day,

end_date=last_day, limit=5, fields='NEGOTIABLEMV', order_by='-NEGOTIABLEMV', df=True)

fin.index = fin['symbol']

# 計(jì)算權(quán)重

percent =1.0/ len(fin.index) * context.ratio

# 獲取當(dāng)前所有倉(cāng)位

? ? positions = context.account().positions()

# 如標(biāo)的池有倉(cāng)位,平不在標(biāo)的池的倉(cāng)位

forpositioninpositions:

symbol = position['symbol']

ifsymbolnotinfin.index:

order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print('市價(jià)單平不在標(biāo)的池的', symbol)

# 對(duì)標(biāo)的池進(jìn)行操作

forsymbolinfin.index:

? ? ? ? order_target_percent(symbol=symbol, percent=percent, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print(symbol,'以市價(jià)單調(diào)整至倉(cāng)位', percent)

if__name__ =='__main__':

'''

? ? strategy_id策略ID,由系統(tǒng)生成

? ? filename文件名,請(qǐng)與本文件名保持一致

? ? mode實(shí)時(shí)模式:MODE_LIVE回測(cè)模式:MODE_BACKTEST

? ? token綁定計(jì)算機(jī)的ID,可在系統(tǒng)設(shè)置-密鑰管理中生成

? ? backtest_start_time回測(cè)開(kāi)始時(shí)間

? ? backtest_end_time回測(cè)結(jié)束時(shí)間

? ? backtest_adjust股票復(fù)權(quán)方式不復(fù)權(quán):ADJUST_NONE前復(fù)權(quán):ADJUST_PREV后復(fù)權(quán):ADJUST_POST

? ? backtest_initial_cash回測(cè)初始資金

? ? backtest_commission_ratio回測(cè)傭金比例

? ? backtest_slippage_ratio回測(cè)滑點(diǎn)比例

? ? '''

run(strategy_id='strategy_id',

filename='main.py',

? ? ? ? mode=MODE_BACKTEST,

token='token_id',

backtest_start_time='2017-07-01 08:00:00',

backtest_end_time='2017-10-01 16:00:00',

? ? ? ? backtest_adjust=ADJUST_PREV,

backtest_initial_cash=10000000,

backtest_commission_ratio=0.0001,

backtest_slippage_ratio=0.0001)

5.集合競(jìng)價(jià)選股

# coding=utf-8

from__future__importprint_function, absolute_import, unicode_literals

fromgm.apiimport*

'''

本策略通過(guò)獲取SHSE.000300滬深300的成份股數(shù)據(jù)并統(tǒng)計(jì)其30天內(nèi)

開(kāi)盤(pán)價(jià)大于前收盤(pán)價(jià)的天數(shù),并在該天數(shù)大于閾值10的時(shí)候加入股票池

隨后對(duì)不在股票池的股票平倉(cāng)并等權(quán)配置股票池的標(biāo)的,每次交易間隔1個(gè)月.

回測(cè)數(shù)據(jù)為:SHSE.000300在2015-01-15的成份股

回測(cè)時(shí)間為:2017-07-01 08:00:00到2017-10-01 16:00:00

'''

definit(context):

# 每月第一個(gè)交易日的09:40 定時(shí)執(zhí)行algo任務(wù)

schedule(schedule_func=algo, date_rule='1m', time_rule='09:40:00')

# context.count_bench累計(jì)天數(shù)闕值

context.count_bench =10

# 用于對(duì)比的天數(shù)

context.count =30

# 最大交易資金比例

context.ratio =0.8

defalgo(context):

# 獲取當(dāng)前時(shí)間

? ? now = context.now

# 獲取上一個(gè)交易日

last_day = get_previous_trading_date(exchange='SHSE', date=now)

# 獲取滬深300成份股

context.stock300 = get_history_constituents(index='SHSE.000300', start_date=last_day,

end_date=last_day)[0]['constituents'].keys()

# 獲取當(dāng)天有交易的股票

? ? not_suspended_info = get_history_instruments(symbols=context.stock300, start_date=now, end_date=now)

not_suspended_symbols = [item['symbol']foriteminnot_suspended_infoifnotitem['is_suspended']]

? ? trade_symbols = []

ifnotnot_suspended_symbols:

print('沒(méi)有當(dāng)日交易的待選股票')

return

forstockinnot_suspended_symbols:

recent_data = history_n(symbol=stock, frequency='1d', count=context.count, fields='pre_close,open',

fill_missing='Last', adjust=ADJUST_PREV, end_time=now, df=True)

diff = recent_data['open'] - recent_data['pre_close']

# 獲取累計(jì)天數(shù)超過(guò)闕值的標(biāo)的池.并剔除當(dāng)天沒(méi)有交易的股票

iflen(diff[diff >0]) >= context.count_bench:

? ? ? ? ? ? trade_symbols.append(stock)

print('本次股票池有股票數(shù)目: ', len(trade_symbols))

# 計(jì)算權(quán)重

percent =1.0/ len(trade_symbols) * context.ratio

# 獲取當(dāng)前所有倉(cāng)位

? ? positions = context.account().positions()

# 如標(biāo)的池有倉(cāng)位,平不在標(biāo)的池的倉(cāng)位

forpositioninpositions:

symbol = position['symbol']

ifsymbolnotintrade_symbols:

order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print('市價(jià)單平不在標(biāo)的池的', symbol)

# 對(duì)標(biāo)的池進(jìn)行操作

forsymbolintrade_symbols:

? ? ? ? order_target_percent(symbol=symbol, percent=percent, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print(symbol,'以市價(jià)單調(diào)整至權(quán)重', percent)

if__name__ =='__main__':

'''

? ? strategy_id策略ID,由系統(tǒng)生成

? ? filename文件名,請(qǐng)與本文件名保持一致

? ? mode實(shí)時(shí)模式:MODE_LIVE回測(cè)模式:MODE_BACKTEST

? ? token綁定計(jì)算機(jī)的ID,可在系統(tǒng)設(shè)置-密鑰管理中生成

? ? backtest_start_time回測(cè)開(kāi)始時(shí)間

? ? backtest_end_time回測(cè)結(jié)束時(shí)間

? ? backtest_adjust股票復(fù)權(quán)方式不復(fù)權(quán):ADJUST_NONE前復(fù)權(quán):ADJUST_PREV后復(fù)權(quán):ADJUST_POST

? ? backtest_initial_cash回測(cè)初始資金

? ? backtest_commission_ratio回測(cè)傭金比例

? ? backtest_slippage_ratio回測(cè)滑點(diǎn)比例

? ? '''

run(strategy_id='strategy_id',

filename='main.py',

? ? ? ? mode=MODE_BACKTEST,

token='token_id',

backtest_start_time='2017-07-01 08:00:00',

backtest_end_time='2017-10-01 16:00:00',

? ? ? ? backtest_adjust=ADJUST_PREV,

backtest_initial_cash=10000000,

backtest_commission_ratio=0.0001,

backtest_slippage_ratio=0.0001)

6.機(jī)器學(xué)習(xí)

# coding=utf-8

from__future__importprint_function, absolute_import, unicode_literals

fromdatetimeimportdatetime

importnumpyasnp

fromgm.apiimport*

importsys

try:

fromsklearnimportsvm

except:

print('請(qǐng)安裝scikit-learn庫(kù)和帶mkl的numpy')

sys.exit(-1)

'''

本策略選取了七個(gè)特征變量組成了滑動(dòng)窗口長(zhǎng)度為15天的訓(xùn)練集,隨后訓(xùn)練了一個(gè)二分類(lèi)(上漲/下跌)的支持向量機(jī)模型.

若沒(méi)有倉(cāng)位則在每個(gè)星期一的時(shí)候輸入標(biāo)的股票近15個(gè)交易日的特征變量進(jìn)行預(yù)測(cè),并在預(yù)測(cè)結(jié)果為上漲的時(shí)候購(gòu)買(mǎi)標(biāo)的.

若已經(jīng)持有倉(cāng)位則在盈利大于10%的時(shí)候止盈,在星期五損失大于2%的時(shí)候止損.

特征變量為:1.收盤(pán)價(jià)/均值2.現(xiàn)量/均量3.最高價(jià)/均價(jià)4.最低價(jià)/均價(jià)5.現(xiàn)量6.區(qū)間收益率7.區(qū)間標(biāo)準(zhǔn)差

訓(xùn)練數(shù)據(jù)為:SHSE.600000浦發(fā)銀行,時(shí)間從2016-03-01到2017-06-30

回測(cè)時(shí)間為:2017-07-01 09:00:00到2017-10-01 09:00:00

'''

definit(context):

# 訂閱浦發(fā)銀行的分鐘bar行情

context.symbol ='SHSE.600000'

subscribe(symbols=context.symbol, frequency='60s')

start_date ='2016-03-01'# SVM訓(xùn)練起始時(shí)間

end_date ='2017-06-30'# SVM訓(xùn)練終止時(shí)間

# 用于記錄工作日

# 獲取目標(biāo)股票的daily歷史行情

recent_data = history(context.symbol, frequency='1d', start_time=start_date, end_time=end_date, fill_missing='last',

df=True)

days_value = recent_data['bob'].values

days_close = recent_data['close'].values

? ? days = []

# 獲取行情日期列表

print('準(zhǔn)備數(shù)據(jù)訓(xùn)練SVM')

foriinrange(len(days_value)):

days.append(str(days_value[i])[0:10])

? ? x_all = []

? ? y_all = []

forindexinrange(15, (len(days) -5)):

# 計(jì)算三星期共15個(gè)交易日相關(guān)數(shù)據(jù)

start_day = days[index -15]

? ? ? ? end_day = days[index]

data = history(context.symbol, frequency='1d', start_time=start_day, end_time=end_day, fill_missing='last',

df=True)

close = data['close'].values

max_x = data['high'].values

min_n = data['low'].values

amount = data['amount'].values

? ? ? ? volume = []

foriinrange(len(close)):

? ? ? ? ? ? volume_temp = amount[i] / close[i]

? ? ? ? ? ? volume.append(volume_temp)

close_mean = close[-1] / np.mean(close)# 收盤(pán)價(jià)/均值

volume_mean = volume[-1] / np.mean(volume)# 現(xiàn)量/均量

max_mean = max_x[-1] / np.mean(max_x)# 最高價(jià)/均價(jià)

min_mean = min_n[-1] / np.mean(min_n)# 最低價(jià)/均價(jià)

vol = volume[-1]# 現(xiàn)量

return_now = close[-1] / close[0]# 區(qū)間收益率

std = np.std(np.array(close), axis=0)# 區(qū)間標(biāo)準(zhǔn)差

# 將計(jì)算出的指標(biāo)添加到訓(xùn)練集X

# features用于存放因子

? ? ? ? features = [close_mean, volume_mean, max_mean, min_mean, vol, return_now, std]

? ? ? ? x_all.append(features)

# 準(zhǔn)備算法需要用到的數(shù)據(jù)

foriinrange(len(days_close) -20):

ifdays_close[i +20] > days_close[i +15]:

label =1

else:

label =0

? ? ? ? y_all.append(label)

x_train = x_all[:-1]

y_train = y_all[:-1]

# 訓(xùn)練SVM

context.clf = svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False,

tol=0.001, cache_size=200, verbose=False, max_iter=-1,

decision_function_shape='ovr', random_state=None)

? ? context.clf.fit(x_train, y_train)

print('訓(xùn)練完成!')

defon_bar(context, bars):

bar = bars[0]

# 獲取當(dāng)前年月日

today = bar.bob.strftime('%Y-%m-%d')

# 獲取數(shù)據(jù)并計(jì)算相應(yīng)的因子

# 于星期一的09:31:00進(jìn)行操作

# 當(dāng)前bar的工作日

weekday = datetime.strptime(today,'%Y-%m-%d').isoweekday()

# 獲取模型相關(guān)的數(shù)據(jù)

# 獲取持倉(cāng)

? ? position = context.account().position(symbol=context.symbol, side=PositionSide_Long)

# 如果bar是新的星期一且沒(méi)有倉(cāng)位則開(kāi)始預(yù)測(cè)

ifnotpositionandweekday ==1:

# 獲取預(yù)測(cè)用的歷史數(shù)據(jù)

data = history_n(symbol=context.symbol, frequency='1d', end_time=today, count=15,

fill_missing='last', df=True)

close = data['close'].values

train_max_x = data['high'].values

train_min_n = data['low'].values

train_amount = data['amount'].values

? ? ? ? volume = []

foriinrange(len(close)):

? ? ? ? ? ? volume_temp = train_amount[i] / close[i]

? ? ? ? ? ? volume.append(volume_temp)

close_mean = close[-1] / np.mean(close)

volume_mean = volume[-1] / np.mean(volume)

max_mean = train_max_x[-1] / np.mean(train_max_x)

min_mean = train_min_n[-1] / np.mean(train_min_n)

vol = volume[-1]

return_now = close[-1] / close[0]

std = np.std(np.array(close), axis=0)

# 得到本次輸入模型的因子

? ? ? ? features = [close_mean, volume_mean, max_mean, min_mean, vol, return_now, std]

features = np.array(features).reshape(1,-1)

prediction = context.clf.predict(features)[0]

# 若預(yù)測(cè)值為上漲則開(kāi)倉(cāng)

ifprediction ==1:

# 獲取昨收盤(pán)價(jià)

context.price = close[-1]

# 把浦發(fā)銀行的倉(cāng)位調(diào)至95%

order_target_percent(symbol=context.symbol, percent=0.95, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print('SHSE.600000以市價(jià)單開(kāi)多倉(cāng)到倉(cāng)位0.95')

# 當(dāng)漲幅大于10%,平掉所有倉(cāng)位止盈

elifpositionandbar.close / context.price >=1.10:

? ? ? ? order_close_all()

print('SHSE.600000以市價(jià)單全平多倉(cāng)止盈')

# 當(dāng)時(shí)間為周五并且跌幅大于2%時(shí),平掉所有倉(cāng)位止損

elifpositionandbar.close / context.price <1.02andweekday ==5:

? ? ? ? order_close_all()

print('SHSE.600000以市價(jià)單全平多倉(cāng)止損')

if__name__ =='__main__':

'''

? ? strategy_id策略ID,由系統(tǒng)生成

? ? filename文件名,請(qǐng)與本文件名保持一致

? ? mode實(shí)時(shí)模式:MODE_LIVE回測(cè)模式:MODE_BACKTEST

? ? token綁定計(jì)算機(jī)的ID,可在系統(tǒng)設(shè)置-密鑰管理中生成

? ? backtest_start_time回測(cè)開(kāi)始時(shí)間

? ? backtest_end_time回測(cè)結(jié)束時(shí)間

? ? backtest_adjust股票復(fù)權(quán)方式不復(fù)權(quán):ADJUST_NONE前復(fù)權(quán):ADJUST_PREV后復(fù)權(quán):ADJUST_POST

? ? backtest_initial_cash回測(cè)初始資金

? ? backtest_commission_ratio回測(cè)傭金比例

? ? backtest_slippage_ratio回測(cè)滑點(diǎn)比例

? ? '''

run(strategy_id='strategy_id',

filename='main.py',

? ? ? ? mode=MODE_BACKTEST,

token='token_id',

backtest_start_time='2017-07-01 09:00:00',

backtest_end_time='2017-10-01 09:00:00',

? ? ? ? backtest_adjust=ADJUST_PREV,

backtest_initial_cash=10000000,

backtest_commission_ratio=0.0001,

backtest_slippage_ratio=0.0001)

7.配對(duì)交易

# coding=utf-8

from__future__importprint_function, absolute_import, unicode_literals

fromgm.apiimport*

importnumpyasnp

definit(context):

#獲得N日股票交易數(shù)據(jù)

context.N=5

#選擇一對(duì)股票

context.stock=['SZSE.000651','SZSE.000333']

# 每個(gè)交易日的09:40 定時(shí)執(zhí)行algo任務(wù)

schedule(schedule_func=algo, date_rule='1d', time_rule='09:40:00')

defalgo(context):

# 獲取上一個(gè)交易日的日期

last_day = get_previous_trading_date(exchange='SHSE', date=context.now)

# 獲取當(dāng)天有交易的股票闸度,似乎無(wú)法同時(shí)獲得兩只股票的數(shù)據(jù),所以只能麻煩一點(diǎn)

not_suspended = get_history_instruments(symbols=context.stock[0], start_date=last_day, end_date=last_day)

a = len([item['symbol']foriteminnot_suspendedifnotitem['is_suspended']])

not_suspended = get_history_instruments(symbols=context.stock[1], start_date=last_day,end_date=last_day)

b = len([item['symbol']foriteminnot_suspendedifnotitem['is_suspended']])

#如果有一支停牌蚜印,就跳過(guò)

ifa+b<2:

return

#獲得交易數(shù)據(jù)

prices1 = history_n(symbol=context.stock[0], frequency='1d', count=context.N, end_time=last_day, fields='close',

skip_suspended=True,

fill_missing=None, adjust=ADJUST_PREV, adjust_end_time='', df=True)

prices2=history_n(symbol=context.stock[1], frequency='1d', count=context.N, end_time=last_day, fields='close',

skip_suspended=True,

fill_missing=None, adjust=ADJUST_PREV, adjust_end_time='', df=True)

p1=list(prices1['close'])

p2=list(prices2['close'])

spread = np.array(p1[:-1]) - np.array(p2[:-1])

# 計(jì)算布林帶的上下軌

up = np.mean(spread) +2* np.std(spread)

down = np.mean(spread) -2* np.std(spread)

# 計(jì)算最新價(jià)差

spread_now = p1[-1] - p2[-1]

# 無(wú)交易時(shí)若價(jià)差上(下)穿布林帶上(下)軌則做空(多)價(jià)差

position_s1_long = context.account().position(symbol=context.stock[0], side=PositionSide_Long)

position_s2_long = context.account().position(symbol=context.stock[1], side=PositionSide_Long)

ifnotposition_s1_longandnotposition_s2_long:

ifspread_now > up:

order_target_percent(symbol=context.stock[1], percent=0.5, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

ifspread_now < down:

order_target_percent(symbol=context.stock[0], percent=0.5, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

# 價(jià)差回歸時(shí)平倉(cāng)

elifposition_s2_long:

ifspread_now <= up:

? ? ? ? ? ? order_close_all()

elifposition_s1_long:

ifspread_now >= down:

? ? ? ? ? ? order_close_all()

if__name__ =='__main__':

'''

? ? strategy_id策略ID,由系統(tǒng)生成

? ? filename文件名,請(qǐng)與本文件名保持一致

? ? mode實(shí)時(shí)模式:MODE_LIVE回測(cè)模式:MODE_BACKTEST

? ? token綁定計(jì)算機(jī)的ID,可在系統(tǒng)設(shè)置-密鑰管理中生成

? ? backtest_start_time回測(cè)開(kāi)始時(shí)間

? ? backtest_end_time回測(cè)結(jié)束時(shí)間

? ? backtest_adjust股票復(fù)權(quán)方式不復(fù)權(quán):ADJUST_NONE前復(fù)權(quán):ADJUST_PREV后復(fù)權(quán):ADJUST_POST

? ? backtest_initial_cash回測(cè)初始資金

? ? backtest_commission_ratio回測(cè)傭金比例

? ? backtest_slippage_ratio回測(cè)滑點(diǎn)比例

? ? '''

run(strategy_id='73bb5bf2-a536-11e8-bd52-9cd21ef04ea9',

filename='配對(duì)交易.py',

? ? ? ? mode=MODE_BACKTEST,

token='c395247a76e8a5caeee699d668d6f550213bc418',

backtest_start_time='2014-01-01 08:00:00',

backtest_end_time='2018-08-01 16:00:00',

? ? ? ? backtest_adjust=ADJUST_PREV,

backtest_initial_cash=10000000,

backtest_commission_ratio=0.0001,

backtest_slippage_ratio=0.0001)

8.GARP策略

# coding=utf-8

from__future__importprint_function, absolute_import, unicode_literals

fromgm.apiimport*

fromsklearnimportpreprocessing

'''

策略思路:

1莺禁、公司的資產(chǎn)負(fù)債率小于等于 25%

2、公司每股凈現(xiàn)金大于 0

3窄赋、當(dāng)前股價(jià)與每股自由現(xiàn)金流量比小于 10(市現(xiàn)率)

4哟冬、在所有股票中取市盈率排倒數(shù)30%的股票(首先PE必須大于0)

5、PEG=市盈率/凈利潤(rùn)增長(zhǎng)率<0.5

回測(cè)數(shù)據(jù):SHSE.000906的成份股

回測(cè)時(shí)間:2016-01-01 08:00:00到2018-01-01 16:00:00

'''

definit(context):

# 每月第一個(gè)交易日的09:40 定時(shí)執(zhí)行algo任務(wù)

schedule(schedule_func=algo, date_rule='1m', time_rule='09:40:00')

defalgo(context):

# 獲取上一個(gè)交易日的日期

last_day = get_previous_trading_date(exchange='SHSE', date=context.now)

# 獲取滬深300成份股

stock800 = get_history_constituents(index='SHSE.000906', start_date=last_day,

end_date=last_day)[0]['constituents'].keys()

# 獲取當(dāng)天有交易的股票

? ? not_suspended = get_history_instruments(symbols=stock800, start_date=last_day, end_date=last_day)

not_suspended = [item['symbol']foriteminnot_suspendedifnotitem['is_suspended']]

df = get_fundamentals(table='deriv_finance_indicator', symbols=not_suspended, start_date=last_day, end_date=last_day,

fields='ASSLIABRT,NCFPS,NPGRT', df=True)

fin=get_fundamentals(table='trading_derivative_indicator', symbols=not_suspended, start_date=last_day, end_date=last_day,

fields='PCLFY,PELFY', df=True)

df['PCLFY']=fin['PCLFY']

df['PELFY'] = fin['PELFY']

# 除去空值

? ? df = df.dropna()

df['PEG']=df['PELFY']/df['NPGRT']

? ? df.index=df.symbol

deldf['symbol'],df['pub_date'],df['end_date']

? ? print(df)

# 選出PEG小于0.5的部分

df = df[df['PEG'] <0.5]

# 選出債務(wù)總資產(chǎn)比小于0.25的部分

df = df[df["ASSLIABRT"] <25]

# 選出每股凈現(xiàn)金大于 0的部分

df = df[df["NCFPS"] >0]

# 選出市盈率大于零的部分

df = df[df['PELFY'] >0]

# 選出市現(xiàn)率小于10的部分

df = df[df['PCLFY'] <10]

? ? print(df)

# 剔除市盈率較高的股票(即剔除3分位數(shù)以后的股票)

iflen(df)<4:

? ? ? ? symbols_pool = list(df.index)

else:

df = df[(df['PELFY'] < df['PELFY'].quantile(0.3))]

? ? ? ? symbols_pool = list(df.index)

? ? print(symbols_pool)

? ? order_close_all()

? ? long=len(symbols_pool)

iflong==0:

return

# 獲取股票的權(quán)重

percent =1/ long

# 買(mǎi)在標(biāo)的池中的股票

forsymbolinsymbols_pool:

? ? ? ? order_target_percent(symbol=symbol, percent=percent, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

#print(symbol, '以市價(jià)單調(diào)多倉(cāng)到倉(cāng)位', percent)

if__name__ =='__main__':

'''

? ? strategy_id策略ID,由系統(tǒng)生成

? ? filename文件名,請(qǐng)與本文件名保持一致

? ? mode實(shí)時(shí)模式:MODE_LIVE回測(cè)模式:MODE_BACKTEST

? ? token綁定計(jì)算機(jī)的ID,可在系統(tǒng)設(shè)置-密鑰管理中生成

? ? backtest_start_time回測(cè)開(kāi)始時(shí)間

? ? backtest_end_time回測(cè)結(jié)束時(shí)間

? ? backtest_adjust股票復(fù)權(quán)方式不復(fù)權(quán):ADJUST_NONE前復(fù)權(quán):ADJUST_PREV后復(fù)權(quán):ADJUST_POST

? ? backtest_initial_cash回測(cè)初始資金

? ? backtest_commission_ratio回測(cè)傭金比例

? ? backtest_slippage_ratio回測(cè)滑點(diǎn)比例

? ? '''

run(strategy_id='73bb5bf2-a536-11e8-bd52-9cd21ef04ea9',

filename='GARP.py',

? ? ? ? mode=MODE_BACKTEST,

token='c395247a76e8a5caeee699d668d6f550213bc418',

backtest_start_time='2016-01-01 08:00:00',

backtest_end_time='2018-01-01 16:00:00',

? ? ? ? backtest_adjust=ADJUST_PREV,

backtest_initial_cash=10000000,

backtest_commission_ratio=0.0001,

backtest_slippage_ratio=0.0001)

9.alpha對(duì)沖(股票+期貨)

# coding=utf-8

from__future__importprint_function, absolute_import, unicode_literals

fromgm.apiimport*

'''

本策略每隔1個(gè)月定時(shí)觸發(fā)計(jì)算SHSE.000300成份股的過(guò)去的EV/EBITDA并選取EV/EBITDA大于0的股票

隨后平掉排名EV/EBITDA不在最小的30的股票持倉(cāng)并等權(quán)購(gòu)買(mǎi)EV/EBITDA最小排名在前30的股票

并用相應(yīng)的CFFEX.IF對(duì)應(yīng)的真實(shí)合約等額對(duì)沖

回測(cè)數(shù)據(jù)為:SHSE.000300和他們的成份股和CFFEX.IF對(duì)應(yīng)的真實(shí)合約

回測(cè)時(shí)間為:2017-07-01 08:00:00到2017-10-01 16:00:00

'''

definit(context):

# 每月第一個(gè)交易日09:40:00的定時(shí)執(zhí)行algo任務(wù)

schedule(schedule_func=algo, date_rule='1m', time_rule='09:40:00')

# 設(shè)置開(kāi)倉(cāng)在股票和期貨的資金百分比(期貨在后面自動(dòng)進(jìn)行杠桿相關(guān)的調(diào)整)

context.percentage_stock =0.4

context.percentage_futures =0.4

defalgo(context):

# 獲取當(dāng)前時(shí)刻

? ? now = context.now

# 獲取上一個(gè)交易日

last_day = get_previous_trading_date(exchange='SHSE', date=now)

# 獲取滬深300成份股

stock300 = get_history_constituents(index='SHSE.000300', start_date=last_day,

end_date=last_day)[0]['constituents'].keys()

# 獲取上一個(gè)工作日的CFFEX.IF對(duì)應(yīng)的合約

index_futures = get_continuous_contracts(csymbol='CFFEX.IF', start_date=last_day, end_date=last_day)[-1]['symbol']

# 獲取當(dāng)天有交易的股票

? ? not_suspended_info = get_history_instruments(symbols=stock300, start_date=now, end_date=now)

not_suspended_symbols = [item['symbol']foriteminnot_suspended_infoifnotitem['is_suspended']]

# 獲取成份股EV/EBITDA大于0并為最小的30個(gè)

fin = get_fundamentals(table='tq_sk_finindic', symbols=not_suspended_symbols,

start_date=now, end_date=now, fields='EVEBITDA',

filter='EVEBITDA>0', order_by='EVEBITDA', limit=30, df=True)

? ? fin.index = fin.symbol

# 獲取當(dāng)前倉(cāng)位

? ? positions = context.account().positions()

# 平不在標(biāo)的池或不為當(dāng)前股指期貨主力合約對(duì)應(yīng)真實(shí)合約的標(biāo)的

forpositioninpositions:

symbol = position['symbol']

sec_type = get_instrumentinfos(symbols=symbol)[0]['sec_type']

# 若類(lèi)型為期貨且不在標(biāo)的池則平倉(cāng)

ifsec_type == SEC_TYPE_FUTUREandsymbol != index_futures:

order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Short)

print('市價(jià)單平不在標(biāo)的池的', symbol)

elifsymbolnotinfin.index:

order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print('市價(jià)單平不在標(biāo)的池的', symbol)

# 獲取股票的權(quán)重

? ? percent = context.percentage_stock / len(fin.index)

# 買(mǎi)在標(biāo)的池中的股票

forsymbolinfin.index:

? ? ? ? order_target_percent(symbol=symbol, percent=percent, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Long)

print(symbol,'以市價(jià)單調(diào)多倉(cāng)到倉(cāng)位', percent)

# 獲取股指期貨的保證金比率

ratio = get_history_instruments(symbols=index_futures, start_date=last_day, end_date=last_day)[0]['margin_ratio']

# 更新股指期貨的權(quán)重

? ? percent = context.percentage_futures * ratio

# 買(mǎi)入股指期貨對(duì)沖

? ? order_target_percent(symbol=index_futures, percent=percent, order_type=OrderType_Market,

? ? ? ? ? ? ? ? ? ? ? ? position_side=PositionSide_Short)

print(index_futures,'以市價(jià)單調(diào)空倉(cāng)到倉(cāng)位', percent)

if__name__ =='__main__':

'''

? ? strategy_id策略ID,由系統(tǒng)生成

? ? filename文件名,請(qǐng)與本文件名保持一致

? ? mode實(shí)時(shí)模式:MODE_LIVE回測(cè)模式:MODE_BACKTEST

? ? token綁定計(jì)算機(jī)的ID,可在系統(tǒng)設(shè)置-密鑰管理中生成

? ? backtest_start_time回測(cè)開(kāi)始時(shí)間

? ? backtest_end_time回測(cè)結(jié)束時(shí)間

? ? backtest_adjust股票復(fù)權(quán)方式不復(fù)權(quán):ADJUST_NONE前復(fù)權(quán):ADJUST_PREV后復(fù)權(quán):ADJUST_POST

? ? backtest_initial_cash回測(cè)初始資金

? ? backtest_commission_ratio回測(cè)傭金比例

? ? backtest_slippage_ratio回測(cè)滑點(diǎn)比例

? ? '''

run(strategy_id='strategy_id',

filename='main.py',

? ? ? ? mode=MODE_BACKTEST,

token='token_id',

backtest_start_time='2017-07-01 08:00:00',

backtest_end_time='2017-10-01 16:00:00',

? ? ? ? backtest_adjust=ADJUST_PREV,

backtest_initial_cash=10000000,

backtest_commission_ratio=0.0001,

backtest_slippage_ratio=0.0001)

鏈接下文:經(jīng)典的股票/期貨量化交易策略忆绰,拿來(lái)即用的Python策略源碼(2)


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末浩峡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子较木,更是在濱河造成了極大的恐慌红符,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伐债,死亡現(xiàn)場(chǎng)離奇詭異预侯,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)峰锁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)萎馅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人虹蒋,你說(shuō)我怎么就攤上這事糜芳。” “怎么了魄衅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵峭竣,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我晃虫,道長(zhǎng)皆撩,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任哲银,我火速辦了婚禮扛吞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘荆责。我一直安慰自己滥比,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布做院。 她就那樣靜靜地躺著盲泛,像睡著了一般濒持。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上查乒,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天弥喉,我揣著相機(jī)與錄音郁竟,去河邊找鬼玛迄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛棚亩,可吹牛的內(nèi)容都是我干的蓖议。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼讥蟆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼勒虾!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起瘸彤,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤修然,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后质况,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體愕宋,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年结榄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了中贝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡臼朗,死狀恐怖邻寿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情视哑,我是刑警寧澤绣否,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站挡毅,受9級(jí)特大地震影響蒜撮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜慷嗜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一淀弹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庆械,春花似錦薇溃、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春策幼,著一層夾襖步出監(jiān)牢的瞬間邑时,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工特姐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晶丘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓唐含,卻偏偏與公主長(zhǎng)得像浅浮,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捷枯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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

  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類(lèi): pyspark.sql...
    mpro閱讀 9,451評(píng)論 0 13