“Financial document futures”版本间的差异
来自cslt Wiki
(→附录手册:) |
|||
| (相同用户的12个中间修订版本未显示) | |||
| 第1行: | 第1行: | ||
=期货虚拟交易平台使用手册= | =期货虚拟交易平台使用手册= | ||
#创建平台 | #创建平台 | ||
| − | #:先到目录下/nfs/disk/work/users/tanghui/platform/platform-and-data-api/ | + | #:先到目录下/nfs/disk/work/users/tanghui/platform/platform-and-data-api/future_platform/test_platform,把main.py文件拷贝到自己的文件夹下。至此,我们的回测系统已经创建好了 |
#使用平台 | #使用平台 | ||
##总体介绍 | ##总体介绍 | ||
| 第28行: | 第28行: | ||
###:这个是获得最近2天的收盘价 | ###:这个是获得最近2天的收盘价 | ||
###:;具体的信息还有'HIGH'(最高价),'LOW'(最低价),'VOLUME'(成交量),'VALUE'(成交额),'OPEN'(开盘价),'CLOSE'(收盘价)。 | ###:;具体的信息还有'HIGH'(最高价),'LOW'(最低价),'VOLUME'(成交量),'VALUE'(成交额),'OPEN'(开盘价),'CLOSE'(收盘价)。 | ||
| + | ###account.order(secID,num,ways='1') | ||
| + | ###:这个函数是指定某只股票的买,卖。 | ||
| + | ###:;account.order('IF',300,ways='1') 表示IF合约买300只 | ||
| + | ###:;account.order('IF',-300,ways='1') 表示IF合约卖300只 | ||
| + | ###:;ways='1'表示优先平今 ,其他值表示为优先平仓。默认为‘1’ | ||
| + | ##account.order_close_today(secID,num) | ||
| + | ##:这个函数表示优先平今,如果能够平掉的话,使用的是开盘价 | ||
| + | ##:如果平掉的数量小于今天开仓的数量,就平掉对应数据的数量就行了。 | ||
| + | ##:如果平掉的数量大于今天开仓的数量,小于总的开仓数量;则先平掉今天的开仓,然后再平掉历史的开仓时数量 | ||
| + | ##:如果平掉的数量大于总的开仓量,则先平掉所有的开仓量,然后再开仓剩下的数量 | ||
| + | ##account.order_close(secID,num) | ||
| + | ##:这个函数表示优先平仓,如果能够平掉的话,使用的是开盘价 | ||
| + | ##:如果平掉的数量小于历史的开仓的数量,则首先平掉历史开仓的数量 | ||
| + | ##:如果平掉的数量大于历史开仓的数量,小于总的开仓数量;则首先平掉历史的开苍量,然后再平掉今天的开仓量 | ||
| + | ##:如果平掉的数量大于总的开仓量,则先平掉所有的开仓量,然后再开仓剩下的数量 | ||
| + | ##account.calculate_close_today_position(self,secID,num,way="1"): | ||
| + | ##:这个执行平仓的函数 | ||
| + | ##:way='1' 表示的优先平今,其他值为优先平仓,默认值为1 | ||
| + | ##:表示secID该合约对应平仓的手数 | ||
| + | ##account.calculate_open_position(self,secID,num): | ||
| + | ##:这个是执行开仓的程序 | ||
| + | ##:表示secID该合约对应的开仓的手数 | ||
| + | ##;函数calculate_close_today_position(self,secID,num,way="1")和calculate_open_position(self,secID,num) 都是通过order函数来调用的 | ||
| + | ##account.record_trade(self,secID,num,count,operation): | ||
| + | ##:这个函数表示的是,在每一次交易成功之后都会记录一次该交易的运行结果。 | ||
| + | ##:secID:合约编号,num:交易数量,count:该分钟交易的次数,operation:这次交易的方式 | ||
| + | ##account.record_minute(self): | ||
| + | ##:这个函数表示的是 | ||
| + | |||
| + | =程序交易规则:= | ||
| + | #程序的买和卖都是都是有手续费的。不同的合约使用的手续费不一样 | ||
| + | #程序的买和卖使用的都是昨天的信息,其中买用的是昨天的开盘价,卖用的是昨天的收盘价 | ||
| + | #程序的交易没有使用滑点 | ||
| + | |||
| + | |||
| + | =测试Demo= | ||
| + | #-*- coding: utf-8 -*- | ||
| + | #coding = utf-8 | ||
| + | import datetime,time | ||
| + | import numpy as np | ||
| + | import os,sys | ||
| + | sys.path.append("/raw/sidhome/fin/future_platform") | ||
| + | from Account import Account | ||
| + | |||
| + | #order ("IF",-4,"1") | ||
| + | #IF:合约名称; | ||
| + | #-4:对该合约操作的手数 ,正数为买入,负数为卖出 | ||
| + | #"1" :表示优先平今,"0" 表示优先平仓 默认为优先平今 | ||
| + | def handle_data(account,day,min): | ||
| + | num = 10 | ||
| + | his = account.get_attribute_minute_history("OPEN",2) | ||
| + | if not his: | ||
| + | return | ||
| + | for secID in account.universe: | ||
| + | if his[secID] is None: | ||
| + | continue | ||
| + | avr = his[secID].mean() | ||
| + | if avr > his[secID][-1]: | ||
| + | account.order(secID,day,min,num*2+5,"1") | ||
| + | else: | ||
| + | account.order(secID,day,min,-num,"1") | ||
| + | return | ||
| + | |||
| + | def daily_run(account,str_temp_date,day): | ||
| + | mins=0 | ||
| + | str_start_time = str_temp_date + " " + "09:15:00" | ||
| + | str_end_time = str_temp_date + " "+ "16:00:00" | ||
| + | start_time=datetime.datetime.strptime(str_start_time,"%Y%m%d %H:%M:%S") | ||
| + | end_time = datetime.datetime.strptime(str_end_time,"%Y%m%d %H:%M:%S") | ||
| + | temp_date = start_time | ||
| + | while temp_date <= end_time: | ||
| + | str_temp_time = temp_date.strftime("%Y%m%d %H:%M:%S") | ||
| + | temp_date = temp_date + datetime.timedelta(minutes=1) | ||
| + | temp_day=str_temp_time[:8] | ||
| + | temp_time =str_temp_time[9:] | ||
| + | account.current_time = temp_time | ||
| + | account.current_day = temp_day | ||
| + | mins= account.update_minute(day,mins) | ||
| + | handle_data(account,day,mins) | ||
| + | account.record_minute() | ||
| + | if mins > 4: | ||
| + | return | ||
| + | |||
| + | def simulation(start,end,universe,captial_base): | ||
| + | account = Account() | ||
| + | account.init_all(universe,start,end,captial_base) | ||
| + | start_date = datetime.datetime.strptime(start,"%Y%m%d") | ||
| + | end_date = datetime.datetime.strptime(end,"%Y%m%d") | ||
| + | temp_date = start_date | ||
| + | day = 0 | ||
| + | while temp_date <= end_date: | ||
| + | str_temp_date=temp_date.strftime("%Y%m%d") | ||
| + | account.current_day = str_temp_date | ||
| + | day = day+1 | ||
| + | temp_date = temp_date + datetime.timedelta(days = 1) | ||
| + | daily_run(account,str_temp_date,day) | ||
| + | account.update_daily() | ||
| + | account.record_minute() | ||
| + | return | ||
| + | |||
| + | if __name__ == "__main__": | ||
| + | start = "20150813" | ||
| + | end = "20150814" | ||
| + | universe=["IF"] | ||
| + | captial_base=500006 | ||
| + | simulation(start,end,universe,captial_base) | ||
| + | |||
| + | =附录手册:= | ||
| + | # 程序流程图 [http://cslt.riit.tsinghua.edu.cn/mediawiki/images/5/5d/Futures.pdf] | ||
| + | # 具体流程 [http://cslt.riit.tsinghua.edu.cn/mediawiki/images/7/79/%E5%85%B7%E4%BD%93%E6%B5%81%E7%A8%8B.pdf] | ||
2015年12月5日 (六) 09:45的最后版本
期货虚拟交易平台使用手册
- 创建平台
- 先到目录下/nfs/disk/work/users/tanghui/platform/platform-and-data-api/future_platform/test_platform,把main.py文件拷贝到自己的文件夹下。至此,我们的回测系统已经创建好了
- 使用平台
- 总体介绍
- 首先导入了几个包,它主要是python库和使用这个平台所依赖的包。
- 然后有三个函数,分别是 'main','simulation','daily_run','handle_data':
- main包含需要使用的回测的基本信息。有起始日期(start),截止日期(end),所用的股票(universe),起始资金(captial_base)
- simulation主要是根据输入的信息,初始化account虚拟账户类,然后主要负责每天运行,主要执行的是daily_run()。
- daily_run主要是每分钟运行程序,主要执行的是account.update_minute()
- handle_data是开发者需要编写程序的地方。这个里面有很有用的东西,我们接下来会慢慢介绍它。
- mian函数使用
- 在main函数中,开发者可以选择起始日期(start),截止日期(end)。日期的格式为‘%Y-%m-%d’,比如:‘2014-01-01’,但不要出现错误日期如:'2014-02-30'。
- 所选的股票(universe),可以选择自己所选的期货合约经行回测,比如 universe= ["IF","cu"]
- 起始资金(captial_base)是你的启动资金
- simulation函数使用
- 这个主要是初始化相关的类,使日期在设定的起始日期和截止日期之间运行,并且每天调用daily_run函数。
- daily_run函数的使用
- 从每个交易日的开始日期到截止日期之间进行回测。然后在每分钟都计算一下当前的总价值。
- handle_date函数使用
- 这个里面主要使用的是account类,这个类中有很多信息供开发者去使用,接下来将会给大家来介绍如何去编写程序回测
- account.current_day:
- 该变量是模拟测试中今天的日期,string类型的。
- account.get_attribute_minute_history(attribute, range) :
- 这个函数是获取最近几天的信息,比如:
- his = account.get_attribute_minute_history("OPEN",2)
- 结果: his = array([11,12])
- 这个是获得最近2天的收盘价
- 具体的信息还有'HIGH'(最高价),'LOW'(最低价),'VOLUME'(成交量),'VALUE'(成交额),'OPEN'(开盘价),'CLOSE'(收盘价)。
- 这个函数是获取最近几天的信息,比如:
- account.order(secID,num,ways='1')
- 这个函数是指定某只股票的买,卖。
- account.order('IF',300,ways='1') 表示IF合约买300只
- account.order('IF',-300,ways='1') 表示IF合约卖300只
- ways='1'表示优先平今 ,其他值表示为优先平仓。默认为‘1’
- 这个函数是指定某只股票的买,卖。
- account.order_close_today(secID,num)
- 这个函数表示优先平今,如果能够平掉的话,使用的是开盘价
- 如果平掉的数量小于今天开仓的数量,就平掉对应数据的数量就行了。
- 如果平掉的数量大于今天开仓的数量,小于总的开仓数量;则先平掉今天的开仓,然后再平掉历史的开仓时数量
- 如果平掉的数量大于总的开仓量,则先平掉所有的开仓量,然后再开仓剩下的数量
- account.order_close(secID,num)
- 这个函数表示优先平仓,如果能够平掉的话,使用的是开盘价
- 如果平掉的数量小于历史的开仓的数量,则首先平掉历史开仓的数量
- 如果平掉的数量大于历史开仓的数量,小于总的开仓数量;则首先平掉历史的开苍量,然后再平掉今天的开仓量
- 如果平掉的数量大于总的开仓量,则先平掉所有的开仓量,然后再开仓剩下的数量
- account.calculate_close_today_position(self,secID,num,way="1"):
- 这个执行平仓的函数
- way='1' 表示的优先平今,其他值为优先平仓,默认值为1
- 表示secID该合约对应平仓的手数
- account.calculate_open_position(self,secID,num):
- 这个是执行开仓的程序
- 表示secID该合约对应的开仓的手数
- 函数calculate_close_today_position(self,secID,num,way="1")和calculate_open_position(self,secID,num) 都是通过order函数来调用的
- account.record_trade(self,secID,num,count,operation):
- 这个函数表示的是,在每一次交易成功之后都会记录一次该交易的运行结果。
- secID:合约编号,num:交易数量,count:该分钟交易的次数,operation:这次交易的方式
- account.record_minute(self):
- 这个函数表示的是
- 总体介绍
程序交易规则:
- 程序的买和卖都是都是有手续费的。不同的合约使用的手续费不一样
- 程序的买和卖使用的都是昨天的信息,其中买用的是昨天的开盘价,卖用的是昨天的收盘价
- 程序的交易没有使用滑点
测试Demo
#-*- coding: utf-8 -*-
#coding = utf-8
import datetime,time
import numpy as np
import os,sys
sys.path.append("/raw/sidhome/fin/future_platform")
from Account import Account
#order ("IF",-4,"1")
#IF:合约名称;
#-4:对该合约操作的手数 ,正数为买入,负数为卖出
#"1" :表示优先平今,"0" 表示优先平仓 默认为优先平今
def handle_data(account,day,min):
num = 10
his = account.get_attribute_minute_history("OPEN",2)
if not his:
return
for secID in account.universe:
if his[secID] is None:
continue
avr = his[secID].mean()
if avr > his[secID][-1]:
account.order(secID,day,min,num*2+5,"1")
else:
account.order(secID,day,min,-num,"1")
return
def daily_run(account,str_temp_date,day):
mins=0
str_start_time = str_temp_date + " " + "09:15:00"
str_end_time = str_temp_date + " "+ "16:00:00"
start_time=datetime.datetime.strptime(str_start_time,"%Y%m%d %H:%M:%S")
end_time = datetime.datetime.strptime(str_end_time,"%Y%m%d %H:%M:%S")
temp_date = start_time
while temp_date <= end_time:
str_temp_time = temp_date.strftime("%Y%m%d %H:%M:%S")
temp_date = temp_date + datetime.timedelta(minutes=1)
temp_day=str_temp_time[:8]
temp_time =str_temp_time[9:]
account.current_time = temp_time
account.current_day = temp_day
mins= account.update_minute(day,mins)
handle_data(account,day,mins)
account.record_minute()
if mins > 4:
return
def simulation(start,end,universe,captial_base):
account = Account()
account.init_all(universe,start,end,captial_base)
start_date = datetime.datetime.strptime(start,"%Y%m%d")
end_date = datetime.datetime.strptime(end,"%Y%m%d")
temp_date = start_date
day = 0
while temp_date <= end_date:
str_temp_date=temp_date.strftime("%Y%m%d")
account.current_day = str_temp_date
day = day+1
temp_date = temp_date + datetime.timedelta(days = 1)
daily_run(account,str_temp_date,day)
account.update_daily()
account.record_minute()
return
if __name__ == "__main__": start = "20150813" end = "20150814" universe=["IF"] captial_base=500006 simulation(start,end,universe,captial_base)