Sina finance offers granular bars for futures listed on Chinese futures exchanges, so basically we can source them via either java or python.
#Loads rb2110 60m bars from Sina's MinLine
class SinaMinLine():
def __init__(self):
pass
def load(self,symbol="RB2110",type="60"):
url_template="https://stock2.finance.sina.com.cn/futures/api/jsonp.php/var%20_{symbol}_{type}_{ts}=/InnerFuturesNewService.getFewMinLine?symbol={symbol}&type={type}"
ts=datetime.datetime.now().strftime('%Y%m%d%H%M%S')
url=url_template.format(symbol=symbol,type=type,ts=ts)
print("url={}".format(url))
res=requests.get(url, verify=False)
tokens=re.split("[(]|[)]",res.text)
bars=json.loads(tokens[1])
print("scraped symbol={},count={}".format(symbol,len(bars)))
#collect all bars into dataframe
rows_list = []
for bar in bars:
item_dict={}
item_dict["date"]=datetime.datetime.strptime(bar['d'],'%Y-%m-%d %H:%M:%S') #2021-05-25 11:15:00
item_dict["open"]=float(bar['o'])
item_dict["high"]=float(bar['h'])
item_dict["low"]=float(bar['l'])
item_dict["close"]=float(bar['c'])
item_dict["volume"]=float(bar['v'])
rows_list.append(item_dict)
df = pd.DataFrame(rows_list)
return df
If you have pro license for Tushare for futures bars, then it works fairly similar. Unfortunately I don’t, and the following codes will get you load daily bars for a stock, for illustration purpose.
#Loads bars from Tushare
class TushareProApi():
def __init__(self):
#initialize tushare api
ts.set_token('please_use_your_token')
self.pro=ts.pro_api()
def histx(self,code='600519.SH', start_date='20220101',end_date='20220601'):
df=self.pro.daily(ts_code='600519.SH',start_date=start_date,end_date=end_date)
return df
#remember to format your data to fit backtrader's standard like following
# pro=TushareProApi()
# df=pro.histx('600519.SH','20220101','20220606')
# df['date']=pd.to_datetime(df['trade_date'],format='%Y%m%d')
# df=df.set_index('date')
# df=df[['open','high','low','close','vol']]
# print(df.tail(20))
# data=bt.feeds.PandasData(...)
With the a given dataframe from SinaMinLine, we can convert its format so that backtrader could recognize. To avoid repeatedly downloading data from Sina, we can save the dataframe to CSV (or pickle), and reuse the persisted copy for coding or backtests.
The following code snippet will initialize backtrader, load some 60min data, inject the data to backtrader, and finally run backtrader. This completes demo on loading 60m bars to backtrader.
if __name__ == '__main__':
#initialize backtest engine
cerebro = bt.Cerebro()
#load data from sina MinLine
sina=SinaMinLine()
df=sina.load()
df.index=df['date']
#inject dataframe to backtrader via PandasData
data=bt.feeds.PandasData(dataname=df)
#convert bars to dataframe
cerebro.adddata(data)
#run
cerebro.run()