
項目地址:https://github.com/ricequant/rqalpha/
RQAlpha
簡介
RQAlpha是一個開源的Python算法交易和回測引擎,適合A股市場,是事件驅動的設計。自帶日線數據, 目前暫時僅支持日線回測。
RQAlpha的邏輯也將會在Ricequant的一些回測部分使用,Ricequant - 是一個開放的量化算法交易社區,有免費的服務器資源給大家測試、實盤模擬您的交易算法,并且可以將交易信號通過微信和郵件實時推送給大家, 如果您想要更好的回測報告體驗和實盤模擬交易功能可以把本地寫好的策略復制黏貼到我們的網站上運行。
如果您想參與和貢獻進來這個項目,可以發郵件給 public@ricequant.com 聯系,如果您有功能需求或者bug報告的話,都可以開一個issue:
https://github.com/ricequant/rqalpha/issues
特色
- 容易使用:RQAlpha可以讓你集中精力在策略的開發上。可以參考./examples 下的范例
- 需要傳入歷史數據,計算的結果是pandas的DataFrame, 和PyData的生態系統很好的結合在一起
- 可以使用Python的統計、機器學習等科學計算庫如matplotlib, scipy, statsmodels和sklearn等
- 免費提供了Ricequant的日級別數據,可以通過互聯網自己更新data bundle
安裝
# 為了避免一些安裝問題,請先升級您的pip和setuptools
pip install -U pip setuptools
# 安裝rqalpha
pip install rqalpha
# 升級rqalpha
pip install -U rqalpha
# 國內的用戶們可以使用鏡像
pip install -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com -U rqalpha
For Windows用戶
如果出現缺失cl.exe
,請訪問https://wiki.python.org/moin/WindowsCompilers下載VC并且安裝。
如果在安裝bcloz
出現編譯困難,可以從bcolz下載bcolz
安裝,安裝bcloz
后,再安裝rqalpha
。
安裝依賴
安裝TA-Lib
你可以通過PyPI安裝:
$ pip install TA-Lib
如果發現無法通過 pip 安裝,請訪問 https://mrjbq7.github.io/ta-lib/install.html 解決。
對于Windows用戶,如果編譯困難,可以根據您本地的Python版本下載指定版本的whl包,然后pip install TA_Lib-0.4.9-cp27-none-win_amd64.whl
。
- TA_Lib-0.4.9-cp27-none-win32.whl
- TA_Lib-0.4.9-cp27-none-win_amd64.whl
- TA_Lib-0.4.9-cp34-none-win32.whl
- TA_Lib-0.4.9-cp34-none-win_amd64.whl
- TA_Lib-0.4.9-cp35-none-win32.whl
- TA_Lib-0.4.9-cp35-none-win_amd64.whl
Usage
Usage: rqalpha [OPTIONS] COMMAND [ARGS]...
Options:
-v, --verbose
--help Show this message and exit.
Commands:
examples generate example strategies to target folder
plot draw result DataFrame
run run strategy from file
update_bundle update data bundle, download if not found
下載回測需要的數據bundle
運行以下命令,將會從Ricequant的服務器下載最新的日級別數據,為回測提供數據支持。
rqalpha update_bundle
生成樣例策略
運行以下命令,將會在指定目錄生成一個examples文件夾,其中包含幾個有趣的樣例策略。
rqalpha examples -d ./
運行回測
回測腳本參數如下:
Usage: rqalpha run [OPTIONS]
run strategy from file
Options:
-f, --strategy-file PATH [required]
-s, --start-date DATE [required]
-e, --end-date DATE [required]
-o, --output-file PATH
-i, --init-cash INTEGER
--plot / --no-plot plot result
--progress / --no-progress show progress bar
-d, --data-bundle-path PATH
--help Show this message and exit.
運行以下命令,將開始回測
rqalpha run -f examples/multi_rsi.py -s 2014-01-01 -e 2016-01-01 -o result.pkl --plot
等待回測結束后,將顯示您的收益率和Risk。

繪制回測結果
如果運行完回測后,還需要再次繪制回測結果,可以運行以下命令:
rqalpha plot result.pkl
分析結果
RQAlpha可以輸出一個DataFrame,其中包含了每天的Portfolio信息、Risk信息、Trades和Positions。
其Index是交易日,columns包括alpha
, annualized_returns
, benchmark_annualized_returns
, benchmark_daily_returns
, benchmark_total_returns
, beta
, cash
, daily_returns
, downside_risk
, information_rate
, market_value
, max_drawdown
, pnl
, portfolio_value
, positions
, sharpe
, sortino
, total_commission
, total_returns
, total_tax
, tracking_error
, trades
, volatility
。
其中positions
是當日的持倉信息,trades
是當日的交易信息。
import pandas as pd
df = pd.read_pickle("result.pkl")
print(df.iloc[-1])
'''
alpha 0.0180666
annualized_returns 0.0559331
benchmark_annualized_returns 0.0454542
benchmark_daily_returns 8.87784e-05
benchmark_total_returns 0.525913
beta 0.518371
cash 4971.44
daily_returns 0.00250376
downside_risk 0.246409
information_rate 0.0380054
market_value 162796
max_drawdown -0.602535
pnl 419
portfolio_value 167767
positions {'000068.XSHE': Position({{'value_percent': 0....
sharpe 2.35011
sortino 2.62967
total_commission 2585.89
total_returns 0.677674
total_tax 1172.01
tracking_error 0.269138
trades []
volatility 0.275721
Name: 2016-07-01 00:00:00, dtype: object
'''
架構圖

FAQ
在Windows運行報Error on import matplotlib.pyplot
請訪問 Error on import matplotlib.pyplot (on Anaconda3 for Windows 10 Home 64-bit PC) 解決。
Python SDK 簡介
Python策略Hello World
以下的策略是最簡單的一個買入并持有平安銀行(buy and hold)的展示,非常簡單:
# 可以自己import我們平臺支持的第三方python模塊,比如pandas、numpy等。
# 在這個方法中編寫任何的初始化邏輯。context對象將會在你的算法策略的任何方法之間做傳遞。
def init(context):
context.s1 = "000001.XSHE"
# order是否被發送出去
context.fired = False
# 你選擇的證券的數據更新將會觸發此段邏輯,例如日或分鐘歷史數據切片或者是實時數據切片更新
def handle_bar(context, bar_dict):
# 開始編寫你的主要的算法邏輯
# bar_dict[order_book_id] 可以拿到某個證券的bar信息
# context.portfolio 可以拿到現在的投資組合狀態信息
# 使用order_shares(id_or_ins, amount)方法進行落單
# TODO: 開始編寫你的算法吧!
if not context.fired:
# order_percent并且傳入1代表買入該股票并且使其占有投資組合的100%
order_percent(context.s1, 1)
context.fired = True
需要實現的方法
你的算法策略目前必須實現至少兩個方法:init
和 handle_bar
,而before_trading
是可選擇實現的方法。
init
init(context)
初始化方法 - 在回測和實時模擬交易只會在啟動的時候觸發一次。你的算法會使用這個方法來設置你需要的各種初始化配置。
context
對象將會在你的算法的所有其他的方法之間進行傳遞以方便你可以拿取到。
參數 | 類型 | 注釋 |
---|---|---|
context | python簡單對象 | 將會在整個算法中當做一個全局變量來使用。屬性通過點標記(".")來取到。 |
返回
None
范例:
def init(context):
# cash_limit的屬性是根據用戶需求自己定義的,你可以定義無限多種自己隨后需要的屬性,ricequant的系統默認只是會占用context.portfolio的關鍵字來調用策略的投資組合信息
context.cash_limit = 5000
handle_bar
handle_bar(context, bar_dict)
切片數據的更新會自動觸發調用這個方法,如果是日回測則是每日的切片數據(OHLC)會觸發調用,分鐘回測則會是每分鐘的切片數據會調用,那么在實時模擬交易中則是實時每分鐘會調用一次。對于切片數據對象你可以看關于Bar對象的更詳細的信息。
參數 | 類型 | 注釋 |
---|---|---|
context | 和init方法中的context對象一樣 | 存儲所有策略的自己定義的變量狀態或是初始設置。 |
bar_dict | bar dictionary - 存儲了關注的證券的bar的一個dict,order_book_id作為key | 所有已‘關注’的股票的切片數據信息都會更新在這個dict里面。 |
返回
None
范例
def handle_bar(context, bar_dict):
# put all your algorithm main logic here.
# ...
order_shares('000001.XSHE', 500)
# ...
before_trading
非強制,可選擇實現的函數。每天在市場開始前會被調用。不可以在這個函數中發送訂單(即不可以調用order_xxxx
函數)。
before_trading(context, bar_dict)
參數 | 類型 | 注釋 |
---|---|---|
context | 和init方法中的context對象一樣 | 存儲所有策略的自己定義的變量狀態或是初始設置,也保存了portfolio 的信息。 |
返回
None
范例
def before_trading(context, bar_dict):
context.stock_list = ["000001.XSHE", "000099.XSHE"]
# 手動更新股票池
update_universe(context.stock_list)
Order方法
你可以在策略中使用下面的幾種豐富的落單方法,他們不同的用法可以讓你落單的操作十分便捷。我們在交易系統內部提供好了倉位計算,因此你可以非常便利使用一些基于倉位管理上的落單方法,比如order_percent
可以讓你基于目前的倉位價值進行落單。
order_shares
落指定股數的買/賣單,最常見的落單方式之一。如有需要落單類型當做一個參量傳入,如果忽略掉落單類型,那么默認是市價單(market order)。
order_shares(id_or_ins, amount, style=MarketOrder())
參數 | 類型 | 注釋 |
---|---|---|
id_or_ins | str或instrument對象-required | order_book_id或symbol或instrument對象 |
amount | float-required | 需要落單的股數。正數代表買入,負數代表賣出。將會根據一手xx股來向下調整到一手的倍數,比如中國A股就是調整成100股的倍數。 |
style | OrderType-optional | 訂單類型,默認是市價單。目前支持的訂單類型有:<ul><li>style=MarketOrder()</li><li>style=LimitOrder(<span></span>limit_price)</li></ul> |
返回
int,唯一的order id
范例
- 購買Buy 2000 股的平安銀行股票,并以市價單發送
order_shares('000001.XSHE', 2000)
- 賣出2000股的平安銀行股票,并以市價單發送:
order_shares('000001.XSHE', -2000)
- 購買1000股的平安銀行股票,并以限價單發送,價格為¥10:
order_shares('000001.XSHG', 1000, style=LimitOrder(10))
order_lots
指定手數發送買/賣單。如有需要落單類型當做一個參量傳入,如果忽略掉落單類型,那么默認是市價單(market order)。
order_lots(id_or_ins, amount, style=OrderType)
參數 | 類型 | 注釋 |
---|---|---|
id_or_ins | str或instrument對象-required | order_book_id或symbol或instrument對象 |
amount | float-required | 多少手的數目。正數表示買入,負數表示賣出 |
style | OrderType-optional | 訂單類型,默認是市價單。目前支持的訂單類型有:<ul><li>style=MarketOrder</li><li>style=LimitOrder(<span></span>limit_price)</li></ul> |
返回
int,唯一的order id
范例
- 買入20手的平安銀行股票,并且發送市價單:
order_lots('000001.XSHE', 20)
- 買入10手平安銀行股票,并且發送限價單,價格為¥10:
order_lots('000001.XSHE', 10, style=LimitOrder(10))
order_value
使用想要花費的金錢買入/賣出股票,而不是買入/賣出想要的股數,正數代表買入,負數代表賣出。股票的股數總是會被調整成對應的100的倍數(在A中國A股市場1手是100股)。當您提交一個賣單時,該方法代表的意義是您希望通過賣出該股票套現的金額。如果金額超出了您所持有股票的價值,那么您將賣出所有股票。
order_value(id_or_ins, cash_amount, style=OrderType)
參數 | 類型 | 注釋 |
---|---|---|
id_or_ins | str或instrument對象-required | order_book_id或symbol或instrument對象 |
cash_amount | float-required | 需要花費現金購買/賣出證券的數目。正數代表買入,負數代表賣出。 |
style | OrderType-optional | 訂單類型,默認是市價單。目前支持的訂單類型有:<ul><li>style=MarketOrder()</li><li>style=LimitOrder(<span></span>limit_price)</li></ul> |
返回
int,唯一的order id
范例
- 買入價值¥10000的平安銀行股票,并以市價單發送。如果現在平安銀行股票的價格是¥7.5,那么下面的代碼會買入1300股的平安銀行,因為少于100股的數目將會被自動刪除掉。
order_value('000001.XSHE', 10000)
- 賣出價值¥10000的現在持有的平安銀行:
order_value('000001.XSHE', -10000)
order_percent
發送一個等于目前投資組合價值(市場價值和目前現金的總和)一定百分比的買/賣單,正數代表買,負數代表賣。股票的股數總是會被調整成對應的一手的股票數的倍數(1手是100股)。百分比是一個小數,并且小于或等于1(<=100%),0.5表示的是50%
order_percent(id_or_ins, percent, style=OrderType)
參數 | 類型 | 注釋 |
---|---|---|
id_or_ins | str或instrument對象 -required | order_book_id或symbol或instrument object. |
percent | float-required | 占有現有的投資組合價值的百分比。正數表示買入,負數表示賣出。 |
style | OrderType-optional | 訂單類型,默認是市價單。目前支持的訂單類型有:<ul><li>style=MarketOrder()</li><li>style=LimitOrder(<span></span>limit_price)</li></ul> |
返回
int,唯一的order id
范例
- 買入等于現有投資組合50%價值的平安銀行股票。如果現在平安銀行的股價是¥10/股并且現在的投資組合總價值是¥2000,那么將會買入200股的平安銀行股票。(不包含交易成本和滑點的損失)
order_percent('000001.XSHG', 0.5)
order_target_value
買入/賣出并且自動調整該證券的倉位到一個目標價值。如果還沒有任何該證券的倉位,那么會買入全部目標價值的證券。如果已經有了該證券的倉位,則會買入/賣出調整該證券的現在倉位和目標倉位的價值差值的數目的證券。
order_target_value(id_or_ins, cash_amount, style=OrderType)
參數 | 類型 | 注釋 |
---|---|---|
id_or_ins | str或instrument對象-required | order_book_id或symbol或instrument對象. |
cash_amount | float-required | 最終的該證券的倉位目標價值 |
style | OrderType-optional | 訂單類型,默認是市價單。目前支持的訂單類型有:<ul><li>style=MarketOrder()</li><li>style=LimitOrder(<span></span>limit_price)</li></ul> |
返回
int,唯一的order id
范例
- 如果現在的投資組合中持有價值¥3000的平安銀行股票的倉位并且設置其目標價值為¥10000,以下代碼范例會發送價值¥7000的平安銀行的買單到市場。(向下調整到最接近每手股數即100的倍數的股數)
order_target_value('000001.XSHE', 10000)
order_target_percent
買入/賣出證券以自動調整該證券的倉位到占有一個指定的投資組合的目標百分比。
- 如果投資組合中沒有任何該證券的倉位,那么會買入等于現在投資組合總價值的目標百分比的數目的證券。
- 如果投資組合中已經擁有該證券的倉位,那么會買入/賣出目標百分比和現有百分比的差額數目的證券,最終調整該證券的倉位占據投資組合的比例至目標百分比。
其實我們需要計算一個position_to_adjust (即應該調整的倉位)
position_to_adjust = target_position - current_position
投資組合價值等于所有已有倉位的價值和剩余現金的總和。買/賣單會被下舍入一手股數(A股是100的倍數)的倍數。目標百分比應該是一個小數,并且最大值應該<=1,比如0.5表示50%。
如果position_to_adjust
計算之后是正的,那么會買入該證券,否則會賣出該證券。
order_target_percent(id_or_ins, percent, style=OrderType)
參數 | 類型 | 注釋 |
---|---|---|
id_or_ins | str或instrument對象-required | order_book_id或symbol或instrument對象。 |
percent | float-required | 倉位最終所占投資組合總價值的目標百分比。 |
style | OrderType-optional | 訂單類型,默認是市價單。目前支持的訂單類型有:<ul><li>style=MarketOrder()</li><li>style=LimitOrder(<span></span>limit_price)</li></ul> |
返回
int,唯一的order id
范例
- 如果投資組合中已經有了平安銀行股票的倉位,并且占據目前投資組合的10%的價值,那么以下代碼會買入平安銀行股票最終使其占據投資組合價值的15%:
order_target_percent('平安銀行', 0.15)
cancel_order
取消由order_id代表的限價單。
cancel_order(order_id)
get_order
通過唯一的order_id拿到對應的訂單信息,不過這個訂單信息會在handle_bar
結尾處丟棄掉。
get_order(order_id)
參數 | 類型 | 注釋 |
---|---|---|
order_id | int-required | 訂單的唯一標示符 |
返回
order對象,如:
<Order: filled_shares=100.0 quantity=100.0 instrument=<Instrument: order_book_id='000001.XSHE' symbol='平安銀行' abbrev_symbol='PAYH' round_lot=100.0 sector_code='Financials' sector_name='金融'>>
get_open_orders
獲取一個由order_id到order對象映射的dict,凡在此dict中的order都未被完全成交或取消。
更改context中的預設值
更改默認基準
可以在init
函數中使用:
def init(context):
context.benchmark = "000001.XSHE"
上面的代碼片段把你的策略的對比參考基準從默認的csi300
修改成了平安銀行。
開啟允許賣空
默認賣空是不允許的,不過我們提供了API可以開啟賣空,不會讓您的賣空單被我們的系統拒掉,可以在init
函數中使用:
def init(context):
context.short_selling_allowed = True
如果您在測試一些諸如統計套利(pair trading)需要允許賣空機制的策略的時候可以開啟這一項,不過注意到在中國A股市場賣空股票是一件非常難的事情。
更改滑點
可以在init
函數中使用:
def init(context):
context.slippage = 0.5
注意 : 其中的數值應為x%中的x, 例子中的0.5=0.5%。
上面的代碼片段把你的策略的滑點更改為了0.5%。
更改交易費
可以在init
函數中使用:
def init(context):
context.commission = 0.02
注意 : 其中的數值應為x%中的x, 例子中的0.02=0.02%,即萬分之2.
上面的代碼片段把你的策略使用的交易費更改為了0.02%。
scheduler方法
如果需要在某個日期、某個時間點運行一個函數,可以在init
函數中使用scheduler
, 注意:scheduler
必須在init
函數中調用。
scheduler.run_daily(function)
scheduler.run_weekly(function, weekday=x,tradingday=t)
scheduler.run_monthly(function, tradingday=t)
定日期運行
每天
每天運行一次傳入的function
scheduler.run_daily(function)
參數 | 類型 | 注釋 |
---|---|---|
function | function | 使傳入的function 每日運行 |
返回
None
注意
1, schedule一定在其對應時間點的handle_bar之后執行。
范例
以下的范例代碼片段是一個非常簡單的例子,在每天交易后查詢現在portfolio
中剩下的cash的情況
def log_cash(context, bar_dict):
logger.info("Remaning cash: %r" % context.portfolio.cash)
def init(context):
#...
# 每天運行一次
scheduler.run_daily(log_cash)
每周某天
每周在固定的某天運行一下傳入的function
scheduler.run_weekly(function, weekday=x, tradingday=t)
參數 | 類型 | 注釋 |
---|---|---|
function | function | 使傳入的function 每日交易開始前運行 |
weekday | int - required | 1:周一,2:周二, ..., 5: 周五 |
tradingday | int - not required | 范圍為[-5,1],[1,5] 例:1(-1):每周(倒數)第一個交易日,n(-n):每周(倒數)第n個交易日 |
返回
None
注意
1, tradingday
中的負數表示倒數。
2, tradingday
表示交易日。如某周只有四個交易日,則此周的tradingday=4
與tradingday=-1
表示同一天
3, weekday
和tradingday
不能同時使用。
范例
以下的代碼片段非常簡單,在每周二固定運行打印一下現在的portfolio
剩余的資金:
def log_cash(context, bar_dict):
logger.info("Remaning cash: %r" % context.portfolio.cash)
def init(context):
#...
# 每周二打印一下剩余資金:
scheduler.run_weekly(log_cash, weekday=2)
# 每周第二個交易日打印剩余資金:
#scheduler.run_weekly(log_cash, tradingday=2)
每月某交易日
在每月的某個交易日運行一次傳入的function
:
scheduler.run_monthly(function,tradingday=t)
參數 | 類型 | 注釋 |
---|---|---|
function | function | 使傳入的function 每日交易開始前運行 |
tradingday | int - required | 范圍為[-23,1], [1,23] ,如: 1(-1):每月(倒數)第一個交易日,2(-2):每月(倒數)第二個交易日, ..., 28(-28):每月(倒數)第28個交易日 |
返回
None
注意
1, tradingday
的負數表示倒數
2, tradingday
表示交易日,如某月只有三個交易日,則此月的tradingday=3與tradingday=-1表示同一天
范例
以下的代碼片段非常簡單的展示了每個月第一個交易日的時候我們進行一次財務數據查詢,這樣子會非常有用在一些根據財務數據來自動調節倉位股票組合的算法來說:
def query_fundamental(context, bar_dict):
# 查詢revenue前十名的公司的股票并且他們的pe_ratio在25和30之間。打fundamentals的時候會有auto-complete方便寫查詢代碼。
fundamental_df = get_fundamentals(
query(
fundamentals.income_statement.revenue, fundamentals.eod_derivative_indicator.pe_ratio
).filter(
fundamentals.eod_derivative_indicator.pe_ratio > 25
).filter(
fundamentals.eod_derivative_indicator.pe_ratio < 30
).order_by(
fundamentals.income_statement.revenue.desc()
).limit(
10
)
)
# 將查詢結果dataframe的fundamental_df存放在context里面以備后面只需:
context.fundamental_df = fundamental_df
# 實時打印日志看下查詢結果,會有我們精心處理的數據表格顯示:
logger.info(context.fundamental_df)
update_universe(context.fundamental_df.columns.values)
# 在這個方法中編寫任何的初始化邏輯。context對象將會在你的算法策略的任何方法之間做傳遞。
def init(context):
# 每月的第一個交易日查詢以下財務數據,以確保可以拿到最新更新的財務數據信息用來調整倉位
scheduler.run_monthly(query_fundamental, tradingday=1)
定時間運行
scheduler
還可以用來做定時間運行,比如在每天開盤后的一小時后或一分鐘后定時運行,這里有很多種組合可以讓您達到各種自己想要達到的定時運行的目的。
注意:使用time_rule
定時運行只會在分鐘級別回測和實時模擬交易中有定義的效果,在日回測中只會默認依然在該天運行,并不能在固定的時間運行。
使用的方法是和上面的scheduler.run_daily
,scheduler.run_weekly
和scheduler.run_monthly
進行組合加入time_rule
來一起使用:
如何使用scheduler
來進行定日期運行已經在上面解釋的很清楚了,這里我們主要介紹如何使用time_rule
來進行定時間運行:
參數 | 類型 | 注釋 |
---|---|---|
time_rule | market_open / market_close | 定時具體幾點幾分運行某個函數。這個可以設置為market_open - 開市后多久運行或market_close - 閉市前多久運行。如果不設置time_rule 默認的值是開市后一分鐘運行。 |
martet_open /market_close參數如下:
參數 | 類型 | 注釋 |
---|---|---|
hour | int - option [0,4] | 具體在market_open/market_close后/前第多少小時執行, 股票的交易時間為[9:30 - 11:30],[13:01 - 15:00]共240分鐘,所以hour的范圍為 [0,4] |
minute | int - option [0,240] | 具體在market_open/market_close的后/前第多少分鐘執行,同上,股票每天交易時間240分鐘,所以minute的范圍為 [0,240],中午休市的時間區間會被忽略。 |
返回:
None
每天的開市后某個時間點運行:
scheduler.run_daily(function, time_rule=market_open(hour=x, minute=x))
每周的閉市前某個時間點運行:
scheduler.run_weekly(function, weekday=w ,tradingday=t, time_rule=market_close(hour=x, minute=x))
每月的第t個交易日開市后某個時間點運行:
scheduler.run_monthly(function,traingday=t ,time_rule=market_open(hour=x, minute=x))
注意
1, 在分鐘回測中如未指定time_rule
,則默認在開盤后一分鐘運行,即09:31分。
2, 如果兩個schedule
,分別使用market_open
與market_close
規則,但規則觸發時間在同一時刻,則market_open
的handle
一定在market_close
的handle
前執行。
3, 目前暫不支持開盤交易(即 09:30分交易) ,所以time_rule(minute=0)
和time_rule(hour=0)
將不會觸發任何事件。
4, market_open(minute=120)將在11:30執行, market_open(minute=121)在13:01執行,中午休市的區間會被忽略。
范例
- 每天開盤后一小時:
scheduler.run_daily(function, time_rule=market_open(hour=1))
- 每周周一開盤后一分鐘:
scheduler.run_weekly(function, weekday=1, time_rule=market_open(minute=1))
- 每月第一個交易日收盤前一小時:
scheduler.run_monthly(function, tradingday=1,time_rule=market_close(hour=1))
其他方法
update_universe
update_universe(id_or_symbols)
這個方法傳入一個或一個列表的id_or_symbol(s)
作為參數,用以更新現在關注的證券的集合(e.g
.:股票池)。PS:會在下一個bar事件觸發時候產生(新的關注的股票池更新)效果。并且update_universe會是覆蓋(overwrite)的操作而不是在已有的股票池的基礎上進行增量添加。比如已有的股票池為['000001 .XSHE', '000024.XSHE']
然后調用了update_universe(['000030.XSHE'])
之后,股票池就會變成000030 .XSHE
一個股票了,隨后的數據更新也只會跟蹤000030.XSHE
這一個股票了。
參數 | 類型 | 注釋 |
---|---|---|
id_or_symbols | str或iterable of strings | 單個或一個id_or_symbol(s)列表. |
范例
下面的代碼是將股票池變更為只有2個股票000001.XSHE
和000024.XSHE
:
update_universe(['000001.XSHE', '000024.XSHE'])
instruments
instruments(id_or_symbols)
轉換單個string或一個string列表的order_book_id到instrument對象
參數 | 類型 | 注釋 |
---|---|---|
id_or_symbols | str或iterable of strings | 單個或一個列表的order_book_id,中國市場的A股的order_book_ids是類似‘000001.XSHE’的寫法 |
返回
單個或一個列表的<a href="/api/python/chn#instrument-object" target="_blank">instrument對象</a> - 用id_or_symbol請求的。
范例
- 只得到單個instrument的對象:
[In]instruments('000001.XSHE')
[Out]
<Instrument: industry_name='貨幣金融服務', listed_date=datetime.datetime(1991, 4, 3, 0, 0), round_lot=100.0, listing=False, abbrev_symbol='PAYH', symbol='平安銀行', industry_code='J66', type='CS', sector_code='Financials', sector_name='金融', order_book_id='000001.XSHE'>
- 得到一個列表的instrument對象 - 中國股票:
[In]instruments(['平安銀行', '000024.XSHE'])
[Out]
[<Instrument: industry_name='貨幣金融服務', listed_date=datetime.datetime(1991, 4, 3, 0, 0), round_lot=100.0, listing=False, abbrev_symbol='PAYH', symbol='平安銀行', industry_code='J66', type='CS', sector_code='Financials', sector_name='金融', order_book_id='000001.XSHE'>,
<Instrument: industry_name='房地產業', listed_date=datetime.datetime(1993, 6, 7, 0, 0), round_lot=100.0, listing=False, abbrev_symbol='ZSDC', symbol='招商地產', industry_code='K70', type='CS', sector_code='Financials', sector_name='金融', order_book_id='000024.XSHE'>]
history
history(bar_count, frequency, field)
history
函數返回所有已關注證券的歷史行情,同時支持日以及分鐘歷史數據。以pandas的DataFrame對象裝載為時間序列。
注意:在我們最新加入的可以動態處理調整證券池的功能以后,您并不只能使用history
函數拿到已經加入證券池的歷史數據,您可以拿到所有想要拿的任意的證券的歷史數據了。
參數 | 類型 | 注釋 |
---|---|---|
bar_count |
int-required | 表示回溯的bar的數量 |
frequency |
str-required | 表示回溯時以什么樣的頻率進行。例如"1d"或"1m"分別表示每日和每分鐘 |
field |
str-required | 制定返回的DataFrame中以哪個指標作為數據值,可取“open”,“close”,“high”,“low”,“volume”,“last”, "total_turnover" - 總成交額 |
返回:
DataFrame
范例:
- 拿取四天的歷史數據:
print (history(4, '1d', 'close')['000001.XSHE'])
當前日期:2013-01-05
日期 | 收盤價格 |
---|---|
2013-01-02 | 12.0 |
2013-01-03 | 11.0 |
2013-01-04 | 13.0 |
2013-01-05 | 11.0 |
- 拿取四分鐘的歷史數據:
print(history(4, '1m', 'close')['000001.XSHE'])
當前時間:2014-01-06 09:34:00
日期 | 收盤價格 |
---|---|
2014-01-06 09:31 | 8.2569 |
2014-01-06 09:32 | 8.2292 |
2014-01-06 09:33 | 8.2014 |
2014-01-06 09:34 | 8.2083 |
plot
plot(series_name, value)
plot
函數可以將時間序列的數據傳給頁面進行繪圖,結果是以時間為橫軸,value為縱軸的曲線。
參數 | 類型 | 注釋 |
---|---|---|
'series_name' | str - required | 繪制曲線的名稱 |
'value' | float - required | 當前日期的曲線的點的值 |
范例:
# 你選擇的證券的數據更新將會觸發此段邏輯,例如日或分鐘歷史數據切片或者是實時數據切片更新
def handle_bar(context, bar_dict):
# TODO: 開始編寫你的算法吧!
plot('close', bar_dict['000001.XSHE'].close)
plot('high', bar_dict['000001.XSHE'].high)
plot('low', bar_dict['000001.XSHE'].low)
plot('open', bar_dict['000001.XSHE'].open)
拿到當前時間
context.now
使用以上的方法就可以在handle_bar
中拿到當前的bar的時間,比如day bar的話就是那天的時間,minute bar的話就是這一分鐘的時間點。
Bar對象
Ricequant的后端算法交易系統會處理你的算法中所有關注的證券,我們支持的包括股票、ETF、LOF、分級基金和期貨。
它會發送bar
事件并且將來還可以發送其他的事件給你的算法策略(比如:tick數據)。bar_dict
是所有的關注的證券的bar數據的一個總集合,你可以在handle_bar
中拿取到bar
對象,其中包含了該證券的所有的市場數據信息。
例如,如果你想拿到平安銀行股票'000001.XSHE'的切片數據信息,那么可以使用這段代碼bar_dict['000001.XSHE']
。下面會介紹我們已經支持的bar
對象的屬性:
同時對bar
對象我們也支持如下的轉換方法:
mavg(intervals, frequency='day')
可以用來計算某個證券的某段時間的移動平均價格,默認單位是‘天’
參數 | 類型 | 注釋 |
---|---|---|
間隔 | int | 一段時間間隔,比如:3 |
頻率 | str | 間隔的頻率,默認是“天” |
vwap(intervals, frequency='day')
可以用來計算某個證券的某段時間的加權平均價格,默認單位是“天”
參數 | 類型 | 注釋 |
---|---|---|
間隔 | int | 一段時間間隔,比如:3 |
頻率 | str | 間隔的頻率,默認是“天” |
Order對象
在order對象中的屬性:
參數 | 類型 | 注釋 |
---|---|---|
instrument |
instrument對象 | 訂單對應的證券的instrument對象 |
filled_shares |
float | 該訂單已經成交的股數 |
quantity |
float | 該訂單的所有的股數 |
Portfolio對象
portfolio
對象包含算法策略的所有的投資組合的信息。在日級別回測中,這表示的是每日收盤以后的投資組合信息。可以使用context.portfolio
去拿取portfolio
對象的信息。
并且有以下的屬性:
參數 | 類型 | 注釋 |
---|---|---|
starting_cash |
float | 回測或實盤交易給算法策略設置的初始資金 |
cash |
float | 現在投資組合中剩余的現金 |
total_returns |
float | 算法投資組合至今的累積百分比收益率。計算方法是現在的投資組合價值/投資組合的初始資金。投資組合價值包含剩余現金和其市場價值。 |
daily_returns |
float | 當前最新一天的每日收益。 |
market_value |
float | 投資組合當前的市場價值(未實現/平倉的價值) |
portfolio_value |
float | 當前投資組合的總共價值,包含市場價值和剩余現金。 |
pnl |
float | 當前投資組合的¥盈虧 |
start_date |
DateTime | 策略投資組合的回測/實時模擬交易的開始日期 |
annualized_returns |
float | 投資組合的年化收益率 |
positions |
Dictionary | 一個包含所有倉位的字典,以id_or_symbol作為鍵,position 對象作為值,關于position的更多的信息可以在下面的部分找到。 |
dividend_receivable |
float | 投資組合在分紅現金收到賬面之前的應收分紅部分。具體細節在分紅部分 |
Position對象
position
對象代表一個證券的倉位信息。可以通過positions字典拿到,例如:如果你的投資組合有平安銀行股票(000001.XSHE)的倉位,你可以通過以下代碼拿到它的倉位:
context.portfolio.positions['000001.XSHE']
并且position
對象有以下的屬性:
參數 | 類型 | 注釋 |
---|---|---|
quantity |
int | 未平倉部分的總股數。 |
bought_quantity |
int | 該證券的總買入股數,例如:如果你的投資組合并沒有任何平安銀行的成交,那么平安銀行這個股票的倉位就是0. |
sold_quantity |
int | 該證券的總賣出股數,例如:如果你的投資組合曾經買入過平安銀行股票200股并且賣出過100股,那么這個屬性會返回100. |
bought_value |
float | 該證券的總買入的價值,等于每一個該證券的買入成交的價格*買入股數的總和。 |
sold_value |
float | 該證券的總賣出價值,等于每一個該證券的賣出成交的價格*賣出股數的總和。 |
total_orders |
int | 該倉位的總訂單的次數。 |
total_trades |
int | 該倉位的總成交的次數。 |
sellable |
int | 該倉位可賣出股數。T+1的市場中sellable = 所有持倉-今日買入的倉位。 |
average_cost |
float | 獲得該持倉的買入均價,計算方法為每次買入的數量做加權平均。 |
market_value |
float | 獲得該持倉的實時市場價值。 |
value_percent |
float | 獲得該持倉的實時市場價值在總投資組合價值中所占比例,取值范圍[0, 1]。 |
Instrument對象
Instrument
代表所有的金融證券,例如:可以是股票,ETF,指數和期貨合同。
股票,ETF,指數Instrument對象
股票,ETF,指數Instrument對象有如下的屬性:
參數 | 類型 | 注釋 |
---|---|---|
order_book_id |
str | 證券的獨特的標識符。 |
symbol |
str | 證券的易讀的名字。 |
abbrev_symbol |
str | 證券的名稱縮寫,比如:在中國A股就是股票的拼音縮寫,‘PAYH’就是平安銀行股票的證券名縮寫。 |
round_lot |
int | 一手是多少股,中國A股一手是100股。 |
sector_code |
str | 板塊縮寫代碼,全球通用標準定義。 |
sector_name |
str | 以當地語言為標準的板塊代碼名。 |
industry_code |
str | 國民經濟行業分類代碼。 |
industry_name |
str | 國民經濟行業分類名稱。 |
listing |
bool | 該證券是否還在交易所交易。 |
listed_date |
DateTime | 該證券的上市日期。 |
type |
str | 需要使用種類簡稱,下面的type列表會解釋我們目前支持的證券類型:'CS', 'INDX', 'LOF', 'ETF', 'FenjiMu', 'FenjiA', 'FenjiB', 'Future' |
board_type |
str | 'MainBoard' - 主板,'GEM' - 創業板 |
開發
pyvenv venv
source venv/bin/activate
pip install -e .
運行單元測試
py.test