Wind Python案例

  • 基础函数使用实例
    • 本案例演示如何使用WindPy接口提取数据。代码示例如下:
  • 输出DataFrame格式
    • 案例1. 输出WindData对象并转化为Pandas格式
    • 案例2. 量化接口直接输出DataFrame
  • 订阅实时行情
    • 案例1. 订阅实时行情,并存储到硬盘中
    • 案例2. 订阅实时行情,并在界面中展示
    • 案例3. 订阅实时行情,并放入分线程中
  • 获取板块数据
    • 案例1. 获取沪深300指数最新成分股并保存为JSON文件
    • 案例2. 获取沪深300成分股历史数据并存入数据库中
    • 案例3. 获取沪深300成分股数据并保存为CSV文件
    • 案例4. 获取沪深300成分股数据并保存如数据库
  • 数据可视化
    • 案例1. 绘制收盘价日期序列
    • 案例2. 绘制K线图,并叠加成交量的折线图
  • 设置Windows计划任务
  • 策略回测
  • 交易模块多账户下单

基础函数使用实例

本案例演示如何使用WindPy接口提取数据。代码示例如下:

from WindPy import ww.start()
# 命令如何写可以用命令生成器来辅助完成
# 定义打印输出函数,用来展示数据使用
def printpy(outdata):if outdata.ErrorCode!=0:print('error code:'+str(outdata.ErrorCode)+'\n')return()for i in range(0,len(outdata.Data[0])):strTemp=''if len(outdata.Times)>1:strTemp=str(outdata.Times[i])+' 'for k in range(0, len(outdata.Fields)):strTemp=strTemp+str(outdata.Data[k][i])+' 'print(strTemp)# 通过wsd来提取时间序列数据,比如取开高低收成交量,成交额数据
print('\n\n'+'-----通过wsd来提取时间序列数据,比如取开高低收成交量,成交额数据-----'+'\n')
wsddata1=w.wsd("000001.SZ", "open,high,low,close,volume,amt", "2015-11-22", "2015-12-22", "Fill=Previous")
printpy(wsddata1)# 通过wsd来提取各个报告期财务数据
print('\n\n'+'-----通过wsd来提取各个报告期财务数据-----'+'\n')
wsddata2=w.wsd("600000.SH", "tot_oper_rev,tot_oper_cost,opprofit,net_profit_is", "2008-01-01", "2015-12-22", "rptType=1;Period=Q;Days=Alldays;Fill=Previous")
printpy(wsddata2)# 通过wss来取截面数据
print('\n\n'+'-----通过wss来取截面数据-----'+'\n')
wssdata=w.wss("600000.SH,600007.SH,600016.SH", "ev,total_shares","tradeDate=20151222;industryType=1")
printpy(wssdata)# 通过wst来取日内成交数据,最新7日内数据
print('\n\n'+'-----通过wst来取日内成交数据-----'+'\n')
wstdata=w.wst("IF.CFE", "last,volume", "2019-4-2 09:00:00", "2019-4-2 14:04:45")
printpy(wstdata)# 通过wsi来取日内分钟数据,三年内数据
print('\n\n'+'-----通过wsi来取日内分钟数据-----'+'\n')
wsidata=w.wsi("IF.CFE", "open,high,low,close,volume,amt", "2018-12-22 09:00:00", "2018-12-22 14:06:15")
printpy(wsidata)# 通过wset来取数据集数据
print('\n\n'+'-----通过wset来取数据集数据,获取沪深300指数权重-----'+'\n')
wsetdata=w.wset("IndexConstituent","date=20151222;windcode=000300.SH;field=date,wind_code,i_weight")
printpy(wsetdata)

输出DataFrame格式

本案例演示如何以DataFrame格式输出数据。在测试以下案例前,请确保已经安装了Pandas。

案例1. 输出WindData对象并转化为Pandas格式

# 案例1. 输出WindData对象并转化为Pandas格式
'''本案例以WSD接口为例,演示如何将输出的WindData转化为DataFrame。WSD接口返回的WindData对象有以下几个字段:ErrorCodeCodesFieldsTimesData
其中,Data为返回的数据,Fields和Times分别为获取的指标名称和日期序列。
'''
from WindPy import w
import pandas as pd
import datetimew.start()# 取数据的命令如何写可以用命令生成器来辅助完成
wsd_data=w.wsd("000001.SZ", "open,high,low,close", "2015-12-10", "2015-12-22", "Fill=Previous")if wsd_data.ErrorCode == 0:#演示如何将api返回的数据装入Pandas的Seriesopen=pd.Series(wsd_data.Data[0])high=pd.Series(wsd_data.Data[1])low=pd.Series(wsd_data.Data[2])close=pd.Series(wsd_data.Data[3])print('open:/n',open)print('high:/n',high)print('low:/n',low)print('close:/n',close)#演示如何将api返回的数据装入Pandas的DataFramefm=pd.DataFrame(wsd_data.Data,index=wsd_data.Fields,columns=wsd_data.Times)fm=fm.T #将矩阵转置print('fm:/n',fm)
else:print("Error Code:", wsd_data.ErrorCode)print("Error Message:", wsd_data.Data[0][0])

案例2. 量化接口直接输出DataFrame

# 案例2. 量化接口直接输出DataFrame
'''
通过在参数表中增加usedf=True,WindPy支持直接输出DataFrame格式。此时,WindPy函数返回错误码和提取的数据。其中数据的格式为DataFrame。
以下以WSD为例,展示如何使用WindPy函数以DataFrame格式提取数据:
'''
from WindPy import w
import pandas as pd
import datetimew.start()
error_code, wsd_data=w.wsd("000001.SZ", "open,high,low,close", "2015-12-10", "2015-12-22", "Fill=Previous", usedf=True)if error_code == 0:print(wsd_data)
else:print("Error Code:", error_code)print("Error Message:", wsd_data.iloc[0, 0])

订阅实时行情

案例1. 订阅实时行情,并存储到硬盘中

# 案例1. 订阅实时行情,并存储到硬盘中
'''本案例演示如何通过WSQ函数订阅实时行情数据,并存储到硬盘中。示例代码分为两个部分,一部分是用WSQ订阅所需的行情指标,另一部分定义了回调函数,用于处理实时推送的行情数据。在运行示例代码后,程序会一致运行。如果需要停止运行,可以输入"q"结束订阅并保存文件。以下为示例Python代码:
'''
from WindPy import w
import osdef myCallback(indata: w.WindData):"""Callback function for WSQparams------indata: WindData, accepts the received market quotation data. WindData has the following fields: .ErrorCode: error code, if it is 0, the code runs successfully.StateCode: state code. No need to process it..RequestID: save the request ID of WSQ request.Codes: wind code of the securities .Fields: fields for the received data.Times: local time rather than the corresponding time for the recieved data.Data: market quotation data"""print(indata)if indata.ErrorCode!=0:print('error code:'+str(indata.ErrorCode)+'\n')return()global begintimelastvalue =""for k in range(0,len(indata.Fields)):if(indata.Fields[k] == "RT_TIME"):begintime = indata.Data[k][0]if(indata.Fields[k] == "RT_LAST"):lastvalue = str(indata.Data[k][0])string = str(begintime) + " " + lastvalue +"\n"pf.writelines(string)print(string)pf.flush()start_ret = w.start()if start_ret.ErrorCode != 0:print("Start failed")print("Error Code:", start_ret.ErrorCode)print("Error Message:", start_ret.Data[0])
else:# Open a file to write.pf = open('pywsqdataif.data', 'w')# Subscribe market quotation datawsq_ret = w.wsq("CN.SG","rt_time,rt_last",func=myCallback)if wsq_ret.ErrorCode != 0:print("Error Code:", wsq_ret.ErrorCode)ext = ''while ext != 'q':ext = input('Enter "q" to exit')w.cancelRequest(0)pf.close()

案例2. 订阅实时行情,并在界面中展示

# 案例2. 订阅实时行情,并在界面中展示
'''本案例将演示如何通过WSQ订阅实时行情,同时通过PyQt模块在界面中展示所订阅的两个品种的现价、盘口报价、成交量及部分订阅指标差值的信息。详细的代码可以从本案例的附件中下载。以下只展示主脚本的代码:
'''
# quotedlg.pyfrom PyQt5.Qt import *
from PyQt5.QtCore import pyqtSlot as Slot
from WindPy import w
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figureimport globaldef
import ui_quote
import wsqw.start()MAC = True
try:from PyQt5.QtGui import qt_mac_set_native_menubar
except ImportError:MAC = Falseclass QuoteDlg(QDialog, ui_quote.Ui_Dialog):def __init__(self, parent=None):super(QuoteDlg, self).__init__(parent)self.setupUi(self)self.sec1Edit.setFocus()self.setWindowTitle("Wind API Demo---WSQ Subscrib")self.updateUi()self.initGraph()def initGraph(self):self.scene = QGraphicsScene()self.dr = Figure_Canvas()self.scene.addWidget(self.dr)self.graphicsView.setScene(self.scene)@Slot()def on_subscribeButton_clicked(self):self.subscribeButton.setEnabled(False)self.cancelButton.setEnabled(True)self.textBrowser.clear()globaldef.secID = []globaldef.indID = []globaldef.secID.extend([self.sec1Edit.text().upper(), self.sec2Edit.text().upper()])globaldef.indID.extend(['rt_time'.upper(), 'rt_bid1'.upper(), 'rt_ask1'.upper(),'rt_bsize1'.upper(), 'rt_asize1'.upper(), 'rt_last'.upper()])self.qThread = wsq.feeder()self.qThread.start()self.qThread.update_data.connect(self.handle_display)self.qThread.update_data.connect(self.handle_graphic)def handle_display(self, data):# Update UIself.last1Edit.setText('{0:.4f}'.format(data[0][5]))self.last2Edit.setText('{0:.4f}'.format(data[1][5]))self.bidvol1Edit.setText('{0:.4f}'.format(data[0][3]))self.bidvol2Edit.setText('{0:.4f}'.format(data[1][3]))self.bid1Edit.setText('{0:.4f}'.format(data[0][1]))self.bid2Edit.setText('{0:.4f}'.format(data[1][1]))self.ask1Edit.setText('{0:.4f}'.format(data[0][2]))self.ask2Edit.setText('{0:.4f}'.format(data[1][2]))self.askvol1Edit.setText('{0:.4f}'.format(data[0][4]))self.askvol2Edit.setText('{0:.4f}'.format(data[1][4]))self.spread1Edit.setText('{0:.4f}'.format(globaldef.spreadBid))self.spread2Edit.setText('{0:.4f}'.format(globaldef.spreadAsk))self.textBrowser.append("<b>%s</b> | Spd_Bid:<b>%s</b> | Spd_Ask:<b>%s</b>|"% (str(int(data[0][0])).zfill(6), '{0:.4f}'.format(globaldef.spreadBid),'{0:.4f}'.format(globaldef.spreadAsk)))def handle_graphic(self, data):self.dr.plot()@Slot()def on_cancelButton_clicked(self):self.subscribeButton.setEnabled(True)self.cancelButton.setEnabled(False)self.qThread.finished()@Slot(str)def on_sec1Edit_textEdited(self, text):self.updateUi()@Slot(str)def on_sec2Edit_textEdited(self, text):self.updateUi()def updateUi(self):enable = bool(self.sec1Edit.text()) and bool(self.sec2Edit.text())self.subscribeButton.setEnabled(enable)self.cancelButton.setEnabled(enable)class Figure_Canvas(FigureCanvas):"""Derived from class FigureCanvas, so that this class is both a Qwidget of PyQt5 and a FigureCanvas of matplotlib.This is a key step to link PyQt5 and matplotlib"""def __init__(self, parent=None, width=7.4, height=5, dpi=100):# Create an Figure. Note that this is figure of matplotlib rather a figure of matplotlib.pyplotfig = Figure(figsize=(width, height), dpi=dpi)FigureCanvas.__init__(self, fig) # Initialize the parent classself.setParent(parent)# Call method add_subplot of figure, which is similar to method subplot of matplotlib.pyplotself.axes1 = fig.add_subplot(311)self.axes2 = fig.add_subplot(312)self.axes3 = fig.add_subplot(313)def plot(self):self.axes1.clear()self.axes1.plot(globaldef.plotTime, globaldef.plotLast, color='k', alpha=0.9, linewidth=0.5)self.axes1.xaxis.set_visible(False)self.axes1.set_title("Real Time Spread_Last Trend Graph", fontsize=10)self.axes2.clear()self.axes2.plot(globaldef.plotTime, globaldef.plotBid, color='k', alpha=0.9, linewidth=0.5)self.axes2.xaxis.set_visible(False)self.axes2.set_title("Real Time Spread_Bid Trend Graph", fontsize=10)self.axes3.clear()self.axes3.plot(globaldef.plotTime, globaldef.plotAsk, color='k', alpha=0.9, linewidth=0.5)self.axes3.set_title("Real Time Spread_Ask Trend Graph", fontsize=10)self.draw()if __name__ == "__main__":import sysapp = QApplication(sys.argv)form = QuoteDlg()form.show()app.exec_()

案例3. 订阅实时行情,并放入分线程中

案例3. 订阅实时行情,并放入分线程中
本案例将演示如何订阅实时行情,并把数据接受模块放到一个分线程里。示例代码如下:import threading
from WindPy import ww.start()#define the callback function
def myCallback(indata):if indata.ErrorCode!=0:print('error code:'+str(indata.ErrorCode)+'\n')return()lastvalue =""for k in range(0,len(indata.Fields)):if(indata.Fields[k] == "RT_LAST"):lastvalue = str(indata.Data[k][0])string = lastvalue +"\n"print(string)class feeder(threading.Thread):def __init__(self,threadID,name):threading.Thread.__init__(self)self.threadID = threadIDself.name = namedef run(self):w.start()w.wsq("IF.CFE","rt_time,rt_last",func=myCallback)
#to subscribe IF.CFEthread1 =feeder(1,"feder-1")
thread1.start()ext = ''
while ext != 'q':ext = input('Enter "q" to exit\n')

获取板块数据

本专题以沪深300指数为例,演示如何通过Wind API获取板块或指数成分的历史数据并把获取的数据保存在本地。

案例1. 获取沪深300指数最新成分股并保存为JSON文件

案例1. 获取沪深300指数最新成分股并保存为JSON文件
本案例通过调用Wind API WSET函数获取沪深300指数的最新成分股代码,并保存为JSON文件。import json
from datetime import datetimefrom WindPy import wdef check_api_error(func):"""A decorator for WindPy functions, so that if a function fails to retrieve data, it will print the error code and the relevant message before exiting:param func: WindPy function that returns a WindData object:return: wrapper"""def wrapper(*args, **kwargs):data = func(*args, **kwargs)if data.ErrorCode != 0:print(data)exit()return datareturn wrapper# Decorate w.start
w.start = check_api_error(w.start)
# Decorate w.wset
w.wset = check_api_error(w.wset)# Start WindPy connection
w.start()# Get the date of today and convert it to a string with format YYYYMMDD
today = datetime.strftime(datetime.today(), "%Y%m%d")# Retrieve the wind codes of the constituent
stock_codes = w.wset("sectorconstituent", "date=" + today + ";windcode=000300.SH;field=wind_code")# Save the data in json
with open('HS300Constituent.json', mode='w') as f:json.dump(stock_codes.Data[0], f)

案例2. 获取沪深300成分股历史数据并存入数据库中

案例2. 获取沪深300成分股历史数据并存入数据库中
本案例演示如何通过Wind API获取沪深300指数的成分股及其历史数据,并借助Pandas的to_sql函数批量导入SQLite数据库。如需使用其他数据库,用户可自行参考sqlalchemy的文档进行设置。示例代码如下:# 本案例仅作参考,目的在于帮助WindPy的用户熟悉WindPy接口的使用方法。用户需根据实际需求自行编写、测试脚本
# 以下将演示如何下载沪深300成分股的历史数据并存入数据库import sqlite3
import timeimport pandas as pd
from WindPy import w
from sqlalchemy import create_engineclass WSDLoader:def __init__(self, start_date, end_date, db_engine):self._start_date = start_dateself._end_date = end_dateself._db_engine = db_engine@propertydef current_time(self):return time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime(time.time()))def __error_logger(self, wind_code, status, info=None):"""Log the errors occuring when retriving or saving data:param wind_code: str, wind code of the present security:param status: status parameters, e.g. the ErrorCode returned by Wind API:return: None"""error_log = pd.DataFrame(index=[wind_code])error_log.loc[wind_code, 'start_date'] = self._start_dateerror_log.loc[wind_code, 'end_date'] = self._end_dateerror_log.loc[wind_code, 'status'] = statuserror_log.loc[wind_code, 'table'] = 'stock_daily_data'error_log.loc[wind_code, 'args'] = 'Symbol: ' + wind_code + ' From ' + self._start_date + ' To ' + self._end_dateerror_log.loc[wind_code, 'error_info'] = infoerror_log.loc[wind_code, 'created_date'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))error_log.to_sql('stock_error_log', self._db_engine, if_exists='append')def fetch_historical_data(self, wind_codes, sleep_time=5):"""Retrieve the WSD data of specified windcodes:param wind_codes: List[str], the windcodes of specified securities:param sleep_time: number, the sleep time for the loop when an error occurs:return: None"""print(self.current_time, ": Start to Download A-Share Stocks")start_date = self._start_dateend_date = self._end_datedb_engine = self._db_enginew.start()for wind_code in wind_codes:print(self.current_time, ": {0}".format(wind_code))# The code can be generated using Code Generator. To get data in format DataFrame, add usedf=True in the parameter listerror_code, data = w.wsd(wind_code,"windcode,trade_code,open,high,low,close,pre_close,volume,amt",start_date,end_date,usedf=True)# Check if Wind API runs successfully. If error_code is not 0, it indicators an error occursif error_code != 0:# Output logself.__error_logger(wind_code, '{0}'.format(int(error_code)))# Print error messageprint(self.current_time, ":data %s : ErrorCode :%s" % (wind_code, error_code))print(data)# Pause the loop for the specified time when an error occurstime.sleep(sleep_time)# Skip the present iterationcontinuetry:# Save the data into the databasedata.to_sql('stock_daily_data', db_engine, if_exists='append')except Exception as e:self.__error_logger(wind_code, None)print(self.current_time, ": SQL Exception :%s" % e)print(self.current_time, ": Downloading A-Share Stock Finished .")def get_windcodes(self, trade_date=None):"""Retrieve the windcodes of CSI300 (沪深300) constituents:param trade_date: the date to retrieve the windcodes of the constituents:return: Error code or a list of windcodes"""w.start()if trade_date is None:trade_date = self._end_date# Retrieve the windcodes of CSI300 constituents. # Users can use Sector Constituents and Index Constituents of WSET to retrieve the constituents of a sector or an indexstock_codes = w.wset("sectorconstituent", "date=" + trade_date + ";windcode=000300.SH;field=wind_code")if stock_codes.ErrorCode != 0:# Return the error code when an error occursreturn stock_codes.ErrorCodeelse:# Return a list of windcodes if the data is achievedreturn stock_codes.Data[0]@staticmethoddef fetchall_data(wind_code):"""Fetch data from SQLite database:param str, wind_code::return: None"""conn = sqlite3.connect('example.db')c = conn.cursor()c.execute("SELECT * FROM stock_daily_data WHERE WINDCODE = ?", [(wind_code)])data = c.fetchall()if len(data) > 0:for row in c.fetchall():# Print the retrieved dataprint(row)else:print("No data found!")conn.close()@staticmethoddef fetchall_log():"""Retrieve the error log:return: None"""conn = sqlite3.connect('example.db')c = conn.cursor()c.execute("SELECT * FROM stock_error_log")for row in c.fetchall():# Print error logprint(row)conn.close()def main(start_date, end_date):"""The main function:param start_date: str, set the start date, format: YYYYMMDD:param end_date: str,set the end date, format: YYYYMMDD:return: None"""# The demonstration uses SQLite as an example. If you need to use another database, please refer to the documentation of sqlalchemydb_engine = create_engine('sqlite:///example.db')loader = WSDLoader(start_date, end_date, db_engine)wind_codes = loader.get_windcodes()if type(wind_codes) is not int:loader.fetch_historical_data(wind_codes)else:print('ErrorCode:', wind_codes)if __name__ == '__main__':start = '20140101'end = '20151231'main(start, end)WSDLoader.fetchall_data('002573.SZ')WSDLoader.fetchall_log()

案例3. 获取沪深300成分股数据并保存为CSV文件

案例3. 获取沪深300成分股数据并保存为CSV文件
本案例演示如何获取沪深300成分股数据并把获取的数据输出为DataFrame格式,然后借助Pandas的to_csv函数把获取到的数据保存为CSV文件。from WindPy import w
from datetime import datetime
import pandas as pdw.start()# Download the latest constituents of HS300 index
today = datetime.today().strftime('%Y-%m-%d')
windcodes = w.wset("sectorconstituent","date={0};windcode=000300.SH;field=wind_code".format(today))
assert windcodes.ErrorCode == 0, 'Download historical constituents, ErrorCode: {0}'.format(windcodes.ErrorCode)# Fetch the data of the last 12 months and return a dataframe
dataset = pd.DataFrame(columns=['WINDCODE', 'OPEN', 'HIGH', 'LOW', 'CLOSE', 'VOLUME', 'AMT'])
for windcode in windcodes.Data[0]:errorcode, data = w.wsd(windcode, "open,high,low,close,volume,amt", "-12M", today, "industryType=2;industryStandard=1", usedf=True)if errorcode != 0:print(windcode, ":ErrorCode:", errorcode)continuedata.loc[:, 'WINDCODE'] = windcodedataset = dataset.append(data, sort=False)dataset.index.name = 'DATE'
dataset.to_csv('HS300 Data.csv')

案例4. 获取沪深300成分股数据并保存如数据库

案例4. 获取沪深300成分股数据并保存如数据库
本案例演示如何获取一段时期内所有的沪深300指数的成分股,并借助Wind API的日期宏获取其自上市以来到选定日期的所有历史数据。获取的数据按照日期和WindCode逐行导入数据库中。本案例采用SQLite数据库进行演示。如需使用其他数据库,用户可以自行替换。示例代码如下:from WindPy import w
from datetime import datetime
import sqlite3# Connect to the database
conn = sqlite3.connect("example.db")
c = conn.cursor()# Create an empty table
table_names = c.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}'")
c.execute("DROP TABLE IF EXISTS stockprice")c.execute("""
CREATE TABLE stockprice (windcode VARCHAR(20) NOT NULL,tradedate VARCHAR(50),openprice FLOAT,highprice FLOAT,lowprice FLOAT,closeprice FLOAT,volume FLOAT,amt FLOAT)""")sql = "INSERT INTO stockprice VALUES (?, ?, ?, ?, ?, ?, ?, ?)"w.start()# Download the changes in the constituents and hisotrical constituents
windcodes_change = w.wset("indexhistory","startdate=2015-01-01;enddate=2020-01-01;windcode=000300.SH;field=tradedate,tradecode")
assert windcodes_change.ErrorCode == 0, 'Download constituents changes, ErrorCode: {0}'.format(windcodes_change.ErrorCode)
windcodes_2015 = w.wset("sectorconstituent","date=2015-01-01;windcode=000300.SH;field=wind_code")
assert windcodes_2015.ErrorCode == 0, 'Download historical constituents, ErrorCode: {0}'.format(windcodes_2015.ErrorCode)windcodes = list(set(windcodes_change.Data[1] + windcodes_2015.Data[0]))# Fetch data and save in the database
for windcode in windcodes:data = w.wsd(windcode, "open,high,low,close,volume,amt", "IPO", "2020-01-01", "industryType=2;industryStandard=1")if data.ErrorCode != 0:print(windcode, ":ErrorCode:", data.ErrorCode)continuefor i, date in enumerate(data.Times):sqlrow = list()for j, field in enumerate(data.Fields):sqlrow.append(data.Data[j][i])c.execute(sql, [(windcode), (date)] + sqlrow)conn.commit()conn.close()

数据可视化

案例1. 绘制收盘价日期序列

案例1. 绘制收盘价日期序列
from WindPy import *
import numpy as np
import pandas as pd
from datetime import datetime
import matplotlib.pylab as pltw.start()errorcode, df = w.wsd("002739.SZ", "close", "2016-05-17", "2020-05-18", "TradingCalendar=SZSE;Fill=Previous", usedf=True)plt.figure(figsize=(10, 7))
df['CLOSE'].plot()
plt.ylabel('Price', fontsize=14)
plt.xlabel('Date', fontsize=14)
plt.show()

案例2. 绘制K线图,并叠加成交量的折线图


案例2. 绘制K线图,并叠加成交量的折线图
from WindPy import *
import numpy as np
import pandas as pd
import talib as ta
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import datetime
from matplotlib.dates import date2numdef mkt_plot(quotes, field, sec): # quotes:行情数据-Dateframe类型 sec:标题  fig = plt.figure(figsize=(11,5))ax1 = fig.add_axes([0, 1, 1, 1])  ax1.set_title(sec, fontsize=15)ax1.grid(True, axis='y')ax1.set_xlim(-1, len(quotes)+1)for i in range(len(quotes)):close_price,open_price = quotes['CLOSE'].iloc[i], quotes['OPEN'].iloc[i]high_price, low_price = quotes['HIGH'].iloc[i], quotes['LOW'].iloc[i]trade_date = quotes.index[i]if close_price > open_price:#画阳线ax1.add_patch(patches.Rectangle((i-0.2, open_price), 0.4, close_price-open_price, fill=False, color='r'))ax1.plot([i, i], [low_price, open_price], 'r')ax1.plot([i, i], [close_price, high_price], 'r')else:#画阴线ax1.add_patch(patches.Rectangle((i-0.2, open_price), 0.4, close_price-open_price, color='g'))ax1.plot([i, i], [low_price, high_price], color='g')ax1.set_ylabel("Price", fontsize=15)ax1.set_xlabel("Date", fontsize=15)#设置x轴标签ax1.set_xticks(range(0,len(quotes),5))#位置ax1.set_xticklabels([(quotes.index[i]).strftime('%Y-%m-%d') for i in ax1.get_xticks()] , rotation=20)#标签内容ax2 = ax1.twinx()ax2.plot(range(len(quotes)), quotes[field.upper()])ax2.set_ylabel(field.capitalize(), fontsize=15)return figw.start()
errorcode, data = w.wsd("600028.SH", "open,high,low,close,volume","ED-1M" ,(datetime.date.today()-datetime.timedelta(days=1)).strftime('%Y-%m-%d'), "Fill=Previous", usedf=True
)
mkt_plot(data, 'volume', '中国石化 600028')plt.show()

设置Windows计划任务

本案例以Wind Python接口为例,介绍如何设置Windows计划任务。通过设定Windows计划任务,用户可以定时调用Wind API并进行数据处理。其他语言的Wind API程序也可通过类似的步骤设置Windows计划任务。

Windows计划任务的设置步骤以及批处理脚本参考附件中的readme.docx和wind_test.bat。测试用Python脚本如下:

from WindPy import w
import time
import osdef start():start_data = w.start()print()if start_data.ErrorCode == 0:print("Wind API started successfully")else:print("Error message:")print(start_data)time.sleep(5)data = w.wss("600000.SH", "sec_name,bsharename,sec_englishname,exchange_cn,exch_eng")time.sleep(5)print()if data.ErrorCode == 0:print("WSS ran successfully")print("The data is:")print(data)else:print("WSS failed to run")print("Error message:")print(data)w.stop()os.system('PAUSE')if __name__ == '__main__':start()

在设置Windows计划任务时,用户需根据系统环境调整本案例参考文件中的部分参数,并进行测试。测试可分以下三个步骤进行:

1.测试Python脚本并确保其能够正常运行并获取到数据
2.测试bat批处理脚本并确保其能够运行
3.设置Windows计划任务并测试

策略回测

使用量化接口wupf函数,结合终端PMS功能模块实现三种调仓方式下的策略回测。

flow_backtest.py 流水上传 holding_backtest.py 持仓上传 weight_backtest.py 权重上传

# -*- coding:utf-8 -*-
# Author:OpenAPISupport@wind.com.cn
# Editdate:2017-11-08from WindPy import *
import timew.start()class wupf_flow(object):def __init__(self,PortfoName,windAccount,windCode,originalCaptial,beginDate,endDate):reloadResult=self.reloadPortfo(PortfoName,windAccount)if reloadResult.ErrorCode!=0:self.throwError(reloadResult.Data[0][0])self.strategy(windCode,beginDate,endDate,originalCaptial,PortfoName,windAccount)#执行回测策略def strategy(self,windCode,beginDate,endDate,originalCaptial,PortfoName,windAccount):#接口获取回测数据closePrice=w.wsd(windCode, "close", beginDate, endDate, "Fill=Previous")     #[beginDate,endDate]收盘价ma10=w.wsd(windCode, "MA", beginDate, endDate, "MA_N=10","PriceAdj=F")       #[beginDate,endDate]5日均线ma30=w.wsd(windCode, "MA", beginDate, endDate, "MA_N=30","PriceAdj=F")       #[beginDate,endDate]10日均线tradeStatus=w.wsd(windCode, "trade_status", beginDate, endDate, "")          #[beginDate,endDate]交易状态#设置期初组合现金wupfCash=w.wupf(PortfoName, beginDate, "CNY", originalCaptial, "1","Direction=Short;Method=BuySell;CreditTrading=No;Owner="+windAccount+";type=flow")if wupfCash.ErrorCode!=0:self.throwError(wupfCash.Data[0][0])time.sleep(0.5)buyFlag=1for i in range(len(ma10.Data[0])):#10日均线与30日均线黄金交叉且30日均线向上运行, 买入if i>0 and buyFlag==1 and (ma10.Data[0][i-1] < ma30.Data[0][i-1] and ma10.Data[0][i] > ma30.Data[0][i] and ma30.Data[0][i-1] < ma30.Data[0][i]) and tradeStatus.Data[0][i]==u"交易":buyFlag=0wupfSecurity=w.wupf("PMStest",closePrice.Times[i].strftime("%Y%m%d"), windCode, "100", str(closePrice.Data[0][i]),"Direction=Long;Method=BuySell;CreditTrading=No;Owner="+windAccount+";type=flow")time.sleep(0.5)if wupfSecurity.ErrorCode!=0:self.throwError(wupfSecurity.Data[0][0])print closePrice.Times[i].strftime("%Y%m%d")+"_buy"#10日均线与30日均线死亡交叉, 卖出elif i>0 and buyFlag==0 and (ma10.Data[0][i-1] > ma30.Data[0][i-1] and ma10.Data[0][i] < ma30.Data[0][i]) and tradeStatus.Data[0][i]==u"交易":buyFlag=1wpfPosition=w.wpf("PMStest", "Position","view=PMS;date="+closePrice.Times[i].strftime("%Y%m%d")+";sectorcode=101;displaymode=1")time.sleep(0.5)if wpfPosition.ErrorCode!=0:self.throwError(wpfPosition.Data[0][0])wupfSecurity=w.wupf("PMStest",closePrice.Times[i].strftime("%Y%m%d"), windCode, "-"+str(wpfPosition.Data[3][0]), str(closePrice.Data[0][i]),"Direction=Long;Method=BuySell;CreditTrading=No;Owner="+windAccount+";type=flow")time.sleep(0.5)if wupfSecurity.ErrorCode!=0:self.throwError(wupfSecurity.Data[0][0])print closePrice.Times[i].strftime("%Y%m%d")+"_sell"#重置回测组合def reloadPortfo(self,PortfoName,windAccount):result=w.wupf(PortfoName, "", "", "", "","Owner="+windAccount+";reset=true")time.sleep(0.5)return result#抛出错误信息def throwError(self,Message):raise Exception(Message)       if __name__=="__main__":wupf_flow("PMStest", "W0817573", "300008.SZ","10000","20150101","20171031")

交易模块多账户下单

本案例为批量下单GUI。用户可以登录两个账号并在沪深市场模拟下单。

第1步:用户登录自己的股票账户,返回登录号(logonID),可参照例子中的登录函数。如果登陆成功,对应的LogonID图标后的"Off"将自动变成LogonID。

第2步:填写GUI中的登录号(LogonID)、股票代码、买卖方向、委托价格和委托数量, 并下单。

源代码和UI文件可从本页面的附件下载。代码如下:

import sys
from PyQt5 import QtCore,QtGui,uic,QtWidgets
from WindPy import w
w.start()qtCreatorFile="sample.ui" # The name of the used UI file
Ui_MainWindow,QtBaseClass = uic.loadUiType(qtCreatorFile)global accountNumber
accountNumber=0class MyApp(QtWidgets.QMainWindow,Ui_MainWindow): def __init__(self):QtWidgets.QMainWindow.__init__(self)Ui_MainWindow.__init__(self)self.setupUi(self)# Relate events with methodsself.accountLogin.clicked.connect(self.login)  self.torder.clicked.connect(self.torderProcess)  self.quit.clicked.connect(self.logout)  # Log on with the entered accountsdef login(self):global accountNumbermsg = list()for k in range(2):accountlabelName="account_label"+str(k)print(self.account_label0.text())temtText = eval("self."+accountlabelName+".text()")if temtText!="":windLogin=w.tlogon('0000','0',str(temtText),'123456','SHSZ') print(windLogin)if windLogin.ErrorCode == 0:exec('self.LogonID_label'+str(k)+'.setText(str(windLogin.Data[0][0]))')# Save ErrorMsgif windLogin.ErrorCode == 0:windLogin.Data[4][0] = 'Succeeded!'msg.append(windLogin.Data[4][0])accountNumber=k+1# Join saved ErrorMsgs to displaymsg = '\n'.join(msg)self.logon_msg_browser.setText(msg)  # Process order when the submit button is clickeddef torderProcess(self):tmp=[]for j in range(5):tmp.append("")table_info = []for i in range(5):table_info.append(tmp)msg = list()for i in range(5):if(len(eval('self.label{0}_1.text()'.format(i)))!=0):logon_id = eval('self.label{0}_0.text()'.format(i))windcode = eval('self.label{0}_1.text()'.format(i))trade_side = eval('self.label{0}_2.text()'.format(i))price = eval('self.label{0}_3.text()'.format(i))amount = eval('self.label{0}_4.text()'.format(i))# Wind code, trading direction, order price, amounttorderResult=w.torder(windcode,trade_side,price,amount,'OrderType=LMT;LogonID='+logon_id)# Save ErrorMsgmsg.append(torderResult.Data[8][0])# Join saved ErrorMsgs to dispalymsg = '\n'.join(msg)self.order_msg_browser_2.setText(msg) # Log out the accounts when the logout button is clickeddef logout(self):global accountNumberif accountNumber!=0:for i in range(1,accountNumber):w.tlogout(i)print(i)self.close()  if __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)window = MyApp()window.show()sys.exit(app.exec_())

Wind Python案例相关推荐

  1. 利用深度学习(Keras)进行癫痫分类-Python案例

    目录 癫痫介绍 数据集 Keras深度学习案例 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区 QQ交流群:903290195 癫痫介绍 癫痫,即俗称"羊癫风",是由多种 ...

  2. python项目实例初学者-经典Python案例,初学者的小帮手,立马学会Python!

    原标题:经典Python案例,初学者的小帮手,立马学会Python! 对于刚开始学习Python的人来说,会通过Python的一些经典案例练手,这样既可以加深对Python的理解,也可以增进自己的技术 ...

  3. 典型相关分析(cca)原理_CCA典型关联分析原理与Python案例

    文章来源于"脑机接口社区" CCA典型关联分析原理与Python案例​mp.weixin.qq.com Rose今天分享一下CCA的相关原理以及Python应用,CCA在EEG等脑 ...

  4. python装饰器setter_第7.27节 Python案例详解: @property装饰器定义属性访问方法getter、setter、deleter...

    上节详细介绍了利用@property装饰器定义属性的语法,本节通过具体案例来进一步说明. 一.    案例说明 本节的案例是定义Rectangle(长方形)类,为了说明问题,除构造函数外,其他方法都只 ...

  5. Python案例:破译爬虫项目实践活动日期密码

    Python案例:破译爬虫项目实践活动日期密码 一.下达编程任务 寒假期间,李铁有幸成为外星人教育Python爬虫项目实践活动的参与者.外星人教育给参加活动的同学都发了一条短信,告知了实践活动日期,但 ...

  6. Python案例:两种方法实现词频统计

    Python案例:两种方法实现词频统计 一.利用字典实现词频统计 1.编写源代码 2.查看运行结果 二.利用collections的Counter模块实现词频统计 <

  7. Python案例:查询城市天气并绘制最高气温与最低气温折线图

    Python案例:查询城市天气并绘制最高气温与最低气温折线图 一.解决思路 比如要查询"泸州"的天气. 1.首先获取泸州的城市代码 http://toy1.weather.com. ...

  8. Python案例:按键测试

    Python案例:按键测试 1.消息类文件message.py import pygameclass Message:def __init__(self, screen, text):self.scr ...

  9. Python案例:通过方向键移动屏幕上的图像

    Python案例:通过方向键移动屏幕上的图像 1.安装PyGame (1)下载PyGame http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame

  10. Python案例:用米粒填充国际象棋盘

    Python案例:用米粒填充国际象棋盘 一.古老传说 有个很古老的传说,那时候象棋刚刚发明出来,阿拉伯的一个国王一下就迷上了,觉得应该重奖发明这个游戏的人,结果发明者来了,他让人家提要求,人家说棋盘上 ...

最新文章

  1. iOS UITextField清空按钮
  2. 圣朱妮佩洛|San Junipero(2)
  3. 用Mina xscocket 通讯框架做(Flex)服务端
  4. 深入学习Web Service系列----异步开发模式
  5. linux安装mysql后怎么进去_linux安装mysql详细步骤
  6. 一些常用的meta标签及其作用
  7. linux select 进程id,Linux基础命令---显示进程ps
  8. 多个服务间多个自定义的ExceptionHandler类的执行顺序
  9. Spoken English-口语-练习频次
  10. photoshop cs5快捷键的用法总结
  11. 复习:线性表——顺序表
  12. 如何自学python知乎-如何快速学习python?
  13. isupper函数python_python字符串是否是大写-python 字符串大写-python isupper函数-python isupper函数未定义-嗨客网...
  14. Frank-Wolfe方法
  15. java栅栏_Java多线程 5.栅栏
  16. 光伏运维将面临行业洗牌?
  17. 4 看电影--贪心算法
  18. 一个人到过的12个国家,45座城市
  19. 12333提交显示服务器异常,掌上12333显示没有收到异地协助认证书什么原因_具体解决办法流程_3DM手游...
  20. 【Java】检查二叉树是否平衡。

热门文章

  1. 量子力学的经典教材_我是亲民_新浪博客
  2. 基于ASP.NET的企业进销存管理系统
  3. 如何让微信好友永远拉黑不了你?
  4. 增量学习(Incremental Learning)小综述
  5. Windows解压tar.gzip文件
  6. 微信公众号开发相关流程及功能介绍
  7. 爬取豆瓣Top250并存储Excel
  8. WIN7下怎么安装iis教程
  9. 巨波公第3子登国公后裔在荆州(巨波公6子的后裔,全部水落石出)
  10. QT+VS开发界面入门(qt界面在VS2022实现自动生成槽函数)