增加交易策略、交易指标、量化库代码等文件夹
This commit is contained in:
+1612
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,315 @@
|
||||
'''逐行解释代码:
|
||||
|
||||
1.导入所需的模块和库,包括 time、table(来自 matplotlib.pyplot)、pandas、numpy、numba 和 operator。
|
||||
|
||||
2.定义了一个名为 process 的函数,用于处理买卖盘的字典数据。
|
||||
|
||||
3.定义了一个名为 data 的函数,用于读取并处理 tick 数据,生成分钟级别的 bar 数据。
|
||||
|
||||
4.定义了一个名为 orderflow_df_new 的函数,用于处理 tick 数据和分钟级别的 bar 数据,生成订单流数据。
|
||||
|
||||
5.定义了一个名为 GetOrderFlow_dj 的函数,用于计算订单流的指标(堆积)。
|
||||
|
||||
6.定义了一个名为 back_data 的函数,用于保存回测数据。
|
||||
|
||||
7.在 if __name__ == "__main__": 下,首先调用 data() 函数获取 tick 数据和分钟级别的 bar 数据。
|
||||
|
||||
然后调用 orderflow_df_new() 函数,传入 tick 数据和 bar 数据,生成订单流数据 ofdata。
|
||||
|
||||
打印输出 ofdata。
|
||||
|
||||
8.调用 back_data() 函数,将订单流数据保存为回测数据。
|
||||
|
||||
打印输出 "done",表示程序执行完毕。
|
||||
|
||||
总体而言,该代码的功能是从 tick 数据中生成分钟级别的 bar 数据,然后根据 bar 数据计算订单流,并将订单流数据保存为回测数据。
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
# 使用前注意事项:
|
||||
1、修改read_csv对应的文件地址
|
||||
2、修改resample对应的转化周期
|
||||
3、修改folder_path、to_csv对应的保存路径
|
||||
'''
|
||||
|
||||
import time
|
||||
from matplotlib.pyplot import table
|
||||
from datetime import timedelta,datetime
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from numba import *
|
||||
from numba import cuda
|
||||
import operator
|
||||
|
||||
import os
|
||||
|
||||
import chardet
|
||||
|
||||
def process(bidDict,askDict):
|
||||
bidDictResult,askDictResult = {},{}
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
#print('bidDict:',list(bidDict.keys()))
|
||||
#print('askDict:',list(askDict.keys()))
|
||||
#print('sList:',sList)
|
||||
#240884432
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
bidDictResult[s] = bidDict[s]
|
||||
else:
|
||||
bidDictResult[s] = 0
|
||||
if s in askDict:
|
||||
askDictResult[s] = askDict[s]
|
||||
else:
|
||||
askDictResult[s] = 0
|
||||
|
||||
return bidDictResult,askDictResult
|
||||
|
||||
def dataload(data,cycle):
|
||||
#日期修正
|
||||
# data['业务日期'] = data['业务日期'].dt.strftime('%Y-%m-%d')
|
||||
# data['datetime'] = data['业务日期'] + ' '+data['最后修改时间'].dt.time.astype(str) + '.' + data['最后修改毫秒'].astype(str)
|
||||
# # 将 'datetime' 列的数据类型更改为 datetime 格式
|
||||
data['datetime'] = pd.to_datetime(data['datetime'], errors='coerce', format='%Y-%m-%d %H:%M:%S.%f')
|
||||
# 如果需要,可以将 datetime 列格式化为字符串
|
||||
#data['formatted_date'] = data['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S.%f')
|
||||
#计算瞬时成交量
|
||||
# data['volume'] = data['数量'] - data['数量'].shift(1)
|
||||
data['volume'] = data['volume'].fillna(0)
|
||||
#整理好要用的tick数据元素
|
||||
tickdata =pd.DataFrame({'datetime':data['datetime'],'symbol':data['symbol'],'lastprice':data['lastprice'],
|
||||
'volume':data['volume'],'bid_p':data['bid_p'],'bid_v':data['bid_v'],'ask_p':data['ask_p'],'ask_v':data['ask_v']})
|
||||
#tickdata['datetime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
|
||||
# # 找到满足条件的行的索引
|
||||
# condition = tickdata['datetime'].dt.time == pd.to_datetime('22:59:59').time()
|
||||
# indexes_to_update = tickdata.index[condition]
|
||||
|
||||
# # 遍历索引,将不一致的日期更新为上一行的日期
|
||||
# for idx in indexes_to_update:
|
||||
# if idx > 0:
|
||||
# tickdata.at[idx, 'datetime'] = tickdata.at[idx - 1, 'datetime'].replace(hour=22, minute=59, second=59)
|
||||
|
||||
# 确保日期列按升序排序
|
||||
tickdata.sort_values(by='datetime', inplace=True)
|
||||
# rule = '1T
|
||||
bardata = tickdata.resample(on = 'datetime',rule = cycle,label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
#240884432
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
return tickdata,bardata
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def orderflow_df_new(df_tick,df_min):
|
||||
df_of=pd.DataFrame({})
|
||||
t1 = time.time()
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
endArray = pd.to_datetime(df_min['datetime']).values
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
dt=endArray[index]
|
||||
for indexTick in range(indexFinal,len(df_tick)):
|
||||
if tTickArray[indexTick] > tEnd:
|
||||
break
|
||||
elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] <= tEnd):
|
||||
if indexTick==0:
|
||||
Bp = round(bp1TickArray[indexTick],2)
|
||||
Ap = round(ap1TickArray[indexTick],2)
|
||||
else:
|
||||
Bp = round(bp1TickArray[indexTick - 1],2)
|
||||
Ap = round(ap1TickArray[indexTick - 1],2)
|
||||
LastPrice = round(lastTickArray[indexTick],2)
|
||||
Volume = volumeTickArray[indexTick]
|
||||
if LastPrice >= Ap:
|
||||
if LastPrice in askDict.keys():
|
||||
askDict[LastPrice] += Volume
|
||||
else:
|
||||
askDict[LastPrice] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if LastPrice in bidDict.keys():
|
||||
bidDict[LastPrice] += Volume
|
||||
else:
|
||||
bidDict[LastPrice] = Volume
|
||||
indexFinal = indexTick
|
||||
|
||||
bidDictResult,askDictResult = process(bidDict,askDict)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
# 过滤'volume'列小于等于0的行
|
||||
df = df[df['volume'] > 0]
|
||||
# 重新排序DataFrame,按照'datetime'列进行升序排序
|
||||
df = df.sort_values(by='datetime', ascending=True)
|
||||
# 重新设置索引,以便索引能够正确对齐
|
||||
df = df.reset_index(drop=True)
|
||||
#df['ticktime']=tTickArray[indexTick]
|
||||
df['dj']=GetOrderFlow_dj(df)
|
||||
#print(df)
|
||||
df_of = pd.concat([df_of, df], ignore_index=True)
|
||||
print(time.time() - t1)
|
||||
return df_of
|
||||
|
||||
def GetOrderFlow_dj(kData):
|
||||
itemAskBG=['rgb(0,255,255)', 'rgb(255,0,255)', "rgb(255,182,193)"] # 买盘背景色
|
||||
itemBidBG=['rgb(173,255,47)', 'rgb(255,127,80)', "rgb(32,178,170)"] # 卖盘背景色
|
||||
Config={
|
||||
'Value1':3,
|
||||
'Value2':3,
|
||||
'Value3':3,
|
||||
'Value4':True,
|
||||
}
|
||||
aryData=kData
|
||||
djcout=0
|
||||
for index,row in aryData.iterrows():
|
||||
kItem=aryData.iloc[index]
|
||||
high=kItem['high']
|
||||
low=kItem['low']
|
||||
close=kItem['close']
|
||||
open=kItem['open']
|
||||
dtime=kItem['datetime']
|
||||
price_s=kItem['price']
|
||||
Ask_s=kItem['Ask']
|
||||
Bid_s=kItem['Bid']
|
||||
delta=kItem['delta']
|
||||
|
||||
price_s=price_s
|
||||
Ask_s=Ask_s
|
||||
Bid_s=Bid_s
|
||||
|
||||
gj=0
|
||||
xq=0
|
||||
gxx=0
|
||||
xxx=0
|
||||
for i in np.arange (0, len(price_s),1) :
|
||||
duiji={
|
||||
'price':0,
|
||||
'time':0,
|
||||
'longshort':0,
|
||||
'cout':0,
|
||||
'color':'blue'
|
||||
}
|
||||
if i==0 :
|
||||
delta=delta
|
||||
|
||||
order= {
|
||||
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
if i>=0 and i<len(price_s)-1:
|
||||
if (order["Bid"]["Value"]>Ask_s[i+1]*int(Config['Value1'])):
|
||||
order["Bid"]["Color"]=itemAskBG[1]
|
||||
gxx+=1
|
||||
gj+=1
|
||||
if gj>=int(Config['Value2']) and Config['Value4']==True:
|
||||
duiji['price']=price_s[i]
|
||||
duiji['time']=dtime
|
||||
duiji['longshort']=-1
|
||||
duiji['cout']=gj
|
||||
duiji['color']='rgba(0,139,0,0.45)'#绿色
|
||||
if float(duiji['price'])>0:
|
||||
djcout+=-1
|
||||
else :
|
||||
gj=0
|
||||
if i>=1 and i<=len(price_s)-1:
|
||||
if (order["Ask"]["Value"]>Bid_s[i-1]*int(Config['Value1'])):
|
||||
xq+=1
|
||||
xxx+=1
|
||||
order["Ask"]["Color"]=itemBidBG[1]
|
||||
if xq>=int(Config['Value2']) and Config['Value4']==True:
|
||||
duiji['price']=price_s[i]
|
||||
duiji['time']=dtime
|
||||
duiji['longshort']=1
|
||||
duiji['cout']=xq
|
||||
duiji['color']='rgba(255,0,0,0.45)' #红色
|
||||
if float(duiji['price'])>0:
|
||||
djcout+=1
|
||||
else :
|
||||
xq=0
|
||||
return djcout
|
||||
|
||||
def back_data(df,csv_path):
|
||||
# 创建新的DataFrame并填充需要的列
|
||||
new_df = pd.DataFrame()
|
||||
new_df['datetime'] = pd.to_datetime(df['datetime'], format='%Y/%m/%d %H:%M')
|
||||
new_df['close'] = df['close']
|
||||
new_df['open'] = df['open']
|
||||
new_df['high'] = df['high']
|
||||
new_df['low'] = df['low']
|
||||
new_df['volume'] = df['volume']
|
||||
new_df['sig'] = df['dj']
|
||||
new_df['symbol'] = df['symbol']
|
||||
new_df['delta'] = df['delta']
|
||||
new_df.to_csv(csv_path,index=False)
|
||||
#new_df.to_csv(f'{sym}back_ofdata_dj.csv',index=False)
|
||||
|
||||
|
||||
def ofdata_dj(file, cycle):
|
||||
print("file:", file)
|
||||
csv_df = pd.DataFrame()
|
||||
dir = os.getcwd()
|
||||
fileNum_errors = 0
|
||||
try:
|
||||
# 读取csv文件,并使用第一行为列标题,编译不通过可以改为gbk
|
||||
csv_df = pd.read_csv(file,encoding='GBK',parse_dates=['datetime'])
|
||||
except:
|
||||
file_path = os.path.join(dir, file)
|
||||
fileNum_errors += 1
|
||||
with open(file_path, 'rb') as file:
|
||||
data = file.read()
|
||||
|
||||
# 使用chardet检测编码
|
||||
detected_encoding = chardet.detect(data)['encoding']
|
||||
# print("%s当前文件不为gbk格式,其文件格式为%s,需要转换为gbk格式,错误总数为%s"%(file,detected_encoding,fileNum_errors))
|
||||
print("%s:%s当前文件不为gbk格式,其文件格式为%s,需要转换为gbk格式,错误总数为%s"%(datetime.now().strftime('%Y-%m-%d %H:%M:%S'),file_path,detected_encoding,fileNum_errors))
|
||||
|
||||
with open('output_error.txt', 'a') as f:
|
||||
print("%s:%s当前文件不为gbk格式,其文件格式为%s,需要转换为gbk格式,错误总数为%s"%(datetime.now().strftime('%Y-%m-%d %H:%M:%S'),file_path,detected_encoding,fileNum_errors), file = f)
|
||||
# print(csv_df)
|
||||
tick,bar=dataload(csv_df,cycle)
|
||||
ofdata = orderflow_df_new(tick,bar)
|
||||
print(ofdata)
|
||||
code_value = csv_df.loc[0, 'main_contract']# csv_df['main_contract'].keys
|
||||
|
||||
return code_value, ofdata
|
||||
@@ -0,0 +1,319 @@
|
||||
'''逐行解释代码:
|
||||
|
||||
1.导入所需的模块和库,包括 time、table(来自 matplotlib.pyplot)、pandas、numpy、numba 和 operator。
|
||||
|
||||
2.定义了一个名为 process 的函数,用于处理买卖盘的字典数据。
|
||||
|
||||
3.定义了一个名为 data 的函数,用于读取并处理 tick 数据,生成分钟级别的 bar 数据。
|
||||
|
||||
4.定义了一个名为 orderflow_df_new 的函数,用于处理 tick 数据和分钟级别的 bar 数据,生成订单流数据。
|
||||
|
||||
5.定义了一个名为 GetOrderFlow_dj 的函数,用于计算订单流的指标(堆积)。
|
||||
|
||||
6.定义了一个名为 back_data 的函数,用于保存回测数据。
|
||||
|
||||
7.在 if __name__ == "__main__": 下,首先调用 data() 函数获取 tick 数据和分钟级别的 bar 数据。
|
||||
|
||||
然后调用 orderflow_df_new() 函数,传入 tick 数据和 bar 数据,生成订单流数据 ofdata。
|
||||
|
||||
打印输出 ofdata。
|
||||
|
||||
8.调用 back_data() 函数,将订单流数据保存为回测数据。
|
||||
|
||||
打印输出 "done",表示程序执行完毕。
|
||||
|
||||
总体而言,该代码的功能是从 tick 数据中生成分钟级别的 bar 数据,然后根据 bar 数据计算订单流,并将订单流数据保存为回测数据。
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
# 使用前注意事项:
|
||||
1、修改read_csv对应的文件地址
|
||||
2、修改resample对应的转化周期
|
||||
3、修改folder_path、to_csv对应的保存路径
|
||||
'''
|
||||
|
||||
import time
|
||||
from matplotlib.pyplot import table
|
||||
from datetime import timedelta
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from numba import *
|
||||
from numba import cuda
|
||||
import operator
|
||||
|
||||
import os
|
||||
|
||||
|
||||
|
||||
def process(bidDict,askDict):
|
||||
bidDictResult,askDictResult = {},{}
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
#print('bidDict:',list(bidDict.keys()))
|
||||
#print('askDict:',list(askDict.keys()))
|
||||
#print('sList:',sList)
|
||||
#240884432
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
bidDictResult[s] = bidDict[s]
|
||||
else:
|
||||
bidDictResult[s] = 0
|
||||
if s in askDict:
|
||||
askDictResult[s] = askDict[s]
|
||||
else:
|
||||
askDictResult[s] = 0
|
||||
|
||||
return bidDictResult,askDictResult
|
||||
|
||||
|
||||
|
||||
|
||||
def dataload(data):
|
||||
#日期修正
|
||||
# data['业务日期'] = data['业务日期'].dt.strftime('%Y-%m-%d')
|
||||
# data['datetime'] = data['业务日期'] + ' '+data['最后修改时间'].dt.time.astype(str) + '.' + data['最后修改毫秒'].astype(str)
|
||||
# # 将 'datetime' 列的数据类型更改为 datetime 格式
|
||||
data['datetime'] = pd.to_datetime(data['datetime'], errors='coerce', format='%Y-%m-%d %H:%M:%S.%f')
|
||||
# 如果需要,可以将 datetime 列格式化为字符串
|
||||
#data['formatted_date'] = data['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S.%f')
|
||||
#计算瞬时成交量
|
||||
# data['volume'] = data['数量'] - data['数量'].shift(1)
|
||||
data['volume'] = data['volume'].fillna(0)
|
||||
#整理好要用的tick数据元素
|
||||
tickdata =pd.DataFrame({'datetime':data['datetime'],'symbol':data['symbol'],'lastprice':data['lastprice'],
|
||||
'volume':data['volume'],'bid_p':data['bid_p'],'bid_v':data['bid_v'],'ask_p':data['ask_p'],'ask_v':data['ask_v']})
|
||||
#tickdata['datetime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
|
||||
# # 找到满足条件的行的索引
|
||||
# condition = tickdata['datetime'].dt.time == pd.to_datetime('22:59:59').time()
|
||||
# indexes_to_update = tickdata.index[condition]
|
||||
|
||||
# # 遍历索引,将不一致的日期更新为上一行的日期
|
||||
# for idx in indexes_to_update:
|
||||
# if idx > 0:
|
||||
# tickdata.at[idx, 'datetime'] = tickdata.at[idx - 1, 'datetime'].replace(hour=22, minute=59, second=59)
|
||||
|
||||
# 确保日期列按升序排序
|
||||
tickdata.sort_values(by='datetime', inplace=True)
|
||||
|
||||
bardata = tickdata.resample(on = 'datetime',rule = '1T',label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
#240884432
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
return tickdata,bardata
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def orderflow_df_new(df_tick,df_min):
|
||||
df_of=pd.DataFrame({})
|
||||
t1 = time.time()
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
endArray = pd.to_datetime(df_min['datetime']).values
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
dt=endArray[index]
|
||||
for indexTick in range(indexFinal,len(df_tick)):
|
||||
if tTickArray[indexTick] > tEnd:
|
||||
break
|
||||
elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] <= tEnd):
|
||||
if indexTick==0:
|
||||
Bp = round(bp1TickArray[indexTick],2)
|
||||
Ap = round(ap1TickArray[indexTick],2)
|
||||
else:
|
||||
Bp = round(bp1TickArray[indexTick - 1],2)
|
||||
Ap = round(ap1TickArray[indexTick - 1],2)
|
||||
LastPrice = round(lastTickArray[indexTick],2)
|
||||
Volume = volumeTickArray[indexTick]
|
||||
if LastPrice >= Ap:
|
||||
if LastPrice in askDict.keys():
|
||||
askDict[LastPrice] += Volume
|
||||
else:
|
||||
askDict[LastPrice] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if LastPrice in bidDict.keys():
|
||||
bidDict[LastPrice] += Volume
|
||||
else:
|
||||
bidDict[LastPrice] = Volume
|
||||
indexFinal = indexTick
|
||||
|
||||
bidDictResult,askDictResult = process(bidDict,askDict)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
# 过滤'volume'列小于等于0的行
|
||||
df = df[df['volume'] > 0]
|
||||
# 重新排序DataFrame,按照'datetime'列进行升序排序
|
||||
df = df.sort_values(by='datetime', ascending=True)
|
||||
# 重新设置索引,以便索引能够正确对齐
|
||||
df = df.reset_index(drop=True)
|
||||
#df['ticktime']=tTickArray[indexTick]
|
||||
df['dj']=GetOrderFlow_dj(df)
|
||||
#print(df)
|
||||
df_of = pd.concat([df_of, df], ignore_index=True)
|
||||
print(time.time() - t1)
|
||||
return df_of
|
||||
|
||||
def GetOrderFlow_dj(kData):
|
||||
itemAskBG=['rgb(0,255,255)', 'rgb(255,0,255)', "rgb(255,182,193)"] # 买盘背景色
|
||||
itemBidBG=['rgb(173,255,47)', 'rgb(255,127,80)', "rgb(32,178,170)"] # 卖盘背景色
|
||||
Config={
|
||||
'Value1':3,
|
||||
'Value2':3,
|
||||
'Value3':3,
|
||||
'Value4':True,
|
||||
}
|
||||
aryData=kData
|
||||
djcout=0
|
||||
for index,row in aryData.iterrows():
|
||||
kItem=aryData.iloc[index]
|
||||
high=kItem['high']
|
||||
low=kItem['low']
|
||||
close=kItem['close']
|
||||
open=kItem['open']
|
||||
dtime=kItem['datetime']
|
||||
price_s=kItem['price']
|
||||
Ask_s=kItem['Ask']
|
||||
Bid_s=kItem['Bid']
|
||||
delta=kItem['delta']
|
||||
|
||||
price_s=price_s
|
||||
Ask_s=Ask_s
|
||||
Bid_s=Bid_s
|
||||
|
||||
gj=0
|
||||
xq=0
|
||||
gxx=0
|
||||
xxx=0
|
||||
for i in np.arange (0, len(price_s),1) :
|
||||
duiji={
|
||||
'price':0,
|
||||
'time':0,
|
||||
'longshort':0,
|
||||
'cout':0,
|
||||
'color':'blue'
|
||||
}
|
||||
if i==0 :
|
||||
delta=delta
|
||||
|
||||
order= {
|
||||
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
if i>=0 and i<len(price_s)-1:
|
||||
if (order["Bid"]["Value"]>Ask_s[i+1]*int(Config['Value1'])):
|
||||
order["Bid"]["Color"]=itemAskBG[1]
|
||||
gxx+=1
|
||||
gj+=1
|
||||
if gj>=int(Config['Value2']) and Config['Value4']==True:
|
||||
duiji['price']=price_s[i]
|
||||
duiji['time']=dtime
|
||||
duiji['longshort']=-1
|
||||
duiji['cout']=gj
|
||||
duiji['color']='rgba(0,139,0,0.45)'#绿色
|
||||
if float(duiji['price'])>0:
|
||||
djcout+=-1
|
||||
else :
|
||||
gj=0
|
||||
if i>=1 and i<=len(price_s)-1:
|
||||
if (order["Ask"]["Value"]>Bid_s[i-1]*int(Config['Value1'])):
|
||||
xq+=1
|
||||
xxx+=1
|
||||
order["Ask"]["Color"]=itemBidBG[1]
|
||||
if xq>=int(Config['Value2']) and Config['Value4']==True:
|
||||
duiji['price']=price_s[i]
|
||||
duiji['time']=dtime
|
||||
duiji['longshort']=1
|
||||
duiji['cout']=xq
|
||||
duiji['color']='rgba(255,0,0,0.45)' #红色
|
||||
if float(duiji['price'])>0:
|
||||
djcout+=1
|
||||
else :
|
||||
xq=0
|
||||
return djcout
|
||||
|
||||
def back_data(df):
|
||||
# 创建新的DataFrame并填充需要的列
|
||||
new_df = pd.DataFrame()
|
||||
new_df['datetime'] = pd.to_datetime(df['datetime'], format='%Y/%m/%d %H:%M')
|
||||
new_df['close'] = df['close']
|
||||
new_df['open'] = df['open']
|
||||
new_df['high'] = df['high']
|
||||
new_df['low'] = df['low']
|
||||
new_df['volume'] = df['volume']
|
||||
new_df['sig'] = df['dj']
|
||||
new_df['symbol'] = df['symbol']
|
||||
new_df['delta'] = df['delta']
|
||||
new_df.to_csv(f'./rb888_rs_2022_back_ofdata_dj.csv',index=False)
|
||||
#new_df.to_csv(f'{sym}back_ofdata_dj.csv',index=False)
|
||||
|
||||
if __name__ == "__main__":
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
data=pd.read_csv('D:/data_transfer/data_rs_merged/上期所/rb888/rb888_rs_2022.csv',encoding='GBK',parse_dates=['datetime']) # ['业务日期','最后修改时间']
|
||||
print(data)
|
||||
tick,bar=dataload(data)
|
||||
ofdata = orderflow_df_new(tick,bar)
|
||||
print(ofdata)
|
||||
#保存orderflow数据
|
||||
folder_path = 'D:/of_data/tick生成的OF数据/data_rs_merged/上期所/rb888/'
|
||||
if not os.path.exists(folder_path):
|
||||
# os.mkdir(folder_path)
|
||||
os.makedirs(folder_path)
|
||||
# 获取当前工作目录
|
||||
current_directory = os.getcwd()
|
||||
print("当前工作目录:", current_directory)
|
||||
# 设置新的工作目录
|
||||
os.chdir(folder_path)
|
||||
# 验证新的工作目录
|
||||
updated_directory = os.getcwd()
|
||||
print("已更改为新的工作目录:", updated_directory)
|
||||
|
||||
|
||||
ofdata.to_csv('./rb888_rs_2022_ofdata_dj.csv')
|
||||
#保存回测数据
|
||||
back_data(ofdata)
|
||||
print('done')
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,226 @@
|
||||
datetime,close,open,high,low,volume,sig,symbol,delta
|
||||
2023-01-03 09:01:00,4070.0,4090.0,4090.0,4056.0,55742.0,0,rb2305,-12329.0
|
||||
2023-01-03 09:02:00,4056.0,4068.0,4069.0,4054.0,37763.0,0,rb2305,3143.0
|
||||
2023-01-03 09:03:00,4052.0,4055.0,4056.0,4046.0,35473.0,0,rb2305,-1952.0
|
||||
2023-01-03 09:04:00,4037.0,4051.0,4051.0,4033.0,46025.0,0,rb2305,89.0
|
||||
2023-01-03 09:05:00,4029.0,4037.0,4037.0,4028.0,39521.0,0,rb2305,-4223.0
|
||||
2023-01-03 09:06:00,4033.0,4029.0,4035.0,4024.0,35130.0,0,rb2305,9520.0
|
||||
2023-01-03 09:07:00,4040.0,4033.0,4042.0,4029.0,23920.0,0,rb2305,4720.0
|
||||
2023-01-03 09:08:00,4042.0,4041.0,4044.0,4037.0,18135.0,0,rb2305,1739.0
|
||||
2023-01-03 09:09:00,4042.0,4041.0,4046.0,4040.0,19528.0,0,rb2305,-86.0
|
||||
2023-01-03 09:10:00,4035.0,4042.0,4043.0,4035.0,13389.0,0,rb2305,-1531.0
|
||||
2023-01-03 09:11:00,4029.0,4034.0,4036.0,4028.0,20563.0,0,rb2305,-2435.0
|
||||
2023-01-03 09:12:00,4031.0,4029.0,4033.0,4029.0,16455.0,0,rb2305,6633.0
|
||||
2023-01-03 09:13:00,4030.0,4030.0,4034.0,4028.0,13479.0,0,rb2305,4027.0
|
||||
2023-01-03 09:14:00,4030.0,4030.0,4032.0,4028.0,17070.0,0,rb2305,-1711.0
|
||||
2023-01-03 09:15:00,4028.0,4030.0,4033.0,4028.0,12241.0,0,rb2305,2226.0
|
||||
2023-01-03 09:16:00,4028.0,4027.0,4031.0,4027.0,11094.0,0,rb2305,-544.0
|
||||
2023-01-03 09:17:00,4020.0,4029.0,4029.0,4019.0,23338.0,-1,rb2305,-5895.0
|
||||
2023-01-03 09:18:00,4018.0,4020.0,4024.0,4018.0,15721.0,0,rb2305,-302.0
|
||||
2023-01-03 09:19:00,4019.0,4018.0,4022.0,4017.0,10202.0,0,rb2305,1162.0
|
||||
2023-01-03 09:20:00,4022.0,4019.0,4022.0,4019.0,9270.0,1,rb2305,4734.0
|
||||
2023-01-03 09:21:00,4019.0,4020.0,4025.0,4018.0,13402.0,0,rb2305,2638.0
|
||||
2023-01-03 09:22:00,4023.0,4018.0,4024.0,4018.0,8214.0,0,rb2305,2843.0
|
||||
2023-01-03 09:23:00,4023.0,4023.0,4025.0,4022.0,9371.0,0,rb2305,3814.0
|
||||
2023-01-03 09:24:00,4023.0,4023.0,4024.0,4019.0,8897.0,0,rb2305,-1819.0
|
||||
2023-01-03 09:25:00,4022.0,4022.0,4024.0,4021.0,7895.0,0,rb2305,-162.0
|
||||
2023-01-03 09:26:00,4019.0,4022.0,4023.0,4016.0,10157.0,0,rb2305,-137.0
|
||||
2023-01-03 09:27:00,4025.0,4018.0,4026.0,4017.0,10624.0,0,rb2305,5036.0
|
||||
2023-01-03 09:28:00,4028.0,4025.0,4029.0,4023.0,10447.0,2,rb2305,2908.0
|
||||
2023-01-03 09:29:00,4030.0,4028.0,4032.0,4025.0,13354.0,0,rb2305,-1638.0
|
||||
2023-01-03 09:30:00,4036.0,4030.0,4038.0,4030.0,16303.0,0,rb2305,1827.0
|
||||
2023-01-03 09:31:00,4044.0,4037.0,4046.0,4035.0,24117.0,0,rb2305,-2499.0
|
||||
2023-01-03 09:32:00,4042.0,4043.0,4045.0,4041.0,8941.0,0,rb2305,-1775.0
|
||||
2023-01-03 09:33:00,4048.0,4042.0,4049.0,4042.0,12987.0,0,rb2305,1611.0
|
||||
2023-01-03 09:34:00,4047.0,4048.0,4049.0,4044.0,7839.0,0,rb2305,-283.0
|
||||
2023-01-03 09:35:00,4046.0,4046.0,4049.0,4044.0,8124.0,0,rb2305,-2421.0
|
||||
2023-01-03 09:36:00,4043.0,4046.0,4047.0,4042.0,7150.0,0,rb2305,-1262.0
|
||||
2023-01-03 09:37:00,4040.0,4042.0,4043.0,4039.0,6684.0,0,rb2305,-2299.0
|
||||
2023-01-03 09:38:00,4043.0,4041.0,4044.0,4040.0,3798.0,0,rb2305,362.0
|
||||
2023-01-03 09:39:00,4040.0,4043.0,4045.0,4038.0,7079.0,0,rb2305,-1865.0
|
||||
2023-01-03 09:40:00,4042.0,4039.0,4043.0,4038.0,3672.0,0,rb2305,979.0
|
||||
2023-01-03 09:41:00,4042.0,4042.0,4044.0,4040.0,5490.0,0,rb2305,1949.0
|
||||
2023-01-03 09:42:00,4042.0,4042.0,4044.0,4040.0,3555.0,0,rb2305,312.0
|
||||
2023-01-03 09:43:00,4045.0,4042.0,4045.0,4039.0,3854.0,0,rb2305,-1107.0
|
||||
2023-01-03 09:44:00,4042.0,4044.0,4047.0,4041.0,3984.0,0,rb2305,1618.0
|
||||
2023-01-03 09:45:00,4043.0,4041.0,4044.0,4041.0,2361.0,0,rb2305,-284.0
|
||||
2023-01-03 09:46:00,4045.0,4043.0,4047.0,4041.0,3712.0,0,rb2305,-81.0
|
||||
2023-01-03 09:47:00,4040.0,4045.0,4045.0,4040.0,2886.0,0,rb2305,-148.0
|
||||
2023-01-03 09:48:00,4035.0,4040.0,4041.0,4033.0,10250.0,-2,rb2305,-4437.0
|
||||
2023-01-03 09:49:00,4036.0,4034.0,4037.0,4033.0,3654.0,0,rb2305,6.0
|
||||
2023-01-03 09:50:00,4035.0,4035.0,4037.0,4034.0,3020.0,0,rb2305,118.0
|
||||
2023-01-03 09:51:00,4038.0,4036.0,4039.0,4036.0,3751.0,0,rb2305,1299.0
|
||||
2023-01-03 09:52:00,4039.0,4038.0,4041.0,4037.0,2804.0,0,rb2305,954.0
|
||||
2023-01-03 09:53:00,4039.0,4039.0,4040.0,4038.0,1046.0,0,rb2305,48.0
|
||||
2023-01-03 09:54:00,4037.0,4038.0,4040.0,4037.0,1251.0,0,rb2305,-119.0
|
||||
2023-01-03 09:55:00,4040.0,4037.0,4041.0,4037.0,2095.0,0,rb2305,289.0
|
||||
2023-01-03 09:56:00,4040.0,4040.0,4042.0,4040.0,1979.0,0,rb2305,379.0
|
||||
2023-01-03 09:57:00,4039.0,4041.0,4041.0,4037.0,2022.0,0,rb2305,-813.0
|
||||
2023-01-03 09:58:00,4042.0,4039.0,4043.0,4039.0,2282.0,0,rb2305,792.0
|
||||
2023-01-03 09:59:00,4040.0,4041.0,4042.0,4040.0,1716.0,0,rb2305,-446.0
|
||||
2023-01-03 10:00:00,4037.0,4040.0,4042.0,4036.0,4221.0,0,rb2305,-800.0
|
||||
2023-01-03 10:01:00,4042.0,4037.0,4042.0,4037.0,2613.0,0,rb2305,-327.0
|
||||
2023-01-03 10:02:00,4047.0,4042.0,4047.0,4041.0,6388.0,0,rb2305,1716.0
|
||||
2023-01-03 10:03:00,4049.0,4047.0,4049.0,4046.0,4646.0,0,rb2305,950.0
|
||||
2023-01-03 10:04:00,4048.0,4048.0,4049.0,4047.0,3146.0,0,rb2305,-768.0
|
||||
2023-01-03 10:05:00,4049.0,4048.0,4050.0,4047.0,5110.0,0,rb2305,2163.0
|
||||
2023-01-03 10:06:00,4049.0,4049.0,4050.0,4048.0,5620.0,0,rb2305,1040.0
|
||||
2023-01-03 10:07:00,4050.0,4049.0,4051.0,4048.0,3200.0,0,rb2305,683.0
|
||||
2023-01-03 10:08:00,4053.0,4050.0,4054.0,4050.0,7732.0,0,rb2305,1492.0
|
||||
2023-01-03 10:09:00,4051.0,4054.0,4056.0,4051.0,8622.0,0,rb2305,-1216.0
|
||||
2023-01-03 10:10:00,4050.0,4052.0,4053.0,4049.0,3967.0,0,rb2305,77.0
|
||||
2023-01-03 10:11:00,4042.0,4051.0,4051.0,4040.0,12156.0,0,rb2305,-1578.0
|
||||
2023-01-03 10:12:00,4040.0,4042.0,4043.0,4040.0,5360.0,0,rb2305,-1458.0
|
||||
2023-01-03 10:13:00,4042.0,4041.0,4042.0,4040.0,4357.0,0,rb2305,705.0
|
||||
2023-01-03 10:14:00,4044.0,4042.0,4044.0,4041.0,3225.0,0,rb2305,1539.0
|
||||
2023-01-03 10:15:00,4044.0,4044.0,4045.0,4043.0,1839.0,0,rb2305,1147.0
|
||||
2023-01-03 10:31:00,4051.0,4051.0,4053.0,4049.0,11318.0,0,rb2305,1525.0
|
||||
2023-01-03 10:32:00,4050.0,4051.0,4052.0,4049.0,2903.0,0,rb2305,-480.0
|
||||
2023-01-03 10:33:00,4048.0,4051.0,4052.0,4048.0,2751.0,0,rb2305,-1241.0
|
||||
2023-01-03 10:34:00,4051.0,4048.0,4052.0,4048.0,3113.0,0,rb2305,799.0
|
||||
2023-01-03 10:35:00,4050.0,4052.0,4053.0,4050.0,2107.0,0,rb2305,334.0
|
||||
2023-01-03 10:36:00,4050.0,4051.0,4052.0,4048.0,2850.0,0,rb2305,594.0
|
||||
2023-01-03 10:37:00,4049.0,4050.0,4050.0,4048.0,2133.0,0,rb2305,-82.0
|
||||
2023-01-03 10:38:00,4052.0,4049.0,4053.0,4048.0,2113.0,0,rb2305,977.0
|
||||
2023-01-03 10:39:00,4047.0,4052.0,4052.0,4047.0,1595.0,0,rb2305,-286.0
|
||||
2023-01-03 10:40:00,4049.0,4046.0,4050.0,4046.0,1699.0,0,rb2305,271.0
|
||||
2023-01-03 10:41:00,4048.0,4050.0,4050.0,4047.0,1397.0,0,rb2305,-243.0
|
||||
2023-01-03 10:42:00,4049.0,4048.0,4051.0,4048.0,3077.0,0,rb2305,854.0
|
||||
2023-01-03 10:43:00,4046.0,4049.0,4049.0,4045.0,3601.0,0,rb2305,-853.0
|
||||
2023-01-03 10:44:00,4046.0,4046.0,4048.0,4044.0,2586.0,0,rb2305,-1212.0
|
||||
2023-01-03 10:45:00,4046.0,4046.0,4048.0,4044.0,1653.0,0,rb2305,239.0
|
||||
2023-01-03 10:46:00,4044.0,4046.0,4046.0,4042.0,3142.0,0,rb2305,-962.0
|
||||
2023-01-03 10:47:00,4042.0,4043.0,4044.0,4041.0,4860.0,0,rb2305,-2225.0
|
||||
2023-01-03 10:48:00,4042.0,4041.0,4043.0,4040.0,2140.0,0,rb2305,138.0
|
||||
2023-01-03 10:49:00,4042.0,4041.0,4043.0,4040.0,4683.0,0,rb2305,-351.0
|
||||
2023-01-03 10:50:00,4041.0,4042.0,4042.0,4038.0,2994.0,0,rb2305,1046.0
|
||||
2023-01-03 10:51:00,4041.0,4041.0,4043.0,4040.0,3100.0,0,rb2305,1524.0
|
||||
2023-01-03 10:52:00,4042.0,4042.0,4044.0,4041.0,2195.0,0,rb2305,-203.0
|
||||
2023-01-03 10:53:00,4041.0,4042.0,4043.0,4041.0,1310.0,0,rb2305,120.0
|
||||
2023-01-03 10:54:00,4040.0,4041.0,4042.0,4039.0,1576.0,0,rb2305,-620.0
|
||||
2023-01-03 10:55:00,4039.0,4041.0,4041.0,4039.0,1123.0,0,rb2305,205.0
|
||||
2023-01-03 10:56:00,4041.0,4039.0,4041.0,4039.0,1125.0,0,rb2305,381.0
|
||||
2023-01-03 10:57:00,4042.0,4041.0,4042.0,4041.0,1654.0,0,rb2305,184.0
|
||||
2023-01-03 10:58:00,4043.0,4041.0,4044.0,4041.0,1824.0,0,rb2305,326.0
|
||||
2023-01-03 10:59:00,4040.0,4043.0,4043.0,4039.0,1451.0,0,rb2305,-405.0
|
||||
2023-01-03 11:00:00,4043.0,4040.0,4044.0,4040.0,2698.0,0,rb2305,-14.0
|
||||
2023-01-03 11:01:00,4041.0,4042.0,4044.0,4041.0,1899.0,0,rb2305,-385.0
|
||||
2023-01-03 11:02:00,4038.0,4041.0,4041.0,4037.0,5970.0,-1,rb2305,-2316.0
|
||||
2023-01-03 11:03:00,4038.0,4039.0,4040.0,4037.0,1485.0,0,rb2305,218.0
|
||||
2023-01-03 11:04:00,4041.0,4039.0,4041.0,4038.0,1802.0,0,rb2305,616.0
|
||||
2023-01-03 11:05:00,4043.0,4041.0,4044.0,4040.0,1429.0,0,rb2305,543.0
|
||||
2023-01-03 11:06:00,4046.0,4043.0,4048.0,4043.0,4905.0,1,rb2305,784.0
|
||||
2023-01-03 11:07:00,4045.0,4046.0,4048.0,4043.0,3025.0,0,rb2305,-58.0
|
||||
2023-01-03 11:08:00,4044.0,4044.0,4045.0,4043.0,1120.0,0,rb2305,28.0
|
||||
2023-01-03 11:09:00,4044.0,4045.0,4045.0,4043.0,710.0,0,rb2305,108.0
|
||||
2023-01-03 11:10:00,4042.0,4044.0,4045.0,4042.0,1090.0,0,rb2305,-86.0
|
||||
2023-01-03 11:11:00,4042.0,4042.0,4044.0,4040.0,2735.0,0,rb2305,-737.0
|
||||
2023-01-03 11:12:00,4040.0,4042.0,4044.0,4040.0,1344.0,0,rb2305,-404.0
|
||||
2023-01-03 11:13:00,4045.0,4040.0,4046.0,4040.0,1463.0,0,rb2305,471.0
|
||||
2023-01-03 11:14:00,4045.0,4045.0,4047.0,4044.0,1437.0,0,rb2305,115.0
|
||||
2023-01-03 11:15:00,4044.0,4045.0,4047.0,4044.0,2209.0,0,rb2305,-289.0
|
||||
2023-01-03 11:16:00,4042.0,4044.0,4048.0,4042.0,2179.0,0,rb2305,145.0
|
||||
2023-01-03 11:17:00,4042.0,4042.0,4044.0,4042.0,894.0,0,rb2305,-292.0
|
||||
2023-01-03 11:18:00,4040.0,4042.0,4043.0,4040.0,1246.0,0,rb2305,-927.0
|
||||
2023-01-03 11:19:00,4041.0,4041.0,4042.0,4040.0,1361.0,0,rb2305,-303.0
|
||||
2023-01-03 11:20:00,4041.0,4041.0,4043.0,4040.0,2020.0,0,rb2305,522.0
|
||||
2023-01-03 11:21:00,4043.0,4041.0,4044.0,4041.0,3003.0,0,rb2305,-81.0
|
||||
2023-01-03 11:22:00,4042.0,4043.0,4044.0,4041.0,695.0,0,rb2305,-103.0
|
||||
2023-01-03 11:23:00,4047.0,4042.0,4048.0,4042.0,3435.0,0,rb2305,1775.0
|
||||
2023-01-03 11:24:00,4049.0,4046.0,4051.0,4046.0,4359.0,0,rb2305,1325.0
|
||||
2023-01-03 11:25:00,4047.0,4048.0,4049.0,4047.0,1313.0,0,rb2305,-215.0
|
||||
2023-01-03 11:26:00,4048.0,4048.0,4049.0,4045.0,2788.0,0,rb2305,-536.0
|
||||
2023-01-03 11:27:00,4047.0,4048.0,4049.0,4046.0,1846.0,0,rb2305,-204.0
|
||||
2023-01-03 11:28:00,4047.0,4047.0,4048.0,4045.0,1724.0,0,rb2305,-268.0
|
||||
2023-01-03 11:29:00,4050.0,4046.0,4051.0,4046.0,2648.0,0,rb2305,555.0
|
||||
2023-01-03 11:30:00,4051.0,4051.0,4054.0,4050.0,5436.0,0,rb2305,-1344.0
|
||||
2023-01-03 13:31:00,4053.0,4055.0,4056.0,4049.0,16041.0,0,rb2305,2817.0
|
||||
2023-01-03 13:32:00,4050.0,4052.0,4054.0,4049.0,4575.0,0,rb2305,197.0
|
||||
2023-01-03 13:33:00,4051.0,4050.0,4054.0,4050.0,3222.0,0,rb2305,408.0
|
||||
2023-01-03 13:34:00,4050.0,4051.0,4051.0,4048.0,3830.0,0,rb2305,-858.0
|
||||
2023-01-03 13:35:00,4047.0,4050.0,4050.0,4046.0,1934.0,0,rb2305,310.0
|
||||
2023-01-03 13:36:00,4046.0,4047.0,4048.0,4045.0,4141.0,0,rb2305,121.0
|
||||
2023-01-03 13:37:00,4050.0,4047.0,4052.0,4047.0,3057.0,1,rb2305,1587.0
|
||||
2023-01-03 13:38:00,4054.0,4051.0,4054.0,4051.0,3090.0,0,rb2305,1122.0
|
||||
2023-01-03 13:39:00,4055.0,4054.0,4056.0,4052.0,4301.0,0,rb2305,653.0
|
||||
2023-01-03 13:40:00,4059.0,4055.0,4060.0,4055.0,8489.0,1,rb2305,3308.0
|
||||
2023-01-03 13:41:00,4062.0,4059.0,4063.0,4057.0,10590.0,0,rb2305,4201.0
|
||||
2023-01-03 13:42:00,4064.0,4062.0,4064.0,4062.0,4483.0,0,rb2305,-156.0
|
||||
2023-01-03 13:43:00,4062.0,4064.0,4065.0,4061.0,3226.0,0,rb2305,-388.0
|
||||
2023-01-03 13:44:00,4062.0,4062.0,4063.0,4061.0,2446.0,0,rb2305,-77.0
|
||||
2023-01-03 13:45:00,4064.0,4063.0,4064.0,4062.0,3071.0,0,rb2305,209.0
|
||||
2023-01-03 13:46:00,4060.0,4064.0,4065.0,4059.0,4674.0,0,rb2305,-1746.0
|
||||
2023-01-03 13:47:00,4060.0,4060.0,4061.0,4058.0,1916.0,0,rb2305,-526.0
|
||||
2023-01-03 13:48:00,4062.0,4059.0,4062.0,4059.0,2074.0,0,rb2305,-448.0
|
||||
2023-01-03 13:49:00,4062.0,4062.0,4063.0,4061.0,2138.0,0,rb2305,274.0
|
||||
2023-01-03 13:50:00,4063.0,4063.0,4064.0,4062.0,2680.0,0,rb2305,-526.0
|
||||
2023-01-03 13:51:00,4062.0,4064.0,4064.0,4061.0,2280.0,0,rb2305,-766.0
|
||||
2023-01-03 13:52:00,4061.0,4063.0,4063.0,4061.0,1909.0,0,rb2305,-477.0
|
||||
2023-01-03 13:53:00,4060.0,4061.0,4062.0,4060.0,2534.0,0,rb2305,-1372.0
|
||||
2023-01-03 13:54:00,4059.0,4061.0,4061.0,4058.0,2392.0,0,rb2305,-566.0
|
||||
2023-01-03 13:55:00,4060.0,4059.0,4060.0,4058.0,2118.0,0,rb2305,-58.0
|
||||
2023-01-03 13:56:00,4060.0,4059.0,4061.0,4059.0,1244.0,0,rb2305,199.0
|
||||
2023-01-03 13:57:00,4058.0,4060.0,4061.0,4057.0,3063.0,-1,rb2305,-2005.0
|
||||
2023-01-03 13:58:00,4058.0,4059.0,4060.0,4057.0,1386.0,0,rb2305,-142.0
|
||||
2023-01-03 13:59:00,4060.0,4058.0,4060.0,4058.0,1593.0,0,rb2305,-527.0
|
||||
2023-01-03 14:00:00,4058.0,4060.0,4060.0,4057.0,1626.0,0,rb2305,-70.0
|
||||
2023-01-03 14:01:00,4060.0,4058.0,4060.0,4058.0,1907.0,0,rb2305,252.0
|
||||
2023-01-03 14:02:00,4059.0,4060.0,4063.0,4058.0,2686.0,0,rb2305,432.0
|
||||
2023-01-03 14:03:00,4058.0,4059.0,4060.0,4058.0,1019.0,0,rb2305,430.0
|
||||
2023-01-03 14:04:00,4061.0,4059.0,4061.0,4058.0,1000.0,0,rb2305,254.0
|
||||
2023-01-03 14:05:00,4063.0,4061.0,4063.0,4061.0,2593.0,0,rb2305,201.0
|
||||
2023-01-03 14:06:00,4061.0,4063.0,4063.0,4060.0,1076.0,0,rb2305,-102.0
|
||||
2023-01-03 14:07:00,4057.0,4060.0,4061.0,4057.0,1662.0,0,rb2305,-664.0
|
||||
2023-01-03 14:08:00,4059.0,4058.0,4060.0,4056.0,2024.0,0,rb2305,-970.0
|
||||
2023-01-03 14:09:00,4060.0,4060.0,4061.0,4059.0,1140.0,0,rb2305,-450.0
|
||||
2023-01-03 14:10:00,4061.0,4060.0,4061.0,4059.0,1021.0,0,rb2305,-197.0
|
||||
2023-01-03 14:11:00,4063.0,4061.0,4063.0,4060.0,1537.0,0,rb2305,113.0
|
||||
2023-01-03 14:12:00,4062.0,4063.0,4063.0,4061.0,798.0,0,rb2305,44.0
|
||||
2023-01-03 14:13:00,4063.0,4061.0,4063.0,4060.0,1974.0,0,rb2305,346.0
|
||||
2023-01-03 14:14:00,4065.0,4062.0,4068.0,4062.0,10552.0,2,rb2305,5824.0
|
||||
2023-01-03 14:15:00,4064.0,4066.0,4067.0,4063.0,3494.0,0,rb2305,-1062.0
|
||||
2023-01-03 14:16:00,4066.0,4066.0,4067.0,4065.0,1856.0,0,rb2305,588.0
|
||||
2023-01-03 14:17:00,4064.0,4067.0,4067.0,4064.0,1989.0,0,rb2305,323.0
|
||||
2023-01-03 14:18:00,4066.0,4064.0,4067.0,4064.0,1582.0,0,rb2305,90.0
|
||||
2023-01-03 14:19:00,4067.0,4067.0,4068.0,4066.0,1890.0,0,rb2305,52.0
|
||||
2023-01-03 14:20:00,4069.0,4067.0,4071.0,4067.0,8506.0,0,rb2305,3374.0
|
||||
2023-01-03 14:21:00,4069.0,4069.0,4070.0,4068.0,2515.0,0,rb2305,617.0
|
||||
2023-01-03 14:22:00,4066.0,4069.0,4070.0,4066.0,2806.0,0,rb2305,-1568.0
|
||||
2023-01-03 14:23:00,4066.0,4067.0,4068.0,4065.0,2845.0,0,rb2305,131.0
|
||||
2023-01-03 14:24:00,4068.0,4066.0,4068.0,4066.0,1107.0,0,rb2305,81.0
|
||||
2023-01-03 14:25:00,4069.0,4068.0,4070.0,4066.0,2229.0,0,rb2305,313.0
|
||||
2023-01-03 14:26:00,4069.0,4069.0,4071.0,4068.0,2890.0,0,rb2305,114.0
|
||||
2023-01-03 14:27:00,4070.0,4070.0,4071.0,4068.0,5475.0,0,rb2305,-813.0
|
||||
2023-01-03 14:28:00,4073.0,4070.0,4074.0,4069.0,4610.0,0,rb2305,-73.0
|
||||
2023-01-03 14:29:00,4073.0,4072.0,4074.0,4072.0,2399.0,0,rb2305,-649.0
|
||||
2023-01-03 14:30:00,4072.0,4073.0,4073.0,4071.0,1854.0,0,rb2305,-576.0
|
||||
2023-01-03 14:31:00,4069.0,4072.0,4072.0,4069.0,3070.0,0,rb2305,-928.0
|
||||
2023-01-03 14:32:00,4063.0,4070.0,4070.0,4063.0,5785.0,-2,rb2305,-2688.0
|
||||
2023-01-03 14:33:00,4062.0,4063.0,4064.0,4060.0,6702.0,0,rb2305,-1393.0
|
||||
2023-01-03 14:34:00,4065.0,4062.0,4065.0,4062.0,1857.0,0,rb2305,987.0
|
||||
2023-01-03 14:35:00,4064.0,4065.0,4066.0,4064.0,1958.0,0,rb2305,132.0
|
||||
2023-01-03 14:36:00,4066.0,4064.0,4066.0,4062.0,2530.0,0,rb2305,-220.0
|
||||
2023-01-03 14:37:00,4062.0,4065.0,4066.0,4062.0,1994.0,0,rb2305,-666.0
|
||||
2023-01-03 14:38:00,4063.0,4063.0,4064.0,4062.0,1849.0,0,rb2305,-345.0
|
||||
2023-01-03 14:39:00,4063.0,4063.0,4065.0,4062.0,1307.0,0,rb2305,-271.0
|
||||
2023-01-03 14:40:00,4061.0,4062.0,4063.0,4061.0,1785.0,0,rb2305,164.0
|
||||
2023-01-03 14:41:00,4062.0,4061.0,4063.0,4061.0,1324.0,0,rb2305,238.0
|
||||
2023-01-03 14:42:00,4065.0,4062.0,4066.0,4061.0,1905.0,0,rb2305,500.0
|
||||
2023-01-03 14:43:00,4064.0,4065.0,4066.0,4064.0,1131.0,0,rb2305,-63.0
|
||||
2023-01-03 14:44:00,4062.0,4065.0,4066.0,4061.0,1773.0,0,rb2305,-427.0
|
||||
2023-01-03 14:45:00,4063.0,4062.0,4064.0,4062.0,700.0,0,rb2305,84.0
|
||||
2023-01-03 14:46:00,4061.0,4064.0,4065.0,4060.0,3722.0,0,rb2305,-1686.0
|
||||
2023-01-03 14:47:00,4058.0,4061.0,4061.0,4057.0,6062.0,0,rb2305,-1636.0
|
||||
2023-01-03 14:48:00,4057.0,4057.0,4058.0,4056.0,3102.0,0,rb2305,-846.0
|
||||
2023-01-03 14:49:00,4059.0,4057.0,4060.0,4056.0,2569.0,0,rb2305,154.0
|
||||
2023-01-03 14:50:00,4058.0,4058.0,4060.0,4057.0,1609.0,0,rb2305,-199.0
|
||||
2023-01-03 14:51:00,4057.0,4058.0,4060.0,4057.0,2286.0,0,rb2305,-441.0
|
||||
2023-01-03 14:52:00,4059.0,4057.0,4060.0,4057.0,2336.0,0,rb2305,-461.0
|
||||
2023-01-03 14:53:00,4059.0,4060.0,4060.0,4058.0,3043.0,0,rb2305,-843.0
|
||||
2023-01-03 14:54:00,4058.0,4059.0,4060.0,4057.0,1460.0,0,rb2305,-30.0
|
||||
2023-01-03 14:55:00,4058.0,4058.0,4059.0,4057.0,2081.0,0,rb2305,-225.0
|
||||
2023-01-03 14:56:00,4057.0,4058.0,4060.0,4057.0,3029.0,0,rb2305,-544.0
|
||||
2023-01-03 14:57:00,4059.0,4058.0,4060.0,4057.0,4039.0,0,rb2305,-1145.0
|
||||
2023-01-03 14:58:00,4061.0,4059.0,4061.0,4058.0,4940.0,0,rb2305,157.0
|
||||
2023-01-03 14:59:00,4063.0,4060.0,4064.0,4060.0,6425.0,0,rb2305,930.0
|
||||
2023-01-03 15:00:00,4063.0,4063.0,4064.0,4061.0,6581.0,0,rb2305,-2157.0
|
||||
|
@@ -0,0 +1,226 @@
|
||||
,price,Ask,Bid,symbol,datetime,delta,close,open,high,low,volume,dj
|
||||
0,"[4056.0, 4057.0, 4058.0, 4059.0, 4060.0, 4061.0, 4062.0, 4063.0, 4064.0, 4065.0, 4066.0, 4067.0, 4068.0, 4069.0, 4070.0, 4071.0, 4072.0, 4073.0, 4074.0, 4078.0, 4081.0, 4090.0]","[0, 0, 4574.0, 0, 1946.0, 330.0, 0, 467.0, 1910.0, 1881.0, 492.0, 504.0, 1094.0, 511.0, 3759.0, 2243.0, 1339.0, 446.0, 127.0, 0, 0, 0]","[2219.0, 1212.0, 0, 1095.0, 953.0, 812.0, 1156.0, 1702.0, 1193.0, 642.0, 2150.0, 1119.0, 985.0, 2139.0, 1927.0, 2644.0, 2720.0, 4267.0, 0, 1662.0, 1519.0, 1836.0]",rb2305,2023-01-03 09:01:00,-12329.0,4070.0,4090.0,4090.0,4056.0,55742.0,0
|
||||
1,"[4054.0, 4055.0, 4056.0, 4057.0, 4058.0, 4059.0, 4060.0, 4061.0, 4062.0, 4063.0, 4064.0, 4065.0, 4066.0, 4067.0, 4068.0, 4069.0]","[507.0, 0, 2896.0, 4249.0, 4348.0, 2734.0, 1108.0, 0, 507.0, 662.0, 286.0, 1097.0, 623.0, 752.0, 0, 231.0]","[1990.0, 246.0, 3662.0, 2049.0, 2456.0, 527.0, 1056.0, 323.0, 1981.0, 606.0, 259.0, 521.0, 0, 723.0, 458.0, 0]",rb2305,2023-01-03 09:02:00,3143.0,4056.0,4068.0,4069.0,4054.0,37763.0,0
|
||||
2,"[4046.0, 4047.0, 4048.0, 4049.0, 4050.0, 4051.0, 4052.0, 4053.0, 4054.0, 4055.0, 4056.0]","[0, 2179.0, 353.0, 1352.0, 1889.0, 388.0, 3919.0, 1451.0, 1826.0, 1780.0, 1221.0]","[1131.0, 338.0, 1222.0, 2522.0, 3443.0, 1898.0, 3251.0, 1232.0, 684.0, 2589.0, 0]",rb2305,2023-01-03 09:03:00,-1952.0,4052.0,4055.0,4056.0,4046.0,35473.0,0
|
||||
3,"[4033.0, 4034.0, 4035.0, 4036.0, 4037.0, 4038.0, 4039.0, 4040.0, 4041.0, 4042.0, 4043.0, 4044.0, 4045.0, 4046.0, 4047.0, 4048.0, 4049.0, 4050.0, 4051.0]","[0, 749.0, 2253.0, 4202.0, 1733.0, 2596.0, 505.0, 1185.0, 129.0, 490.0, 1229.0, 373.0, 2846.0, 2451.0, 1013.0, 702.0, 145.0, 0, 0]","[300.0, 1487.0, 2859.0, 1452.0, 722.0, 0, 1610.0, 1239.0, 1336.0, 0, 302.0, 401.0, 1572.0, 2695.0, 1579.0, 745.0, 0, 3089.0, 1124.0]",rb2305,2023-01-03 09:04:00,89.0,4037.0,4051.0,4051.0,4033.0,46025.0,0
|
||||
4,"[4028.0, 4029.0, 4030.0, 4031.0, 4032.0, 4033.0, 4034.0, 4035.0, 4036.0, 4037.0]","[0, 1539.0, 930.0, 7269.0, 1853.0, 629.0, 2545.0, 1754.0, 243.0, 461.0]","[345.0, 2979.0, 4554.0, 3548.0, 2134.0, 2465.0, 3241.0, 1138.0, 1042.0, 0]",rb2305,2023-01-03 09:05:00,-4223.0,4029.0,4037.0,4037.0,4028.0,39521.0,0
|
||||
5,"[4024.0, 4025.0, 4026.0, 4027.0, 4028.0, 4029.0, 4030.0, 4031.0, 4032.0, 4033.0, 4034.0, 4035.0]","[1088.0, 1058.0, 4856.0, 518.0, 468.0, 2328.0, 1249.0, 2934.0, 1260.0, 2482.0, 3144.0, 821.0]","[2659.0, 928.0, 745.0, 533.0, 668.0, 2919.0, 537.0, 839.0, 599.0, 1639.0, 620.0, 0]",rb2305,2023-01-03 09:06:00,9520.0,4033.0,4029.0,4035.0,4024.0,35130.0,0
|
||||
6,"[4029.0, 4030.0, 4031.0, 4032.0, 4033.0, 4034.0, 4035.0, 4036.0, 4037.0, 4038.0, 4039.0, 4040.0, 4041.0, 4042.0]","[424.0, 274.0, 1083.0, 496.0, 217.0, 508.0, 541.0, 408.0, 1005.0, 1987.0, 588.0, 2465.0, 2722.0, 1602.0]","[316.0, 740.0, 0, 875.0, 274.0, 351.0, 108.0, 144.0, 896.0, 1723.0, 2092.0, 1034.0, 1047.0, 0]",rb2305,2023-01-03 09:07:00,4720.0,4040.0,4033.0,4042.0,4029.0,23920.0,0
|
||||
7,"[4037.0, 4038.0, 4039.0, 4040.0, 4041.0, 4042.0, 4043.0, 4044.0]","[0, 388.0, 806.0, 1077.0, 687.0, 2958.0, 2656.0, 1333.0]","[596.0, 296.0, 668.0, 1046.0, 1275.0, 2620.0, 1665.0, 0]",rb2305,2023-01-03 09:08:00,1739.0,4042.0,4041.0,4044.0,4037.0,18135.0,0
|
||||
8,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0, 4045.0, 4046.0]","[0, 420.0, 3391.0, 2666.0, 1971.0, 0, 1050.0]","[160.0, 2828.0, 3527.0, 2663.0, 340.0, 66.0, 0]",rb2305,2023-01-03 09:09:00,-86.0,4042.0,4041.0,4046.0,4040.0,19528.0,0
|
||||
9,"[4035.0, 4036.0, 4037.0, 4038.0, 4039.0, 4040.0, 4041.0, 4042.0, 4043.0]","[0, 77.0, 61.0, 570.0, 480.0, 2377.0, 1319.0, 882.0, 163.0]","[215.0, 799.0, 41.0, 571.0, 1804.0, 2051.0, 139.0, 1840.0, 0]",rb2305,2023-01-03 09:10:00,-1531.0,4035.0,4042.0,4043.0,4035.0,13389.0,0
|
||||
10,"[4028.0, 4029.0, 4030.0, 4031.0, 4032.0, 4033.0, 4034.0, 4035.0, 4036.0]","[0, 3085.0, 1881.0, 765.0, 992.0, 192.0, 318.0, 1159.0, 672.0]","[1209.0, 4291.0, 985.0, 1617.0, 0, 189.0, 1544.0, 1664.0, 0]",rb2305,2023-01-03 09:11:00,-2435.0,4029.0,4034.0,4036.0,4028.0,20563.0,0
|
||||
11,"[4029.0, 4030.0, 4031.0, 4032.0, 4033.0]","[106.0, 930.0, 3851.0, 2200.0, 4345.0]","[173.0, 1410.0, 1544.0, 1580.0, 92.0]",rb2305,2023-01-03 09:12:00,6633.0,4031.0,4029.0,4033.0,4029.0,16455.0,0
|
||||
12,"[4028.0, 4029.0, 4030.0, 4031.0, 4032.0, 4033.0, 4034.0]","[0, 416.0, 1922.0, 2289.0, 427.0, 746.0, 2873.0]","[796.0, 917.0, 1201.0, 448.0, 913.0, 371.0, 0]",rb2305,2023-01-03 09:13:00,4027.0,4030.0,4030.0,4034.0,4028.0,13479.0,0
|
||||
13,"[4028.0, 4029.0, 4030.0, 4031.0, 4032.0]","[453.0, 2276.0, 3085.0, 1534.0, 313.0]","[2559.0, 3045.0, 2642.0, 1126.0, 0]",rb2305,2023-01-03 09:14:00,-1711.0,4030.0,4030.0,4032.0,4028.0,17070.0,0
|
||||
14,"[4028.0, 4029.0, 4030.0, 4031.0, 4032.0, 4033.0]","[0, 1481.0, 870.0, 3154.0, 1392.0, 326.0]","[371.0, 1010.0, 1212.0, 2198.0, 206.0, 0]",rb2305,2023-01-03 09:15:00,2226.0,4028.0,4030.0,4033.0,4028.0,12241.0,0
|
||||
15,"[4027.0, 4028.0, 4029.0, 4030.0, 4031.0]","[0, 0, 1444.0, 3494.0, 212.0]","[1395.0, 438.0, 2810.0, 1051.0, 0]",rb2305,2023-01-03 09:16:00,-544.0,4028.0,4027.0,4031.0,4027.0,11094.0,0
|
||||
16,"[4019.0, 4020.0, 4021.0, 4022.0, 4024.0, 4025.0, 4026.0, 4027.0, 4028.0, 4029.0]","[0, 669.0, 2293.0, 2244.0, 0, 158.0, 34.0, 1023.0, 559.0, 1631.0]","[268.0, 4242.0, 2684.0, 908.0, 1931.0, 2282.0, 792.0, 839.0, 560.0, 0]",rb2305,2023-01-03 09:17:00,-5895.0,4020.0,4029.0,4029.0,4019.0,23338.0,-1
|
||||
17,"[4018.0, 4019.0, 4020.0, 4021.0, 4022.0, 4023.0, 4024.0]","[0, 1490.0, 3966.0, 387.0, 1139.0, 574.0, 79.0]","[828.0, 1176.0, 2539.0, 1808.0, 1446.0, 140.0, 0]",rb2305,2023-01-03 09:18:00,-302.0,4018.0,4020.0,4024.0,4018.0,15721.0,0
|
||||
18,"[4017.0, 4018.0, 4019.0, 4020.0, 4021.0, 4022.0]","[0, 992.0, 917.0, 3045.0, 600.0, 128.0]","[155.0, 575.0, 1813.0, 1916.0, 61.0, 0]",rb2305,2023-01-03 09:19:00,1162.0,4019.0,4018.0,4022.0,4017.0,10202.0,0
|
||||
19,"[4019.0, 4020.0, 4021.0, 4022.0]","[0, 817.0, 778.0, 5309.0]","[230.0, 194.0, 1289.0, 457.0]",rb2305,2023-01-03 09:20:00,4734.0,4022.0,4019.0,4022.0,4019.0,9270.0,1
|
||||
20,"[4018.0, 4019.0, 4020.0, 4021.0, 4022.0, 4023.0, 4024.0, 4025.0]","[0, 1673.0, 922.0, 1102.0, 489.0, 823.0, 2493.0, 485.0]","[300.0, 2194.0, 910.0, 138.0, 1335.0, 280.0, 192.0, 0]",rb2305,2023-01-03 09:21:00,2638.0,4019.0,4020.0,4025.0,4018.0,13402.0,0
|
||||
21,"[4018.0, 4019.0, 4020.0, 4021.0, 4022.0, 4023.0, 4024.0]","[345.0, 1213.0, 342.0, 391.0, 1052.0, 1344.0, 801.0]","[987.0, 350.0, 264.0, 211.0, 210.0, 623.0, 0]",rb2305,2023-01-03 09:22:00,2843.0,4023.0,4018.0,4024.0,4018.0,8214.0,0
|
||||
22,"[4022.0, 4023.0, 4024.0, 4025.0]","[279.0, 3904.0, 1843.0, 554.0]","[313.0, 2437.0, 16.0, 0]",rb2305,2023-01-03 09:23:00,3814.0,4023.0,4023.0,4025.0,4022.0,9371.0,0
|
||||
23,"[4019.0, 4020.0, 4021.0, 4022.0, 4023.0, 4024.0]","[0, 677.0, 927.0, 1563.0, 193.0, 141.0]","[1746.0, 1829.0, 1018.0, 643.0, 84.0, 0]",rb2305,2023-01-03 09:24:00,-1819.0,4023.0,4023.0,4024.0,4019.0,8897.0,0
|
||||
24,"[4021.0, 4022.0, 4023.0, 4024.0]","[0, 920.0, 2814.0, 89.0]","[481.0, 1938.0, 1566.0, 0]",rb2305,2023-01-03 09:25:00,-162.0,4022.0,4022.0,4024.0,4021.0,7895.0,0
|
||||
25,"[4016.0, 4017.0, 4018.0, 4019.0, 4020.0, 4021.0, 4022.0, 4023.0]","[0, 389.0, 895.0, 1837.0, 867.0, 615.0, 331.0, 76.0]","[94.0, 1294.0, 1065.0, 1545.0, 451.0, 698.0, 0, 0]",rb2305,2023-01-03 09:26:00,-137.0,4019.0,4022.0,4023.0,4016.0,10157.0,0
|
||||
26,"[4017.0, 4018.0, 4019.0, 4020.0, 4021.0, 4022.0, 4023.0, 4024.0, 4025.0, 4026.0]","[0, 113.0, 230.0, 634.0, 345.0, 1042.0, 935.0, 2519.0, 1147.0, 855.0]","[26.0, 207.0, 49.0, 704.0, 10.0, 664.0, 503.0, 0, 621.0, 0]",rb2305,2023-01-03 09:27:00,5036.0,4025.0,4018.0,4026.0,4017.0,10624.0,0
|
||||
27,"[4023.0, 4024.0, 4025.0, 4026.0, 4027.0, 4028.0, 4029.0]","[0, 1120.0, 962.0, 632.0, 1021.0, 694.0, 2228.0]","[248.0, 2150.0, 56.0, 251.0, 221.0, 738.0, 85.0]",rb2305,2023-01-03 09:28:00,2908.0,4028.0,4025.0,4029.0,4023.0,10447.0,2
|
||||
28,"[4025.0, 4026.0, 4027.0, 4028.0, 4029.0, 4030.0, 4031.0, 4032.0]","[0, 210.0, 1000.0, 1094.0, 1923.0, 1149.0, 385.0, 97.0]","[41.0, 517.0, 1255.0, 2642.0, 2365.0, 576.0, 100.0, 0]",rb2305,2023-01-03 09:29:00,-1638.0,4030.0,4028.0,4032.0,4025.0,13354.0,0
|
||||
29,"[4030.0, 4031.0, 4032.0, 4033.0, 4034.0, 4035.0, 4036.0, 4037.0, 4038.0]","[0, 615.0, 723.0, 1070.0, 1354.0, 1237.0, 1186.0, 1076.0, 1728.0]","[476.0, 1192.0, 33.0, 400.0, 1208.0, 616.0, 499.0, 1789.0, 949.0]",rb2305,2023-01-03 09:30:00,1827.0,4036.0,4030.0,4038.0,4030.0,16303.0,0
|
||||
30,"[4035.0, 4036.0, 4037.0, 4038.0, 4039.0, 4040.0, 4041.0, 4042.0, 4043.0, 4044.0, 4045.0, 4046.0]","[170.0, 326.0, 1343.0, 202.0, 330.0, 924.0, 790.0, 944.0, 1868.0, 1646.0, 1694.0, 480.0]","[198.0, 1110.0, 1607.0, 1973.0, 1266.0, 0, 519.0, 2448.0, 723.0, 1990.0, 1382.0, 0]",rb2305,2023-01-03 09:31:00,-2499.0,4044.0,4037.0,4046.0,4035.0,24117.0,0
|
||||
31,"[4041.0, 4042.0, 4043.0, 4044.0, 4045.0]","[0, 1651.0, 1386.0, 519.0, 27.0]","[413.0, 2423.0, 1884.0, 638.0, 0]",rb2305,2023-01-03 09:32:00,-1775.0,4042.0,4043.0,4045.0,4041.0,8941.0,0
|
||||
32,"[4042.0, 4043.0, 4044.0, 4045.0, 4046.0, 4047.0, 4048.0, 4049.0]","[0, 704.0, 1668.0, 841.0, 1207.0, 425.0, 1431.0, 1023.0]","[633.0, 622.0, 1308.0, 466.0, 149.0, 708.0, 1439.0, 363.0]",rb2305,2023-01-03 09:33:00,1611.0,4048.0,4042.0,4049.0,4042.0,12987.0,0
|
||||
33,"[4044.0, 4045.0, 4046.0, 4047.0, 4048.0, 4049.0]","[222.0, 391.0, 711.0, 951.0, 999.0, 485.0]","[644.0, 83.0, 1029.0, 1471.0, 815.0, 0]",rb2305,2023-01-03 09:34:00,-283.0,4047.0,4048.0,4049.0,4044.0,7839.0,0
|
||||
34,"[4044.0, 4045.0, 4046.0, 4047.0, 4048.0, 4049.0]","[0, 35.0, 577.0, 871.0, 825.0, 521.0]","[246.0, 549.0, 1136.0, 1555.0, 1588.0, 176.0]",rb2305,2023-01-03 09:35:00,-2421.0,4046.0,4046.0,4049.0,4044.0,8124.0,0
|
||||
35,"[4042.0, 4043.0, 4044.0, 4045.0, 4046.0, 4047.0]","[0, 839.0, 856.0, 563.0, 33.0, 633.0]","[21.0, 1460.0, 1241.0, 762.0, 517.0, 185.0]",rb2305,2023-01-03 09:36:00,-1262.0,4043.0,4046.0,4047.0,4042.0,7150.0,0
|
||||
36,"[4039.0, 4040.0, 4041.0, 4042.0, 4043.0]","[0, 358.0, 418.0, 892.0, 517.0]","[459.0, 1296.0, 1667.0, 1062.0, 0]",rb2305,2023-01-03 09:37:00,-2299.0,4040.0,4042.0,4043.0,4039.0,6684.0,0
|
||||
37,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0]","[0, 596.0, 565.0, 886.0, 33.0]","[317.0, 471.0, 750.0, 180.0, 0]",rb2305,2023-01-03 09:38:00,362.0,4043.0,4041.0,4044.0,4040.0,3798.0,0
|
||||
38,"[4038.0, 4039.0, 4040.0, 4041.0, 4042.0, 4043.0, 4044.0, 4045.0]","[0, 287.0, 120.0, 667.0, 47.0, 455.0, 432.0, 599.0]","[254.0, 369.0, 792.0, 968.0, 902.0, 253.0, 906.0, 28.0]",rb2305,2023-01-03 09:39:00,-1865.0,4040.0,4043.0,4045.0,4038.0,7079.0,0
|
||||
39,"[4038.0, 4039.0, 4040.0, 4041.0, 4042.0, 4043.0]","[0, 84.0, 735.0, 473.0, 737.0, 290.0]","[127.0, 391.0, 462.0, 99.0, 261.0, 0]",rb2305,2023-01-03 09:40:00,979.0,4042.0,4039.0,4043.0,4038.0,3672.0,0
|
||||
40,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0]","[0, 1199.0, 951.0, 770.0, 799.0]","[36.0, 1186.0, 252.0, 296.0, 0]",rb2305,2023-01-03 09:41:00,1949.0,4042.0,4042.0,4044.0,4040.0,5490.0,0
|
||||
41,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0]","[0, 351.0, 815.0, 640.0, 115.0]","[121.0, 392.0, 697.0, 399.0, 0]",rb2305,2023-01-03 09:42:00,312.0,4042.0,4042.0,4044.0,4040.0,3555.0,0
|
||||
42,"[4039.0, 4040.0, 4041.0, 4042.0, 4043.0, 4044.0, 4045.0]","[0, 341.0, 190.0, 148.0, 232.0, 312.0, 117.0]","[290.0, 586.0, 784.0, 325.0, 391.0, 71.0, 0]",rb2305,2023-01-03 09:43:00,-1107.0,4045.0,4042.0,4045.0,4039.0,3854.0,0
|
||||
43,"[4041.0, 4042.0, 4043.0, 4044.0, 4045.0, 4046.0, 4047.0]","[0, 288.0, 60.0, 70.0, 1257.0, 780.0, 346.0]","[160.0, 91.0, 72.0, 412.0, 434.0, 14.0, 0]",rb2305,2023-01-03 09:44:00,1618.0,4042.0,4044.0,4047.0,4041.0,3984.0,0
|
||||
44,"[4041.0, 4042.0, 4043.0, 4044.0]","[0, 31.0, 804.0, 199.0]","[328.0, 707.0, 283.0, 0]",rb2305,2023-01-03 09:45:00,-284.0,4043.0,4041.0,4044.0,4041.0,2361.0,0
|
||||
45,"[4041.0, 4042.0, 4043.0, 4044.0, 4045.0, 4046.0, 4047.0]","[0, 10.0, 559.0, 431.0, 217.0, 384.0, 152.0]","[219.0, 560.0, 348.0, 7.0, 259.0, 441.0, 0]",rb2305,2023-01-03 09:46:00,-81.0,4045.0,4043.0,4047.0,4041.0,3712.0,0
|
||||
46,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0, 4045.0]","[0, 737.0, 396.0, 80.0, 66.0, 85.0]","[573.0, 687.0, 108.0, 24.0, 120.0, 0]",rb2305,2023-01-03 09:47:00,-148.0,4040.0,4045.0,4045.0,4040.0,2886.0,0
|
||||
47,"[4033.0, 4034.0, 4035.0, 4036.0, 4037.0, 4038.0, 4039.0, 4040.0, 4041.0]","[0, 679.0, 1015.0, 762.0, 0, 120.0, 101.0, 40.0, 114.0]","[694.0, 928.0, 1273.0, 127.0, 2884.0, 445.0, 714.0, 203.0, 0]",rb2305,2023-01-03 09:48:00,-4437.0,4035.0,4040.0,4041.0,4033.0,10250.0,-2
|
||||
48,"[4033.0, 4034.0, 4035.0, 4036.0, 4037.0]","[0, 966.0, 347.0, 508.0, 9.0]","[1006.0, 519.0, 85.0, 214.0, 0]",rb2305,2023-01-03 09:49:00,6.0,4036.0,4034.0,4037.0,4033.0,3654.0,0
|
||||
49,"[4034.0, 4035.0, 4036.0, 4037.0]","[0, 579.0, 746.0, 244.0]","[379.0, 731.0, 341.0, 0]",rb2305,2023-01-03 09:50:00,118.0,4035.0,4035.0,4037.0,4034.0,3020.0,0
|
||||
50,"[4036.0, 4037.0, 4038.0, 4039.0]","[301.0, 1003.0, 647.0, 574.0]","[643.0, 230.0, 353.0, 0]",rb2305,2023-01-03 09:51:00,1299.0,4038.0,4036.0,4039.0,4036.0,3751.0,0
|
||||
51,"[4037.0, 4038.0, 4039.0, 4040.0, 4041.0]","[0, 211.0, 439.0, 825.0, 404.0]","[196.0, 181.0, 202.0, 346.0, 0]",rb2305,2023-01-03 09:52:00,954.0,4039.0,4038.0,4041.0,4037.0,2804.0,0
|
||||
52,"[4038.0, 4039.0, 4040.0]","[0, 238.0, 308.0]","[60.0, 438.0, 0]",rb2305,2023-01-03 09:53:00,48.0,4039.0,4039.0,4040.0,4038.0,1046.0,0
|
||||
53,"[4037.0, 4038.0, 4039.0, 4040.0]","[0, 4.0, 496.0, 66.0]","[105.0, 476.0, 104.0, 0]",rb2305,2023-01-03 09:54:00,-119.0,4037.0,4038.0,4040.0,4037.0,1251.0,0
|
||||
54,"[4037.0, 4038.0, 4039.0, 4040.0, 4041.0]","[0, 250.0, 122.0, 263.0, 555.0]","[141.0, 40.0, 205.0, 515.0, 0]",rb2305,2023-01-03 09:55:00,289.0,4040.0,4037.0,4041.0,4037.0,2095.0,0
|
||||
55,"[4040.0, 4041.0, 4042.0]","[89.0, 1063.0, 27.0]","[710.0, 90.0, 0]",rb2305,2023-01-03 09:56:00,379.0,4040.0,4040.0,4042.0,4040.0,1979.0,0
|
||||
56,"[4037.0, 4038.0, 4039.0, 4040.0, 4041.0]","[0, 153.0, 246.0, 111.0, 94.0]","[320.0, 493.0, 436.0, 168.0, 0]",rb2305,2023-01-03 09:57:00,-813.0,4039.0,4041.0,4041.0,4037.0,2022.0,0
|
||||
57,"[4039.0, 4040.0, 4041.0, 4042.0, 4043.0]","[31.0, 343.0, 546.0, 493.0, 124.0]","[220.0, 196.0, 97.0, 232.0, 0]",rb2305,2023-01-03 09:58:00,792.0,4042.0,4039.0,4043.0,4039.0,2282.0,0
|
||||
58,"[4040.0, 4041.0, 4042.0]","[203.0, 416.0, 16.0]","[876.0, 205.0, 0]",rb2305,2023-01-03 09:59:00,-446.0,4040.0,4041.0,4042.0,4040.0,1716.0,0
|
||||
59,"[4036.0, 4037.0, 4038.0, 4039.0, 4040.0, 4041.0, 4042.0]","[27.0, 147.0, 112.0, 18.0, 543.0, 758.0, 96.0]","[391.0, 653.0, 392.0, 49.0, 937.0, 79.0, 0]",rb2305,2023-01-03 10:00:00,-800.0,4037.0,4040.0,4042.0,4036.0,4221.0,0
|
||||
60,"[4037.0, 4038.0, 4039.0, 4040.0, 4041.0, 4042.0]","[0, 214.0, 128.0, 315.0, 171.0, 315.0]","[381.0, 116.0, 399.0, 329.0, 191.0, 54.0]",rb2305,2023-01-03 10:01:00,-327.0,4042.0,4037.0,4042.0,4037.0,2613.0,0
|
||||
61,"[4041.0, 4042.0, 4043.0, 4044.0, 4045.0, 4046.0, 4047.0]","[0, 253.0, 219.0, 860.0, 163.0, 1596.0, 961.0]","[33.0, 124.0, 10.0, 650.0, 849.0, 670.0, 0]",rb2305,2023-01-03 10:02:00,1716.0,4047.0,4042.0,4047.0,4041.0,6388.0,0
|
||||
62,"[4046.0, 4047.0, 4048.0, 4049.0]","[0, 388.0, 1591.0, 819.0]","[214.0, 889.0, 745.0, 0]",rb2305,2023-01-03 10:03:00,950.0,4049.0,4047.0,4049.0,4046.0,4646.0,0
|
||||
63,"[4047.0, 4048.0, 4049.0]","[125.0, 517.0, 547.0]","[772.0, 1185.0, 0]",rb2305,2023-01-03 10:04:00,-768.0,4048.0,4048.0,4049.0,4047.0,3146.0,0
|
||||
64,"[4047.0, 4048.0, 4049.0, 4050.0]","[0, 878.0, 928.0, 1822.0]","[225.0, 557.0, 683.0, 0]",rb2305,2023-01-03 10:05:00,2163.0,4049.0,4048.0,4050.0,4047.0,5110.0,0
|
||||
65,"[4048.0, 4049.0, 4050.0]","[0, 730.0, 2592.0]","[4.0, 2145.0, 133.0]",rb2305,2023-01-03 10:06:00,1040.0,4049.0,4049.0,4050.0,4048.0,5620.0,0
|
||||
66,"[4048.0, 4049.0, 4050.0, 4051.0]","[0, 565.0, 1368.0, 1.0]","[140.0, 871.0, 240.0, 0]",rb2305,2023-01-03 10:07:00,683.0,4050.0,4049.0,4051.0,4048.0,3200.0,0
|
||||
67,"[4050.0, 4051.0, 4052.0, 4053.0, 4054.0]","[0, 881.0, 309.0, 745.0, 2677.0]","[163.0, 526.0, 320.0, 1749.0, 362.0]",rb2305,2023-01-03 10:08:00,1492.0,4053.0,4050.0,4054.0,4050.0,7732.0,0
|
||||
68,"[4051.0, 4052.0, 4053.0, 4054.0, 4055.0, 4056.0]","[0, 149.0, 309.0, 851.0, 2299.0, 95.0]","[22.0, 414.0, 868.0, 3139.0, 476.0, 0]",rb2305,2023-01-03 10:09:00,-1216.0,4051.0,4054.0,4056.0,4051.0,8622.0,0
|
||||
69,"[4049.0, 4050.0, 4051.0, 4052.0, 4053.0]","[0, 420.0, 1022.0, 429.0, 146.0]","[37.0, 1183.0, 518.0, 202.0, 0]",rb2305,2023-01-03 10:10:00,77.0,4050.0,4052.0,4053.0,4049.0,3967.0,0
|
||||
70,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0, 4045.0, 4046.0, 4047.0, 4048.0, 4049.0, 4050.0, 4051.0]","[202.0, 866.0, 695.0, 1217.0, 519.0, 167.0, 122.0, 270.0, 19.0, 167.0, 351.0, 679.0]","[773.0, 1817.0, 926.0, 1088.0, 204.0, 517.0, 35.0, 166.0, 312.0, 527.0, 487.0, 0]",rb2305,2023-01-03 10:11:00,-1578.0,4042.0,4051.0,4051.0,4040.0,12156.0,0
|
||||
71,"[4040.0, 4041.0, 4042.0, 4043.0]","[84.0, 1011.0, 654.0, 200.0]","[1028.0, 1743.0, 636.0, 0]",rb2305,2023-01-03 10:12:00,-1458.0,4040.0,4042.0,4043.0,4040.0,5360.0,0
|
||||
72,"[4040.0, 4041.0, 4042.0]","[718.0, 1622.0, 191.0]","[1174.0, 479.0, 173.0]",rb2305,2023-01-03 10:13:00,705.0,4042.0,4041.0,4042.0,4040.0,4357.0,0
|
||||
73,"[4041.0, 4042.0, 4043.0, 4044.0]","[0, 777.0, 1578.0, 27.0]","[161.0, 258.0, 424.0, 0]",rb2305,2023-01-03 10:14:00,1539.0,4044.0,4042.0,4044.0,4041.0,3225.0,0
|
||||
74,"[4043.0, 4044.0, 4045.0]","[0, 795.0, 698.0]","[192.0, 154.0, 0]",rb2305,2023-01-03 10:15:00,1147.0,4044.0,4044.0,4045.0,4043.0,1839.0,0
|
||||
75,"[4049.0, 4050.0, 4051.0, 4052.0, 4053.0]","[360.0, 1451.0, 2605.0, 1062.0, 585.0]","[733.0, 1633.0, 1351.0, 821.0, 0]",rb2305,2023-01-03 10:31:00,1525.0,4051.0,4051.0,4053.0,4049.0,11318.0,0
|
||||
76,"[4049.0, 4050.0, 4051.0, 4052.0]","[0, 452.0, 564.0, 195.0]","[106.0, 1270.0, 315.0, 0]",rb2305,2023-01-03 10:32:00,-480.0,4050.0,4051.0,4052.0,4049.0,2903.0,0
|
||||
77,"[4048.0, 4049.0, 4050.0, 4051.0, 4052.0]","[0, 141.0, 153.0, 410.0, 51.0]","[225.0, 508.0, 1086.0, 177.0, 0]",rb2305,2023-01-03 10:33:00,-1241.0,4048.0,4051.0,4052.0,4048.0,2751.0,0
|
||||
78,"[4048.0, 4049.0, 4050.0, 4051.0, 4052.0]","[0, 231.0, 699.0, 961.0, 52.0]","[25.0, 400.0, 376.0, 343.0, 0]",rb2305,2023-01-03 10:34:00,799.0,4051.0,4048.0,4052.0,4048.0,3113.0,0
|
||||
79,"[4050.0, 4051.0, 4052.0, 4053.0]","[0, 249.0, 800.0, 169.0]","[69.0, 438.0, 377.0, 0]",rb2305,2023-01-03 10:35:00,334.0,4050.0,4052.0,4053.0,4050.0,2107.0,0
|
||||
80,"[4048.0, 4049.0, 4050.0, 4051.0, 4052.0]","[0, 405.0, 952.0, 357.0, 7.0]","[162.0, 603.0, 339.0, 23.0, 0]",rb2305,2023-01-03 10:36:00,594.0,4050.0,4051.0,4052.0,4048.0,2850.0,0
|
||||
81,"[4048.0, 4049.0, 4050.0]","[0, 435.0, 590.0]","[375.0, 671.0, 61.0]",rb2305,2023-01-03 10:37:00,-82.0,4049.0,4050.0,4050.0,4048.0,2133.0,0
|
||||
82,"[4048.0, 4049.0, 4050.0, 4051.0, 4052.0, 4053.0]","[0, 275.0, 187.0, 545.0, 394.0, 144.0]","[2.0, 92.0, 325.0, 0, 149.0, 0]",rb2305,2023-01-03 10:38:00,977.0,4052.0,4049.0,4053.0,4048.0,2113.0,0
|
||||
83,"[4047.0, 4048.0, 4049.0, 4050.0, 4051.0, 4052.0]","[0, 0, 340.0, 75.0, 70.0, 160.0]","[272.0, 401.0, 83.0, 101.0, 74.0, 0]",rb2305,2023-01-03 10:39:00,-286.0,4047.0,4052.0,4052.0,4047.0,1595.0,0
|
||||
84,"[4046.0, 4047.0, 4048.0, 4049.0, 4050.0]","[0, 128.0, 113.0, 299.0, 439.0]","[29.0, 365.0, 26.0, 195.0, 93.0]",rb2305,2023-01-03 10:40:00,271.0,4049.0,4046.0,4050.0,4046.0,1699.0,0
|
||||
85,"[4047.0, 4048.0, 4049.0, 4050.0]","[0, 57.0, 427.0, 93.0]","[43.0, 226.0, 509.0, 42.0]",rb2305,2023-01-03 10:41:00,-243.0,4048.0,4050.0,4050.0,4047.0,1397.0,0
|
||||
86,"[4048.0, 4049.0, 4050.0, 4051.0]","[0, 1272.0, 485.0, 200.0]","[114.0, 876.0, 113.0, 0]",rb2305,2023-01-03 10:42:00,854.0,4049.0,4048.0,4051.0,4048.0,3077.0,0
|
||||
87,"[4045.0, 4046.0, 4047.0, 4048.0, 4049.0]","[0, 431.0, 489.0, 446.0, 8.0]","[350.0, 1094.0, 639.0, 144.0, 0]",rb2305,2023-01-03 10:43:00,-853.0,4046.0,4049.0,4049.0,4045.0,3601.0,0
|
||||
88,"[4044.0, 4045.0, 4046.0, 4047.0, 4048.0]","[0, 135.0, 249.0, 206.0, 97.0]","[168.0, 1176.0, 249.0, 306.0, 0]",rb2305,2023-01-03 10:44:00,-1212.0,4046.0,4046.0,4048.0,4044.0,2586.0,0
|
||||
89,"[4044.0, 4045.0, 4046.0, 4047.0, 4048.0]","[0, 321.0, 342.0, 160.0, 122.0]","[85.0, 339.0, 150.0, 132.0, 0]",rb2305,2023-01-03 10:45:00,239.0,4046.0,4046.0,4048.0,4044.0,1653.0,0
|
||||
90,"[4042.0, 4043.0, 4044.0, 4045.0, 4046.0]","[0, 382.0, 195.0, 263.0, 241.0]","[28.0, 866.0, 454.0, 513.0, 182.0]",rb2305,2023-01-03 10:46:00,-962.0,4044.0,4046.0,4046.0,4042.0,3142.0,0
|
||||
91,"[4041.0, 4042.0, 4043.0, 4044.0]","[142.0, 243.0, 789.0, 139.0]","[1100.0, 1793.0, 645.0, 0]",rb2305,2023-01-03 10:47:00,-2225.0,4042.0,4043.0,4044.0,4041.0,4860.0,0
|
||||
92,"[4040.0, 4041.0, 4042.0, 4043.0]","[0, 486.0, 537.0, 116.0]","[191.0, 704.0, 106.0, 0]",rb2305,2023-01-03 10:48:00,138.0,4042.0,4041.0,4043.0,4040.0,2140.0,0
|
||||
93,"[4040.0, 4041.0, 4042.0, 4043.0]","[98.0, 562.0, 1419.0, 87.0]","[1350.0, 917.0, 250.0, 0]",rb2305,2023-01-03 10:49:00,-351.0,4042.0,4041.0,4043.0,4040.0,4683.0,0
|
||||
94,"[4038.0, 4039.0, 4040.0, 4041.0, 4042.0]","[0, 427.0, 806.0, 501.0, 286.0]","[106.0, 469.0, 330.0, 69.0, 0]",rb2305,2023-01-03 10:50:00,1046.0,4041.0,4042.0,4042.0,4038.0,2994.0,0
|
||||
95,"[4040.0, 4041.0, 4042.0, 4043.0]","[0, 495.0, 709.0, 1108.0]","[81.0, 266.0, 374.0, 67.0]",rb2305,2023-01-03 10:51:00,1524.0,4041.0,4041.0,4043.0,4040.0,3100.0,0
|
||||
96,"[4041.0, 4042.0, 4043.0, 4044.0]","[0, 164.0, 802.0, 30.0]","[1.0, 1156.0, 42.0, 0]",rb2305,2023-01-03 10:52:00,-203.0,4042.0,4042.0,4044.0,4041.0,2195.0,0
|
||||
97,"[4041.0, 4042.0, 4043.0]","[0, 614.0, 99.0]","[330.0, 263.0, 0]",rb2305,2023-01-03 10:53:00,120.0,4041.0,4042.0,4043.0,4041.0,1310.0,0
|
||||
98,"[4039.0, 4040.0, 4041.0, 4042.0]","[0, 239.0, 210.0, 27.0]","[206.0, 693.0, 197.0, 0]",rb2305,2023-01-03 10:54:00,-620.0,4040.0,4041.0,4042.0,4039.0,1576.0,0
|
||||
99,"[4039.0, 4040.0, 4041.0]","[0, 456.0, 208.0]","[160.0, 299.0, 0]",rb2305,2023-01-03 10:55:00,205.0,4039.0,4041.0,4041.0,4039.0,1123.0,0
|
||||
100,"[4039.0, 4040.0, 4041.0]","[0, 281.0, 472.0]","[196.0, 176.0, 0]",rb2305,2023-01-03 10:56:00,381.0,4041.0,4039.0,4041.0,4039.0,1125.0,0
|
||||
101,"[4041.0, 4042.0]","[0, 919.0]","[570.0, 165.0]",rb2305,2023-01-03 10:57:00,184.0,4042.0,4041.0,4042.0,4041.0,1654.0,0
|
||||
102,"[4041.0, 4042.0, 4043.0, 4044.0]","[0, 16.0, 968.0, 86.0]","[279.0, 161.0, 304.0, 0]",rb2305,2023-01-03 10:58:00,326.0,4043.0,4041.0,4044.0,4041.0,1824.0,0
|
||||
103,"[4039.0, 4040.0, 4041.0, 4042.0, 4043.0]","[0, 46.0, 368.0, 60.0, 49.0]","[119.0, 454.0, 235.0, 120.0, 0]",rb2305,2023-01-03 10:59:00,-405.0,4040.0,4043.0,4043.0,4039.0,1451.0,0
|
||||
104,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0]","[0, 480.0, 88.0, 326.0, 414.0]","[571.0, 319.0, 238.0, 194.0, 0]",rb2305,2023-01-03 11:00:00,-14.0,4043.0,4040.0,4044.0,4040.0,2698.0,0
|
||||
105,"[4041.0, 4042.0, 4043.0, 4044.0]","[0, 335.0, 250.0, 165.0]","[75.0, 691.0, 293.0, 76.0]",rb2305,2023-01-03 11:01:00,-385.0,4041.0,4042.0,4044.0,4041.0,1899.0,0
|
||||
106,"[4037.0, 4038.0, 4039.0, 4040.0, 4041.0]","[0, 1136.0, 534.0, 10.0, 40.0]","[610.0, 1841.0, 751.0, 624.0, 210.0]",rb2305,2023-01-03 11:02:00,-2316.0,4038.0,4041.0,4041.0,4037.0,5970.0,-1
|
||||
107,"[4037.0, 4038.0, 4039.0, 4040.0]","[0, 276.0, 315.0, 246.0]","[287.0, 159.0, 173.0, 0]",rb2305,2023-01-03 11:03:00,218.0,4038.0,4039.0,4040.0,4037.0,1485.0,0
|
||||
108,"[4038.0, 4039.0, 4040.0, 4041.0]","[0, 556.0, 455.0, 198.0]","[209.0, 145.0, 239.0, 0]",rb2305,2023-01-03 11:04:00,616.0,4041.0,4039.0,4041.0,4038.0,1802.0,0
|
||||
109,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0]","[0, 411.0, 181.0, 387.0, 7.0]","[23.0, 147.0, 172.0, 101.0, 0]",rb2305,2023-01-03 11:05:00,543.0,4043.0,4041.0,4044.0,4040.0,1429.0,0
|
||||
110,"[4043.0, 4044.0, 4045.0, 4046.0, 4047.0, 4048.0]","[78.0, 74.0, 992.0, 523.0, 508.0, 611.0]","[11.0, 135.0, 112.0, 580.0, 1048.0, 116.0]",rb2305,2023-01-03 11:06:00,784.0,4046.0,4043.0,4048.0,4043.0,4905.0,1
|
||||
111,"[4043.0, 4044.0, 4045.0, 4046.0, 4047.0, 4048.0]","[31.0, 338.0, 64.0, 637.0, 234.0, 179.0]","[388.0, 180.0, 427.0, 359.0, 187.0, 0]",rb2305,2023-01-03 11:07:00,-58.0,4045.0,4046.0,4048.0,4043.0,3025.0,0
|
||||
112,"[4043.0, 4044.0, 4045.0]","[0, 179.0, 395.0]","[31.0, 515.0, 0]",rb2305,2023-01-03 11:08:00,28.0,4044.0,4044.0,4045.0,4043.0,1120.0,0
|
||||
113,"[4043.0, 4044.0, 4045.0]","[0, 150.0, 259.0]","[41.0, 260.0, 0]",rb2305,2023-01-03 11:09:00,108.0,4044.0,4045.0,4045.0,4043.0,710.0,0
|
||||
114,"[4042.0, 4043.0, 4044.0, 4045.0]","[0, 33.0, 83.0, 386.0]","[3.0, 392.0, 193.0, 0]",rb2305,2023-01-03 11:10:00,-86.0,4042.0,4044.0,4045.0,4042.0,1090.0,0
|
||||
115,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0]","[0, 295.0, 273.0, 354.0, 77.0]","[216.0, 501.0, 470.0, 549.0, 0]",rb2305,2023-01-03 11:11:00,-737.0,4042.0,4042.0,4044.0,4040.0,2735.0,0
|
||||
116,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0]","[0, 172.0, 113.0, 144.0, 41.0]","[149.0, 439.0, 240.0, 46.0, 0]",rb2305,2023-01-03 11:12:00,-404.0,4040.0,4042.0,4044.0,4040.0,1344.0,0
|
||||
117,"[4040.0, 4041.0, 4042.0, 4043.0, 4044.0, 4045.0, 4046.0]","[0, 176.0, 66.0, 97.0, 76.0, 432.0, 120.0]","[20.0, 63.0, 21.0, 6.0, 287.0, 99.0, 0]",rb2305,2023-01-03 11:13:00,471.0,4045.0,4040.0,4046.0,4040.0,1463.0,0
|
||||
118,"[4044.0, 4045.0, 4046.0, 4047.0]","[0, 0, 760.0, 15.0]","[16.0, 528.0, 116.0, 0]",rb2305,2023-01-03 11:14:00,115.0,4045.0,4045.0,4047.0,4044.0,1437.0,0
|
||||
119,"[4044.0, 4045.0, 4046.0, 4047.0]","[0, 253.0, 420.0, 287.0]","[340.0, 784.0, 5.0, 120.0]",rb2305,2023-01-03 11:15:00,-289.0,4044.0,4045.0,4047.0,4044.0,2209.0,0
|
||||
120,"[4042.0, 4043.0, 4044.0, 4045.0, 4046.0, 4047.0, 4048.0]","[0, 0, 13.0, 191.0, 490.0, 466.0, 1.0]","[1.0, 149.0, 261.0, 453.0, 84.0, 68.0, 0]",rb2305,2023-01-03 11:16:00,145.0,4042.0,4044.0,4048.0,4042.0,2179.0,0
|
||||
121,"[4042.0, 4043.0, 4044.0]","[0, 298.0, 3.0]","[514.0, 79.0, 0]",rb2305,2023-01-03 11:17:00,-292.0,4042.0,4042.0,4044.0,4042.0,894.0,0
|
||||
122,"[4040.0, 4041.0, 4042.0, 4043.0]","[0, 52.0, 80.0, 27.0]","[144.0, 477.0, 445.0, 20.0]",rb2305,2023-01-03 11:18:00,-927.0,4040.0,4042.0,4043.0,4040.0,1246.0,0
|
||||
123,"[4040.0, 4041.0, 4042.0]","[0, 239.0, 290.0]","[560.0, 272.0, 0]",rb2305,2023-01-03 11:19:00,-303.0,4041.0,4041.0,4042.0,4040.0,1361.0,0
|
||||
124,"[4040.0, 4041.0, 4042.0, 4043.0]","[0, 877.0, 355.0, 39.0]","[56.0, 652.0, 41.0, 0]",rb2305,2023-01-03 11:20:00,522.0,4041.0,4041.0,4043.0,4040.0,2020.0,0
|
||||
125,"[4041.0, 4042.0, 4043.0, 4044.0]","[0, 729.0, 720.0, 12.0]","[259.0, 379.0, 904.0, 0]",rb2305,2023-01-03 11:21:00,-81.0,4043.0,4041.0,4044.0,4041.0,3003.0,0
|
||||
126,"[4041.0, 4042.0, 4043.0, 4044.0]","[0, 184.0, 25.0, 87.0]","[9.0, 148.0, 242.0, 0]",rb2305,2023-01-03 11:22:00,-103.0,4042.0,4043.0,4044.0,4041.0,695.0,0
|
||||
127,"[4042.0, 4043.0, 4044.0, 4045.0, 4046.0, 4047.0, 4048.0]","[0, 185.0, 187.0, 632.0, 440.0, 278.0, 883.0]","[6.0, 34.0, 226.0, 110.0, 122.0, 332.0, 0]",rb2305,2023-01-03 11:23:00,1775.0,4047.0,4042.0,4048.0,4042.0,3435.0,0
|
||||
128,"[4046.0, 4047.0, 4048.0, 4049.0, 4050.0, 4051.0]","[0, 352.0, 133.0, 1159.0, 854.0, 336.0]","[121.0, 0, 236.0, 811.0, 341.0, 0]",rb2305,2023-01-03 11:24:00,1325.0,4049.0,4046.0,4051.0,4046.0,4359.0,0
|
||||
129,"[4047.0, 4048.0, 4049.0]","[0, 389.0, 160.0]","[585.0, 179.0, 0]",rb2305,2023-01-03 11:25:00,-215.0,4047.0,4048.0,4049.0,4047.0,1313.0,0
|
||||
130,"[4045.0, 4046.0, 4047.0, 4048.0, 4049.0]","[0, 97.0, 218.0, 361.0, 445.0]","[39.0, 354.0, 335.0, 642.0, 287.0]",rb2305,2023-01-03 11:26:00,-536.0,4048.0,4048.0,4049.0,4045.0,2788.0,0
|
||||
131,"[4046.0, 4047.0, 4048.0, 4049.0]","[0, 254.0, 376.0, 191.0]","[36.0, 500.0, 489.0, 0]",rb2305,2023-01-03 11:27:00,-204.0,4047.0,4048.0,4049.0,4046.0,1846.0,0
|
||||
132,"[4045.0, 4046.0, 4047.0, 4048.0]","[0, 73.0, 428.0, 224.0]","[1.0, 625.0, 367.0, 0]",rb2305,2023-01-03 11:28:00,-268.0,4047.0,4047.0,4048.0,4045.0,1724.0,0
|
||||
133,"[4046.0, 4047.0, 4048.0, 4049.0, 4050.0, 4051.0]","[0, 224.0, 29.0, 328.0, 984.0, 32.0]","[11.0, 116.0, 27.0, 461.0, 427.0, 0]",rb2305,2023-01-03 11:29:00,555.0,4050.0,4046.0,4051.0,4046.0,2648.0,0
|
||||
134,"[4050.0, 4051.0, 4052.0, 4053.0, 4054.0]","[0, 243.0, 1082.0, 549.0, 164.0]","[370.0, 1147.0, 1641.0, 224.0, 0]",rb2305,2023-01-03 11:30:00,-1344.0,4051.0,4051.0,4054.0,4050.0,5436.0,0
|
||||
135,"[4049.0, 4050.0, 4051.0, 4052.0, 4053.0, 4055.0, 4056.0]","[75.0, 1368.0, 2486.0, 1094.0, 743.0, 3036.0, 470.0]","[1410.0, 1848.0, 987.0, 1977.0, 233.0, 0, 0]",rb2305,2023-01-03 13:31:00,2817.0,4053.0,4055.0,4056.0,4049.0,16041.0,0
|
||||
136,"[4049.0, 4050.0, 4051.0, 4052.0, 4053.0, 4054.0]","[0, 605.0, 433.0, 77.0, 644.0, 627.0]","[122.0, 1097.0, 139.0, 61.0, 364.0, 406.0]",rb2305,2023-01-03 13:32:00,197.0,4050.0,4052.0,4054.0,4049.0,4575.0,0
|
||||
137,"[4050.0, 4051.0, 4052.0, 4053.0, 4054.0]","[0, 553.0, 655.0, 518.0, 88.0]","[261.0, 418.0, 160.0, 567.0, 0]",rb2305,2023-01-03 13:33:00,408.0,4051.0,4050.0,4054.0,4050.0,3222.0,0
|
||||
138,"[4048.0, 4049.0, 4050.0, 4051.0]","[0, 347.0, 1036.0, 95.0]","[296.0, 709.0, 1331.0, 0]",rb2305,2023-01-03 13:34:00,-858.0,4050.0,4051.0,4051.0,4048.0,3830.0,0
|
||||
139,"[4046.0, 4047.0, 4048.0, 4049.0, 4050.0]","[0, 62.0, 371.0, 486.0, 199.0]","[18.0, 346.0, 136.0, 308.0, 0]",rb2305,2023-01-03 13:35:00,310.0,4047.0,4050.0,4050.0,4046.0,1934.0,0
|
||||
140,"[4045.0, 4046.0, 4047.0, 4048.0]","[0, 810.0, 967.0, 354.0]","[371.0, 778.0, 861.0, 0]",rb2305,2023-01-03 13:36:00,121.0,4046.0,4047.0,4048.0,4045.0,4141.0,0
|
||||
141,"[4047.0, 4048.0, 4049.0, 4050.0, 4051.0, 4052.0]","[103.0, 289.0, 393.0, 941.0, 565.0, 31.0]","[27.0, 56.0, 86.0, 566.0, 0, 0]",rb2305,2023-01-03 13:37:00,1587.0,4050.0,4047.0,4052.0,4047.0,3057.0,1
|
||||
142,"[4051.0, 4052.0, 4053.0, 4054.0]","[55.0, 589.0, 1023.0, 439.0]","[66.0, 481.0, 370.0, 67.0]",rb2305,2023-01-03 13:38:00,1122.0,4054.0,4051.0,4054.0,4051.0,3090.0,0
|
||||
143,"[4052.0, 4053.0, 4054.0, 4055.0, 4056.0]","[0, 34.0, 436.0, 1798.0, 209.0]","[18.0, 865.0, 767.0, 174.0, 0]",rb2305,2023-01-03 13:39:00,653.0,4055.0,4054.0,4056.0,4052.0,4301.0,0
|
||||
144,"[4055.0, 4056.0, 4057.0, 4058.0, 4059.0, 4060.0]","[0, 538.0, 769.0, 1806.0, 2601.0, 131.0]","[130.0, 0, 175.0, 2129.0, 103.0, 0]",rb2305,2023-01-03 13:40:00,3308.0,4059.0,4055.0,4060.0,4055.0,8489.0,1
|
||||
145,"[4057.0, 4058.0, 4059.0, 4060.0, 4061.0, 4062.0, 4063.0]","[0, 371.0, 1499.0, 1585.0, 2378.0, 824.0, 533.0]","[168.0, 492.0, 967.0, 0, 739.0, 623.0, 0]",rb2305,2023-01-03 13:41:00,4201.0,4062.0,4059.0,4063.0,4057.0,10590.0,0
|
||||
146,"[4062.0, 4063.0, 4064.0]","[135.0, 1155.0, 863.0]","[850.0, 1459.0, 0]",rb2305,2023-01-03 13:42:00,-156.0,4064.0,4062.0,4064.0,4062.0,4483.0,0
|
||||
147,"[4061.0, 4062.0, 4063.0, 4064.0, 4065.0]","[0, 256.0, 104.0, 749.0, 310.0]","[483.0, 790.0, 197.0, 337.0, 0]",rb2305,2023-01-03 13:43:00,-388.0,4062.0,4064.0,4065.0,4061.0,3226.0,0
|
||||
148,"[4061.0, 4062.0, 4063.0]","[20.0, 852.0, 283.0]","[971.0, 261.0, 0]",rb2305,2023-01-03 13:44:00,-77.0,4062.0,4062.0,4063.0,4061.0,2446.0,0
|
||||
149,"[4062.0, 4063.0, 4064.0]","[0, 1033.0, 604.0]","[599.0, 829.0, 0]",rb2305,2023-01-03 13:45:00,209.0,4064.0,4063.0,4064.0,4062.0,3071.0,0
|
||||
150,"[4059.0, 4060.0, 4061.0, 4062.0, 4063.0, 4064.0, 4065.0]","[124.0, 322.0, 183.0, 274.0, 24.0, 378.0, 157.0]","[1342.0, 605.0, 538.0, 248.0, 459.0, 16.0, 0]",rb2305,2023-01-03 13:46:00,-1746.0,4060.0,4064.0,4065.0,4059.0,4674.0,0
|
||||
151,"[4058.0, 4059.0, 4060.0, 4061.0]","[0, 176.0, 476.0, 43.0]","[96.0, 833.0, 292.0, 0]",rb2305,2023-01-03 13:47:00,-526.0,4060.0,4060.0,4061.0,4058.0,1916.0,0
|
||||
152,"[4059.0, 4060.0, 4061.0, 4062.0]","[0, 272.0, 459.0, 61.0]","[91.0, 595.0, 554.0, 0]",rb2305,2023-01-03 13:48:00,-448.0,4062.0,4059.0,4062.0,4059.0,2074.0,0
|
||||
153,"[4061.0, 4062.0, 4063.0]","[0, 774.0, 432.0]","[254.0, 678.0, 0]",rb2305,2023-01-03 13:49:00,274.0,4062.0,4062.0,4063.0,4061.0,2138.0,0
|
||||
154,"[4062.0, 4063.0, 4064.0]","[128.0, 399.0, 550.0]","[702.0, 901.0, 0]",rb2305,2023-01-03 13:50:00,-526.0,4063.0,4063.0,4064.0,4062.0,2680.0,0
|
||||
155,"[4061.0, 4062.0, 4063.0, 4064.0]","[0, 185.0, 475.0, 97.0]","[361.0, 1119.0, 43.0, 0]",rb2305,2023-01-03 13:51:00,-766.0,4062.0,4064.0,4064.0,4061.0,2280.0,0
|
||||
156,"[4061.0, 4062.0, 4063.0]","[0, 124.0, 592.0]","[523.0, 670.0, 0]",rb2305,2023-01-03 13:52:00,-477.0,4061.0,4063.0,4063.0,4061.0,1909.0,0
|
||||
157,"[4060.0, 4061.0, 4062.0]","[0, 118.0, 463.0]","[897.0, 1056.0, 0]",rb2305,2023-01-03 13:53:00,-1372.0,4060.0,4061.0,4062.0,4060.0,2534.0,0
|
||||
158,"[4058.0, 4059.0, 4060.0, 4061.0]","[0, 388.0, 148.0, 377.0]","[354.0, 476.0, 645.0, 4.0]",rb2305,2023-01-03 13:54:00,-566.0,4059.0,4061.0,4061.0,4058.0,2392.0,0
|
||||
159,"[4058.0, 4059.0, 4060.0]","[0, 725.0, 305.0]","[234.0, 854.0, 0]",rb2305,2023-01-03 13:55:00,-58.0,4060.0,4059.0,4060.0,4058.0,2118.0,0
|
||||
160,"[4059.0, 4060.0, 4061.0]","[0, 669.0, 48.0]","[400.0, 118.0, 0]",rb2305,2023-01-03 13:56:00,199.0,4060.0,4059.0,4061.0,4059.0,1244.0,0
|
||||
161,"[4057.0, 4058.0, 4059.0, 4060.0, 4061.0]","[0, 337.0, 87.0, 66.0, 5.0]","[391.0, 1409.0, 460.0, 240.0, 0]",rb2305,2023-01-03 13:57:00,-2005.0,4058.0,4060.0,4061.0,4057.0,3063.0,-1
|
||||
162,"[4057.0, 4058.0, 4059.0, 4060.0]","[0, 159.0, 380.0, 83.0]","[77.0, 444.0, 243.0, 0]",rb2305,2023-01-03 13:58:00,-142.0,4058.0,4059.0,4060.0,4057.0,1386.0,0
|
||||
163,"[4058.0, 4059.0, 4060.0]","[0, 488.0, 43.0]","[879.0, 179.0, 0]",rb2305,2023-01-03 13:59:00,-527.0,4060.0,4058.0,4060.0,4058.0,1593.0,0
|
||||
164,"[4057.0, 4058.0, 4059.0, 4060.0]","[0, 124.0, 619.0, 35.0]","[64.0, 468.0, 316.0, 0]",rb2305,2023-01-03 14:00:00,-70.0,4058.0,4060.0,4060.0,4057.0,1626.0,0
|
||||
165,"[4058.0, 4059.0, 4060.0]","[0, 463.0, 616.0]","[60.0, 710.0, 57.0]",rb2305,2023-01-03 14:01:00,252.0,4060.0,4058.0,4060.0,4058.0,1907.0,0
|
||||
166,"[4058.0, 4059.0, 4060.0, 4061.0, 4062.0, 4063.0]","[0, 118.0, 172.0, 799.0, 422.0, 48.0]","[8.0, 307.0, 206.0, 547.0, 59.0, 0]",rb2305,2023-01-03 14:02:00,432.0,4059.0,4060.0,4063.0,4058.0,2686.0,0
|
||||
167,"[4058.0, 4059.0, 4060.0]","[0, 705.0, 4.0]","[191.0, 88.0, 0]",rb2305,2023-01-03 14:03:00,430.0,4058.0,4059.0,4060.0,4058.0,1019.0,0
|
||||
168,"[4058.0, 4059.0, 4060.0, 4061.0]","[0, 180.0, 396.0, 48.0]","[72.0, 249.0, 49.0, 0]",rb2305,2023-01-03 14:04:00,254.0,4061.0,4059.0,4061.0,4058.0,1000.0,0
|
||||
169,"[4061.0, 4062.0, 4063.0]","[354.0, 314.0, 729.0]","[50.0, 1146.0, 0]",rb2305,2023-01-03 14:05:00,201.0,4063.0,4061.0,4063.0,4061.0,2593.0,0
|
||||
170,"[4060.0, 4061.0, 4062.0, 4063.0]","[0, 71.0, 66.0, 350.0]","[1.0, 210.0, 378.0, 0]",rb2305,2023-01-03 14:06:00,-102.0,4061.0,4063.0,4063.0,4060.0,1076.0,0
|
||||
171,"[4057.0, 4058.0, 4059.0, 4060.0, 4061.0]","[0, 3.0, 104.0, 158.0, 234.0]","[54.0, 588.0, 194.0, 327.0, 0]",rb2305,2023-01-03 14:07:00,-664.0,4057.0,4060.0,4061.0,4057.0,1662.0,0
|
||||
172,"[4056.0, 4057.0, 4058.0, 4059.0, 4060.0]","[0, 10.0, 281.0, 112.0, 124.0]","[424.0, 434.0, 471.0, 168.0, 0]",rb2305,2023-01-03 14:08:00,-970.0,4059.0,4058.0,4060.0,4056.0,2024.0,0
|
||||
173,"[4059.0, 4060.0, 4061.0]","[0, 294.0, 51.0]","[483.0, 312.0, 0]",rb2305,2023-01-03 14:09:00,-450.0,4060.0,4060.0,4061.0,4059.0,1140.0,0
|
||||
174,"[4059.0, 4060.0, 4061.0]","[0, 255.0, 156.0]","[34.0, 574.0, 0]",rb2305,2023-01-03 14:10:00,-197.0,4061.0,4060.0,4061.0,4059.0,1021.0,0
|
||||
175,"[4060.0, 4061.0, 4062.0, 4063.0]","[0, 694.0, 75.0, 48.0]","[303.0, 401.0, 0, 0]",rb2305,2023-01-03 14:11:00,113.0,4063.0,4061.0,4063.0,4060.0,1537.0,0
|
||||
176,"[4061.0, 4062.0, 4063.0]","[0, 409.0, 12.0]","[222.0, 155.0, 0]",rb2305,2023-01-03 14:12:00,44.0,4062.0,4063.0,4063.0,4061.0,798.0,0
|
||||
177,"[4060.0, 4061.0, 4062.0, 4063.0]","[0, 291.0, 850.0, 19.0]","[159.0, 508.0, 147.0, 0]",rb2305,2023-01-03 14:13:00,346.0,4063.0,4061.0,4063.0,4060.0,1974.0,0
|
||||
178,"[4062.0, 4063.0, 4064.0, 4065.0, 4066.0, 4067.0, 4068.0]","[0, 630.0, 1021.0, 2734.0, 720.0, 2722.0, 361.0]","[53.0, 38.0, 329.0, 47.0, 1155.0, 742.0, 0]",rb2305,2023-01-03 14:14:00,5824.0,4065.0,4062.0,4068.0,4062.0,10552.0,2
|
||||
179,"[4063.0, 4064.0, 4065.0, 4066.0, 4067.0]","[0, 153.0, 474.0, 343.0, 246.0]","[25.0, 610.0, 1245.0, 398.0, 0]",rb2305,2023-01-03 14:15:00,-1062.0,4064.0,4066.0,4067.0,4063.0,3494.0,0
|
||||
180,"[4065.0, 4066.0, 4067.0]","[0, 387.0, 835.0]","[295.0, 339.0, 0]",rb2305,2023-01-03 14:16:00,588.0,4066.0,4066.0,4067.0,4065.0,1856.0,0
|
||||
181,"[4064.0, 4065.0, 4066.0, 4067.0]","[0, 632.0, 420.0, 104.0]","[171.0, 568.0, 94.0, 0]",rb2305,2023-01-03 14:17:00,323.0,4064.0,4067.0,4067.0,4064.0,1989.0,0
|
||||
182,"[4064.0, 4065.0, 4066.0, 4067.0]","[0, 365.0, 323.0, 148.0]","[364.0, 116.0, 266.0, 0]",rb2305,2023-01-03 14:18:00,90.0,4066.0,4064.0,4067.0,4064.0,1582.0,0
|
||||
183,"[4066.0, 4067.0, 4068.0]","[0, 346.0, 625.0]","[192.0, 727.0, 0]",rb2305,2023-01-03 14:19:00,52.0,4067.0,4067.0,4068.0,4066.0,1890.0,0
|
||||
184,"[4067.0, 4068.0, 4069.0, 4070.0, 4071.0]","[0, 684.0, 1145.0, 2860.0, 1251.0]","[228.0, 655.0, 1025.0, 658.0, 0]",rb2305,2023-01-03 14:20:00,3374.0,4069.0,4067.0,4071.0,4067.0,8506.0,0
|
||||
185,"[4068.0, 4069.0, 4070.0]","[0, 514.0, 1050.0]","[18.0, 929.0, 0]",rb2305,2023-01-03 14:21:00,617.0,4069.0,4069.0,4070.0,4068.0,2515.0,0
|
||||
186,"[4066.0, 4067.0, 4068.0, 4069.0, 4070.0]","[0, 108.0, 140.0, 206.0, 165.0]","[506.0, 671.0, 535.0, 475.0, 0]",rb2305,2023-01-03 14:22:00,-1568.0,4066.0,4069.0,4070.0,4066.0,2806.0,0
|
||||
187,"[4065.0, 4066.0, 4067.0, 4068.0]","[0, 101.0, 676.0, 699.0]","[403.0, 660.0, 282.0, 0]",rb2305,2023-01-03 14:23:00,131.0,4066.0,4067.0,4068.0,4065.0,2845.0,0
|
||||
188,"[4066.0, 4067.0, 4068.0]","[0, 506.0, 83.0]","[391.0, 117.0, 0]",rb2305,2023-01-03 14:24:00,81.0,4068.0,4066.0,4068.0,4066.0,1107.0,0
|
||||
189,"[4066.0, 4067.0, 4068.0, 4069.0, 4070.0]","[0, 35.0, 212.0, 313.0, 711.0]","[65.0, 176.0, 59.0, 658.0, 0]",rb2305,2023-01-03 14:25:00,313.0,4069.0,4068.0,4070.0,4066.0,2229.0,0
|
||||
190,"[4068.0, 4069.0, 4070.0, 4071.0]","[0, 321.0, 471.0, 697.0]","[416.0, 565.0, 394.0, 0]",rb2305,2023-01-03 14:26:00,114.0,4069.0,4069.0,4071.0,4068.0,2890.0,0
|
||||
191,"[4068.0, 4069.0, 4070.0, 4071.0]","[0, 1030.0, 1301.0, 0]","[477.0, 1347.0, 1315.0, 5.0]",rb2305,2023-01-03 14:27:00,-813.0,4070.0,4070.0,4071.0,4068.0,5475.0,0
|
||||
192,"[4069.0, 4070.0, 4071.0, 4072.0, 4073.0, 4074.0]","[0, 168.0, 179.0, 551.0, 758.0, 612.0]","[233.0, 361.0, 396.0, 954.0, 397.0, 0]",rb2305,2023-01-03 14:28:00,-73.0,4073.0,4070.0,4074.0,4069.0,4610.0,0
|
||||
193,"[4072.0, 4073.0, 4074.0]","[0, 828.0, 47.0]","[1213.0, 311.0, 0]",rb2305,2023-01-03 14:29:00,-649.0,4073.0,4072.0,4074.0,4072.0,2399.0,0
|
||||
194,"[4071.0, 4072.0, 4073.0]","[110.0, 425.0, 102.0]","[954.0, 259.0, 0]",rb2305,2023-01-03 14:30:00,-576.0,4072.0,4073.0,4073.0,4071.0,1854.0,0
|
||||
195,"[4069.0, 4070.0, 4071.0, 4072.0]","[0, 395.0, 75.0, 601.0]","[981.0, 771.0, 247.0, 0]",rb2305,2023-01-03 14:31:00,-928.0,4069.0,4072.0,4072.0,4069.0,3070.0,0
|
||||
196,"[4063.0, 4064.0, 4065.0, 4066.0, 4067.0, 4068.0, 4069.0, 4070.0]","[311.0, 423.0, 193.0, 299.0, 163.0, 0, 0, 130.0]","[1247.0, 518.0, 938.0, 567.0, 209.0, 598.0, 130.0, 0]",rb2305,2023-01-03 14:32:00,-2688.0,4063.0,4070.0,4070.0,4063.0,5785.0,-2
|
||||
197,"[4060.0, 4061.0, 4062.0, 4063.0, 4064.0]","[0, 998.0, 1264.0, 375.0, 12.0]","[1497.0, 1296.0, 773.0, 476.0, 0]",rb2305,2023-01-03 14:33:00,-1393.0,4062.0,4063.0,4064.0,4060.0,6702.0,0
|
||||
198,"[4062.0, 4063.0, 4064.0, 4065.0]","[0, 212.0, 656.0, 554.0]","[94.0, 282.0, 59.0, 0]",rb2305,2023-01-03 14:34:00,987.0,4065.0,4062.0,4065.0,4062.0,1857.0,0
|
||||
199,"[4064.0, 4065.0, 4066.0]","[0, 775.0, 270.0]","[491.0, 422.0, 0]",rb2305,2023-01-03 14:35:00,132.0,4064.0,4065.0,4066.0,4064.0,1958.0,0
|
||||
200,"[4062.0, 4063.0, 4064.0, 4065.0, 4066.0]","[0, 125.0, 182.0, 737.0, 111.0]","[160.0, 637.0, 139.0, 439.0, 0]",rb2305,2023-01-03 14:36:00,-220.0,4066.0,4064.0,4066.0,4062.0,2530.0,0
|
||||
201,"[4062.0, 4063.0, 4064.0, 4065.0, 4066.0]","[0, 110.0, 209.0, 209.0, 121.0]","[150.0, 391.0, 440.0, 334.0, 0]",rb2305,2023-01-03 14:37:00,-666.0,4062.0,4065.0,4066.0,4062.0,1994.0,0
|
||||
202,"[4062.0, 4063.0, 4064.0]","[32.0, 512.0, 208.0]","[897.0, 200.0, 0]",rb2305,2023-01-03 14:38:00,-345.0,4063.0,4063.0,4064.0,4062.0,1849.0,0
|
||||
203,"[4062.0, 4063.0, 4064.0, 4065.0]","[0, 186.0, 216.0, 116.0]","[227.0, 361.0, 201.0, 0]",rb2305,2023-01-03 14:39:00,-271.0,4063.0,4063.0,4065.0,4062.0,1307.0,0
|
||||
204,"[4061.0, 4062.0, 4063.0]","[0, 911.0, 62.0]","[139.0, 670.0, 0]",rb2305,2023-01-03 14:40:00,164.0,4061.0,4062.0,4063.0,4061.0,1785.0,0
|
||||
205,"[4061.0, 4062.0, 4063.0]","[0, 754.0, 26.0]","[188.0, 354.0, 0]",rb2305,2023-01-03 14:41:00,238.0,4062.0,4061.0,4063.0,4061.0,1324.0,0
|
||||
206,"[4061.0, 4062.0, 4063.0, 4064.0, 4065.0, 4066.0]","[0, 27.0, 416.0, 395.0, 323.0, 36.0]","[4.0, 94.0, 248.0, 334.0, 17.0, 0]",rb2305,2023-01-03 14:42:00,500.0,4065.0,4062.0,4066.0,4061.0,1905.0,0
|
||||
207,"[4064.0, 4065.0, 4066.0]","[0, 123.0, 411.0]","[154.0, 443.0, 0]",rb2305,2023-01-03 14:43:00,-63.0,4064.0,4065.0,4066.0,4064.0,1131.0,0
|
||||
208,"[4061.0, 4062.0, 4063.0, 4064.0, 4065.0, 4066.0]","[0, 192.0, 132.0, 35.0, 313.0, 1.0]","[58.0, 442.0, 154.0, 303.0, 143.0, 0]",rb2305,2023-01-03 14:44:00,-427.0,4062.0,4065.0,4066.0,4061.0,1773.0,0
|
||||
209,"[4062.0, 4063.0, 4064.0]","[0, 103.0, 289.0]","[12.0, 296.0, 0]",rb2305,2023-01-03 14:45:00,84.0,4063.0,4062.0,4064.0,4062.0,700.0,0
|
||||
210,"[4060.0, 4061.0, 4062.0, 4063.0, 4064.0, 4065.0]","[0, 75.0, 62.0, 237.0, 192.0, 446.0]","[629.0, 383.0, 247.0, 339.0, 487.0, 613.0]",rb2305,2023-01-03 14:46:00,-1686.0,4061.0,4064.0,4065.0,4060.0,3722.0,0
|
||||
211,"[4057.0, 4058.0, 4059.0, 4060.0, 4061.0]","[0, 1482.0, 143.0, 476.0, 112.0]","[1399.0, 1246.0, 53.0, 930.0, 221.0]",rb2305,2023-01-03 14:47:00,-1636.0,4058.0,4061.0,4061.0,4057.0,6062.0,0
|
||||
212,"[4056.0, 4057.0, 4058.0]","[0, 828.0, 300.0]","[271.0, 1703.0, 0]",rb2305,2023-01-03 14:48:00,-846.0,4057.0,4057.0,4058.0,4056.0,3102.0,0
|
||||
213,"[4056.0, 4057.0, 4058.0, 4059.0, 4060.0]","[0, 354.0, 506.0, 331.0, 167.0]","[513.0, 424.0, 170.0, 97.0, 0]",rb2305,2023-01-03 14:49:00,154.0,4059.0,4057.0,4060.0,4056.0,2569.0,0
|
||||
214,"[4057.0, 4058.0, 4059.0, 4060.0]","[0, 262.0, 218.0, 223.0]","[296.0, 559.0, 47.0, 0]",rb2305,2023-01-03 14:50:00,-199.0,4058.0,4058.0,4060.0,4057.0,1609.0,0
|
||||
215,"[4057.0, 4058.0, 4059.0, 4060.0]","[0, 458.0, 240.0, 224.0]","[805.0, 352.0, 206.0, 0]",rb2305,2023-01-03 14:51:00,-441.0,4057.0,4058.0,4060.0,4057.0,2286.0,0
|
||||
216,"[4057.0, 4058.0, 4059.0, 4060.0]","[0, 352.0, 579.0, 5.0]","[513.0, 802.0, 82.0, 0]",rb2305,2023-01-03 14:52:00,-461.0,4059.0,4057.0,4060.0,4057.0,2336.0,0
|
||||
217,"[4058.0, 4059.0, 4060.0]","[44.0, 526.0, 530.0]","[65.0, 1878.0, 0]",rb2305,2023-01-03 14:53:00,-843.0,4059.0,4060.0,4060.0,4058.0,3043.0,0
|
||||
218,"[4057.0, 4058.0, 4059.0, 4060.0]","[0, 169.0, 469.0, 77.0]","[54.0, 662.0, 29.0, 0]",rb2305,2023-01-03 14:54:00,-30.0,4058.0,4059.0,4060.0,4057.0,1460.0,0
|
||||
219,"[4057.0, 4058.0, 4059.0]","[0, 881.0, 47.0]","[850.0, 303.0, 0]",rb2305,2023-01-03 14:55:00,-225.0,4058.0,4058.0,4059.0,4057.0,2081.0,0
|
||||
220,"[4057.0, 4058.0, 4059.0, 4060.0]","[0, 226.0, 741.0, 268.0]","[97.0, 999.0, 683.0, 0]",rb2305,2023-01-03 14:56:00,-544.0,4057.0,4058.0,4060.0,4057.0,3029.0,0
|
||||
221,"[4057.0, 4058.0, 4059.0, 4060.0]","[0, 94.0, 714.0, 561.0]","[457.0, 925.0, 1132.0, 0]",rb2305,2023-01-03 14:57:00,-1145.0,4059.0,4058.0,4060.0,4057.0,4039.0,0
|
||||
222,"[4058.0, 4059.0, 4060.0, 4061.0]","[0, 1138.0, 1039.0, 368.0]","[540.0, 1425.0, 423.0, 0]",rb2305,2023-01-03 14:58:00,157.0,4061.0,4059.0,4061.0,4058.0,4940.0,0
|
||||
223,"[4060.0, 4061.0, 4062.0, 4063.0, 4064.0]","[0, 189.0, 1559.0, 1671.0, 222.0]","[212.0, 518.0, 1450.0, 531.0, 0]",rb2305,2023-01-03 14:59:00,930.0,4063.0,4060.0,4064.0,4060.0,6425.0,0
|
||||
224,"[4061.0, 4062.0, 4063.0, 4064.0]","[0, 323.0, 687.0, 1202.0]","[272.0, 2372.0, 1725.0, 0]",rb2305,2023-01-03 15:00:00,-2157.0,4063.0,4063.0,4064.0,4061.0,6581.0,0
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+297
@@ -0,0 +1,297 @@
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
|
||||
# import pandas as pd
|
||||
import itertools
|
||||
import multiprocessing
|
||||
import talib as tb
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
lines = ("sig", "delta")
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.02),
|
||||
("fixed_stop_loss_percent", 0.01),
|
||||
("duiji", 1),
|
||||
("cout_delta", 1),
|
||||
("delta", 1),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1
|
||||
self.signal = self.datas[0].sig
|
||||
self.delta = self.datas[0].delta
|
||||
self.pos = 0
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.renei_open_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.reniei_bop = []
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
self.barN = 0
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def next(self):
|
||||
self.barN += 1
|
||||
# position = self.getposition(self.datas[0]).size
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
def 每日重置数据():
|
||||
current_time = dt.time()
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
clearing_executed = False
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_open_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_open_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.renei_open_ma.append(self.open[0])
|
||||
self.renei_high_ma.append(self.high[0])
|
||||
self.renei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.reniei_bop = tb.BOP(
|
||||
np.array(self.renei_open_ma),
|
||||
np.array(self.renei_high_ma),
|
||||
np.array(self.renei_low_ma),
|
||||
np.array(self.rinei_ma),
|
||||
)
|
||||
clearing_executed = False
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
self.long_trailing_stop_price = max(self.low[0], self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
self.short_trailing_stop_price = min(self.high[0], self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
|
||||
if (
|
||||
self.out_long > 0
|
||||
and self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if (
|
||||
self.out_short > 0
|
||||
and self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
if run_kg is False:
|
||||
t3 = tb.T3(np.array(self.deltas_list))
|
||||
t3_cum = tb.T3(np.array(self.delta_cumsum))
|
||||
# 开多组合 = self.rinei_mean > 0 and self.closes[0] > self.rinei_mean and self.signal[0] > self.params.duiji and self.data.delta[0] > self.params.delta and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
# 开空组合 = self.rinei_mean > 0 and self.closes[0] < self.rinei_mean and self.signal[0] < -self.params.duiji and self.data.delta[0] < -self.params.delta and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
开多组合 = (
|
||||
self.reniei_bop[-1] > 0
|
||||
and self.signal[0] > self.params.duiji
|
||||
and self.data.delta[0] > t3[-1] # self.params.delta
|
||||
and self.delta_cumsum[-1] > t3_cum[-1] # self.params.cout_delta
|
||||
)
|
||||
开空组合 = (
|
||||
self.reniei_bop[-1] < 0
|
||||
and self.signal[0] < -self.params.duiji
|
||||
and self.data.delta[0] < t3[-1] # -self.params.delta
|
||||
and self.delta_cumsum[-1] < t3_cum[-1] # -self.params.cout_delta
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > self.params.duiji
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -self.params.duiji
|
||||
|
||||
if self.pos != 1:
|
||||
if 平多条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合:
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
|
||||
if self.pos != -1:
|
||||
if 平空条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合:
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
|
||||
|
||||
def evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(
|
||||
MyStrategy_固定止损_跟踪止盈,
|
||||
trailing_stop_percent=trailing_stop_percent,
|
||||
fixed_stop_loss_percent=fixed_stop_loss_percent,
|
||||
duiji=duiji,
|
||||
cout_delta=cout_delta,
|
||||
delta=delta,
|
||||
)
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2020, 1, 1),
|
||||
todate=datetime(2023, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
cerebro.adddata(data)
|
||||
cerebro.broker.setcash(300000.0)
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300)
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue(), (trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta)
|
||||
|
||||
|
||||
def run_backtest(params):
|
||||
trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file = params
|
||||
return evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
csv_file = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IM888\IM888_rs_2023_5T_back_ofdata_dj_new.csv"
|
||||
|
||||
trailing_stop_percents = np.arange(0.005, 0.025, 0.005)
|
||||
fixed_stop_loss_percents = np.arange(0.01, 0.050, 0.01)
|
||||
duiji = np.arange(1, 4, 1)
|
||||
cout_delta = np.arange(100000, 200000, 100000) # (500, 3500, 500)
|
||||
delta = np.arange(100000, 200000, 100000) # (500, 3500, 500)
|
||||
|
||||
combinations = list(itertools.product(trailing_stop_percents, fixed_stop_loss_percents, duiji, cout_delta, delta))
|
||||
combinations = [(tsp, fslp, d, cd, dl, csv_file) for tsp, fslp, d, cd, dl in combinations]
|
||||
|
||||
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
|
||||
results = pool.map(run_backtest, combinations)
|
||||
|
||||
best_value = 0
|
||||
best_parameters = None
|
||||
|
||||
for value, params in results:
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_parameters = params
|
||||
print(f"combo: {params}, value: {value}, best_value: {best_value}, best_parameters: {best_parameters}")
|
||||
|
||||
print(f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%")
|
||||
print(f"最大市值: {best_value}")
|
||||
|
||||
# trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta
|
||||
# IM
|
||||
# 5M:(0.01, 0.02, 2, 700000, 500000)
|
||||
# 1M:(0.005, 0.02, 3, 100000, 200000)
|
||||
# IF
|
||||
# 5M:(0.005, 0.02, 1, 100000, 400000)
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import itertools
|
||||
import multiprocessing
|
||||
|
||||
import talib as tb
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
lines = ("sig", "delta")
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.02),
|
||||
("fixed_stop_loss_percent", 0.01),
|
||||
("duiji", 1),
|
||||
("cout_delta", 1),
|
||||
("delta", 1),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1
|
||||
self.signal = self.datas[0].sig
|
||||
self.delta = self.datas[0].delta
|
||||
self.pos = 0
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.reniei_sar = []
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
self.barN = 0
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def next(self):
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
def 每日重置数据():
|
||||
current_time = dt.time()
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
clearing_executed = False
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.renei_high_ma.append(self.high[0])
|
||||
self.renei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.reniei_sar = tb.SAR(np.array(self.renei_high_ma), np.array(self.renei_low_ma), 0.02, 0.2)
|
||||
clearing_executed = False
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
self.long_trailing_stop_price = max(self.low[0], self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
self.short_trailing_stop_price = min(self.high[0], self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
|
||||
if (
|
||||
self.out_long > 0
|
||||
and self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if (
|
||||
self.out_short > 0
|
||||
and self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
if run_kg == False:
|
||||
# 开多组合 = self.rinei_mean > 0 and self.closes[0] > self.rinei_mean and self.signal[0] > self.params.duiji and self.data.delta[0] > self.params.delta and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
# 开空组合 = self.rinei_mean > 0 and self.closes[0] < self.rinei_mean and self.signal[0] < -self.params.duiji and self.data.delta[0] < -self.params.delta and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
开多组合 = (
|
||||
self.reniei_sar[-1] > self.closes[0]
|
||||
and self.signal[0] > self.params.duiji
|
||||
and self.data.delta[0] > self.params.delta
|
||||
and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
)
|
||||
开空组合 = (
|
||||
self.reniei_sar[-1] < self.closes[0]
|
||||
and self.signal[0] < -self.params.duiji
|
||||
and self.data.delta[0] < -self.params.delta
|
||||
and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > self.params.duiji
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -self.params.duiji
|
||||
|
||||
if self.pos != 1:
|
||||
if 平多条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合:
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
|
||||
if self.pos != -1:
|
||||
if 平空条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合:
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
|
||||
|
||||
def evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(
|
||||
MyStrategy_固定止损_跟踪止盈,
|
||||
trailing_stop_percent=trailing_stop_percent,
|
||||
fixed_stop_loss_percent=fixed_stop_loss_percent,
|
||||
duiji=duiji,
|
||||
cout_delta=cout_delta,
|
||||
delta=delta,
|
||||
)
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2020, 1, 1),
|
||||
todate=datetime(2023, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
cerebro.adddata(data)
|
||||
cerebro.broker.setcash(300000.0)
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300)
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue(), (trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta)
|
||||
|
||||
|
||||
def run_backtest(params):
|
||||
trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file = params
|
||||
return evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
csv_file = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IM888\IM888_rs_2023_5T_back_ofdata_dj.csv"
|
||||
|
||||
trailing_stop_percents = np.arange(0.005, 0.025, 0.005)
|
||||
fixed_stop_loss_percents = np.arange(0.01, 0.050, 0.01)
|
||||
duiji = np.arange(1, 4, 1)
|
||||
cout_delta = np.arange(100000, 800000, 100000) # (500, 3500, 500)
|
||||
delta = np.arange(100000, 800000, 100000) # (500, 3500, 500)
|
||||
|
||||
combinations = list(itertools.product(trailing_stop_percents, fixed_stop_loss_percents, duiji, cout_delta, delta))
|
||||
combinations = [(tsp, fslp, d, cd, dl, csv_file) for tsp, fslp, d, cd, dl in combinations]
|
||||
|
||||
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
|
||||
results = pool.map(run_backtest, combinations)
|
||||
|
||||
best_value = 0
|
||||
best_parameters = None
|
||||
|
||||
for value, params in results:
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_parameters = params
|
||||
print(f"combo: {params}, value: {value}, best_value: {best_value}, best_parameters: {best_parameters}")
|
||||
|
||||
print(f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%")
|
||||
print(f"最大市值: {best_value}")
|
||||
|
||||
# trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta
|
||||
# IM
|
||||
# 5M:(0.01, 0.02, 2, 700000, 500000)
|
||||
# 1M:(0.005, 0.02, 3, 100000, 200000)
|
||||
# IF
|
||||
# 5M:(0.005, 0.02, 1, 100000, 400000)
|
||||
+382
@@ -0,0 +1,382 @@
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
|
||||
# import pandas as pd
|
||||
import itertools
|
||||
import multiprocessing
|
||||
import talib as tb
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
lines = ("sig", "delta")
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.02),
|
||||
("fixed_stop_loss_percent", 0.01),
|
||||
("duiji", 1),
|
||||
("cout_delta", 1),
|
||||
("delta", 1),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1
|
||||
self.signal = self.datas[0].sig
|
||||
self.delta = self.datas[0].delta
|
||||
self.pos = 0
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.renei_open_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.reniei_indicator = []
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
self.barN = 0
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def next(self):
|
||||
self.barN += 1
|
||||
# position = self.getposition(self.datas[0]).size
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
def 每日重置数据():
|
||||
current_time = dt.time()
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
clearing_executed = False
|
||||
if (
|
||||
clearing_time1_start <= current_time <= clearing_time1_end
|
||||
and not clearing_executed
|
||||
):
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_open_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif (
|
||||
clearing_time2_start <= current_time <= clearing_time2_end
|
||||
and not clearing_executed
|
||||
):
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_open_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.renei_open_ma.append(self.open[0])
|
||||
self.renei_high_ma.append(self.high[0])
|
||||
self.renei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.reniei_indicator = tb.AROONOSC(
|
||||
np.array(self.renei_high_ma),
|
||||
np.array(self.renei_low_ma),
|
||||
self.params.delta,
|
||||
)
|
||||
clearing_executed = False
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
self.long_trailing_stop_price = max(
|
||||
self.low[0], self.long_trailing_stop_price
|
||||
)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
self.short_trailing_stop_price = min(
|
||||
self.high[0], self.short_trailing_stop_price
|
||||
)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (
|
||||
1 + self.trailing_stop_percent
|
||||
)
|
||||
|
||||
if (
|
||||
self.out_long > 0
|
||||
and self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=self.Lots,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if (
|
||||
self.out_short > 0
|
||||
and self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=self.Lots,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=self.Lots,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=self.Lots,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
if run_kg is False:
|
||||
# t3 = tb.T3(np.array(self.deltas_list))
|
||||
# t3_cum = tb.T3(np.array(self.delta_cumsum))
|
||||
# 开多组合 = self.rinei_mean > 0 and self.closes[0] > self.rinei_mean and self.signal[0] > self.params.duiji and self.data.delta[0] > self.params.delta and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
# 开空组合 = self.rinei_mean > 0 and self.closes[0] < self.rinei_mean and self.signal[0] < -self.params.duiji and self.data.delta[0] < -self.params.delta and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
开多组合 = (
|
||||
self.reniei_indicator[-1] > 0
|
||||
and self.signal[0] > self.params.duiji
|
||||
and self.data.delta[0]
|
||||
> max(self.deltas_list[-self.params.cout_delta : -1])
|
||||
and self.delta_cumsum[-1]
|
||||
> max(self.delta_cumsum[-self.params.cout_delta : -1])
|
||||
)
|
||||
开空组合 = (
|
||||
self.reniei_indicator[-1] < 0
|
||||
and self.signal[0] < -self.params.duiji
|
||||
and self.data.delta[0]
|
||||
< min(self.deltas_list[-self.params.cout_delta : -1])
|
||||
and self.delta_cumsum[-1]
|
||||
< min(self.delta_cumsum[-self.params.cout_delta : -1])
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > self.params.duiji
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -self.params.duiji
|
||||
|
||||
if self.pos != 1:
|
||||
if 平多条件:
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合:
|
||||
self.buy(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=1,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
|
||||
if self.pos != -1:
|
||||
if 平空条件:
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合:
|
||||
self.sell(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=1,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
|
||||
|
||||
def evaluate_strategy(
|
||||
trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file
|
||||
):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(
|
||||
MyStrategy_固定止损_跟踪止盈,
|
||||
trailing_stop_percent=trailing_stop_percent,
|
||||
fixed_stop_loss_percent=fixed_stop_loss_percent,
|
||||
duiji=duiji,
|
||||
cout_delta=cout_delta,
|
||||
delta=delta,
|
||||
)
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2020, 1, 1),
|
||||
todate=datetime(2023, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
cerebro.adddata(data)
|
||||
cerebro.broker.setcash(300000.0)
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300)
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue(), (
|
||||
trailing_stop_percent,
|
||||
fixed_stop_loss_percent,
|
||||
duiji,
|
||||
cout_delta,
|
||||
delta,
|
||||
)
|
||||
|
||||
|
||||
def run_backtest(params):
|
||||
(
|
||||
trailing_stop_percent,
|
||||
fixed_stop_loss_percent,
|
||||
duiji,
|
||||
cout_delta,
|
||||
delta,
|
||||
csv_file,
|
||||
) = params
|
||||
return evaluate_strategy(
|
||||
trailing_stop_percent,
|
||||
fixed_stop_loss_percent,
|
||||
duiji,
|
||||
cout_delta,
|
||||
delta,
|
||||
csv_file,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
csv_file = r"E:\of_data\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IM888\IM888_rs_2023_5T_back_ofdata_dj.csv"
|
||||
|
||||
trailing_stop_percents = np.arange(0.005, 0.025, 0.005)
|
||||
fixed_stop_loss_percents = np.arange(0.01, 0.050, 0.01)
|
||||
duiji = np.arange(0, 4, 1)
|
||||
cout_delta = np.arange(5, 20, 5) # (500, 3500, 500)
|
||||
delta = np.arange(20, 120, 10) # (500, 3500, 500)
|
||||
|
||||
combinations = list(
|
||||
itertools.product(
|
||||
trailing_stop_percents, fixed_stop_loss_percents, duiji, cout_delta, delta
|
||||
)
|
||||
)
|
||||
combinations = [
|
||||
(tsp, fslp, d, cd, dl, csv_file) for tsp, fslp, d, cd, dl in combinations
|
||||
]
|
||||
|
||||
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
|
||||
results = pool.map(run_backtest, combinations)
|
||||
|
||||
best_value = 0
|
||||
best_parameters = None
|
||||
|
||||
for value, params in results:
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_parameters = params
|
||||
print(
|
||||
f"combo: {params}, value: {value}, best_value: {best_value}, best_parameters: {best_parameters}"
|
||||
)
|
||||
|
||||
print(
|
||||
f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%"
|
||||
)
|
||||
print(f"最大市值: {best_value}")
|
||||
|
||||
# trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta
|
||||
# IM
|
||||
# 5M:(0.01, 0.02, 2, 700000, 500000)
|
||||
# 1M:(0.005, 0.02, 3, 100000, 200000)
|
||||
# IF
|
||||
# 5M:(0.005, 0.02, 1, 100000, 400000)
|
||||
@@ -0,0 +1,553 @@
|
||||
"""
|
||||
以下是代码的详细说明:
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
1.
|
||||
导入必要的模块和库:
|
||||
backtrader 用于回测功能
|
||||
datetime 用于处理日期和时间
|
||||
GenericCSVData 用于从CSV文件加载数据
|
||||
numpy 用于数值操作
|
||||
time 用于时间相关操作
|
||||
matplotlib.pyplot 用于绘图
|
||||
|
||||
2. 定义自定义手续费模板MyCommission
|
||||
继承自bt.CommInfoBase
|
||||
|
||||
3.
|
||||
定义自定义数据源类 GenericCSV_SIG:
|
||||
继承自 GenericCSVData,并添加了两个额外的行:'sig'和'delta'
|
||||
定义了参数 'sig'和'delta'
|
||||
|
||||
4.
|
||||
定义 MyStrategy_固定止损_跟踪止盈 类:
|
||||
继承自 bt.Strategy(backtrader的基础策略类)
|
||||
定义了两个参数:trailing_stop_percent 和 fixed_stop_loss_percent
|
||||
初始化策略并设置各种变量和指标
|
||||
实现了 next 方法,该方法在数据源的每个新的K线出现时被调用
|
||||
根据当前K线数据更新跟踪止盈价格
|
||||
实现了跟踪止盈出场和固定止损出场
|
||||
根据信号处理多头和空头仓位
|
||||
在策略执行过程中打印调试信息
|
||||
|
||||
5.
|
||||
if __name__ == "__main__": 代码块:
|
||||
使用 Cerebro 实例设置回测环境
|
||||
使用 GenericCSV_SIG 数据源从CSV文件加载数据
|
||||
将数据源和策略添加到 Cerebro 实例中
|
||||
添加观察者和分析器以评估性能
|
||||
设置初始资金和经纪人参数
|
||||
运行回测并获取结果
|
||||
打印回测报告,包括收益率、回撤、胜率和交易统计数据
|
||||
|
||||
6.使用前事项:
|
||||
1、主程序中修改ofdata_dj文件地址、png_filepath地址
|
||||
2、修改clearing_time2_start、clearing_time2_stop
|
||||
3、修改交易参数:lots、跟踪止损百分、固定止损百分比、duiji、cout_delta、delta
|
||||
4、修改资金参数:初始资金;回测参数:回测时间段、佣金、单边保证金、手续费;
|
||||
"""
|
||||
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
import os
|
||||
|
||||
import talib as tb # jerom注释: 增加talib库
|
||||
|
||||
# import time
|
||||
# import matplotlib.pyplot as plt
|
||||
|
||||
手续费汇总 = 0
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
# 从基类继承,添加一个 'sig',‘delta’行
|
||||
lines = ("sig", "delta")
|
||||
# 添加参数为从基类继承的参数
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.005), # 跟踪止盈百分比
|
||||
("fixed_stop_loss_percent", 0.02), # 固定止损百分比
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1 # 下单手数
|
||||
|
||||
self.signal = self.datas[0].sig # 使用sig字段作为策略的信号字段
|
||||
self.delta = self.datas[0].delta
|
||||
# 获取数据序列别名列表
|
||||
line_aliases = self.datas[0].getlinealiases()
|
||||
self.pos = 0
|
||||
print(line_aliases)
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
# 240884432
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.renei_open_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.reniei_bop = []
|
||||
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
|
||||
self.barN = 0
|
||||
self.df = pd.DataFrame(columns=["datetime", "high", "low", "close", "open", "delta", "delta_cumsum"])
|
||||
|
||||
self.trader_df = pd.DataFrame(columns=["open", "high", "low", "close", "volume", "openInterest", "delta"])
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
"""可选,构建策略打印日志的函数:可用于打印订单记录或交易记录等"""
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def notify_order(self, order):
|
||||
# 未被处理的订单
|
||||
if order.status in [order.Submitted, order.Accepted]:
|
||||
return
|
||||
# 已经处理的订单
|
||||
if order.status in [order.Completed, order.Canceled, order.Margin]:
|
||||
global 手续费汇总
|
||||
if order.isbuy():
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"BUY EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref, # 订单编号
|
||||
order.executed.price, # 成交价
|
||||
order.executed.comm, # 佣金
|
||||
order.executed.size, # 成交量
|
||||
order.data._name, # 品种名称
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
else: # Sell
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"SELL EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref,
|
||||
order.executed.price,
|
||||
order.executed.comm,
|
||||
order.executed.size,
|
||||
order.data._name,
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
def next(self):
|
||||
# 公众号:松鼠Quant
|
||||
# 主页:www.quant789.com
|
||||
# 本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
# 版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
# bar线计数初始化
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
# 时间轴
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
# 更新跟踪止损价格
|
||||
def 每日重置数据():
|
||||
# 获取当前时间
|
||||
current_time = dt.time()
|
||||
# print(current_time)
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
|
||||
# 创建一个标志变量
|
||||
clearing_executed = False
|
||||
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.renei_open_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.renei_open_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
# 如果不在任何时间范围内,可以执行其他操作
|
||||
else:
|
||||
self.renei_open_ma.append(self.open[0])
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.renei_high_ma.append(self.high[0])
|
||||
self.renei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.reniei_bop = tb.BOP(
|
||||
np.array(self.renei_open_ma),
|
||||
np.array(self.renei_high_ma),
|
||||
np.array(self.renei_low_ma),
|
||||
np.array(self.rinei_ma),
|
||||
)
|
||||
# self.delta_cumsum=[]
|
||||
# self.deltas_list=[]
|
||||
# print('rinei_ma',self.rinei_ma)
|
||||
clearing_executed = False
|
||||
pass
|
||||
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
# 过滤成交量为0或小于0
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
# print(f'volume,{self.data.volume[0]}')
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
# print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = (
|
||||
self.low[0] if self.long_trailing_stop_price < self.low[0] else self.long_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
# print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = (
|
||||
self.high[0] if self.high[0] < self.short_trailing_stop_price else self.short_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
# print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
# print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long > 0:
|
||||
if (
|
||||
self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
print(
|
||||
"--多头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position",
|
||||
"TR",
|
||||
self.out_long,
|
||||
"low",
|
||||
self.low[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if self.out_short > 0:
|
||||
if (
|
||||
self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
print(
|
||||
"--空头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position: ",
|
||||
"TR",
|
||||
self.out_short,
|
||||
"high",
|
||||
self.high[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_shor = 0
|
||||
self.pos = 0
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
print(
|
||||
"--多头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_L,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
print(
|
||||
"--空头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_S,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
# 更新最高价和最低价的列表
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
# 计算delta累计
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
# 将当前行数据添加到 DataFrame
|
||||
# new_row = {
|
||||
# 'datetime': dt,
|
||||
# 'high': self.data.high[0],
|
||||
# 'low': self.data.low[0],
|
||||
# 'close': self.data.close[0],
|
||||
# 'open': self.data.open[0],
|
||||
# 'delta': self.data.delta[0],
|
||||
# 'delta_cumsum': sum(self.deltas_list)
|
||||
# }
|
||||
# # 使用pandas.concat代替append
|
||||
# self.df = pd.concat([self.df, pd.DataFrame([new_row])], ignore_index=True)
|
||||
|
||||
# # 检查文件是否存在
|
||||
# csv_file_path = f"output.csv"
|
||||
# if os.path.exists(csv_file_path):
|
||||
# # 仅保存最后一行数据
|
||||
# self.df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
# else:
|
||||
# # 创建新文件并保存整个DataFrame
|
||||
# self.df.to_csv(csv_file_path, index=False)
|
||||
|
||||
#
|
||||
if run_kg is False: #
|
||||
# ————jerome注释:增加Boll指标测试
|
||||
upper, middle, lower = tb.BBANDS(np.array(self.deltas_list), timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
|
||||
upper_cum, middle_cum, lower_cum = tb.BBANDS(
|
||||
np.array(self.delta_cumsum), timeperiod=20, nbdevup=2, nbdevdn=2, matype=0
|
||||
)
|
||||
# 增加PPO指标测试
|
||||
# ppo = tb.PPO(np.array(self.deltas_list))
|
||||
# PPO_cum = tb.PPO(np.array(self.delta_cumsum))
|
||||
# 增加MOM指标测试
|
||||
# mom = tb.MOM(np.array(self.deltas_list), 30)
|
||||
# mom_cum = tb.MOM(np.array(self.delta_cumsum), 30)
|
||||
# 增加 MACDFIX指标测试
|
||||
# macdfix = tb.MACDFIX(np.array(self.deltas_list), 9)
|
||||
# macdfix_cum = tb.MACDFIX(np.array(self.delta_cumsum), 9)
|
||||
# 增加 CMO指标测试
|
||||
# cmo = tb.CMO(np.array(self.deltas_list))
|
||||
# cmo_cum = tb.CMO(np.array(self.delta_cumsum))
|
||||
# 增加 APO指标测试
|
||||
# apo = tb.APO(np.array(self.deltas_list))
|
||||
# apo_cum = tb.APO(np.array(self.delta_cumsum))
|
||||
# 增加 WMA指标测试
|
||||
# wma = tb.WMA(np.array(self.deltas_list))
|
||||
# wma_cum = tb.WMA(np.array(self.delta_cumsum))
|
||||
# 增加 WMA指标测试
|
||||
# ema = tb.EMA(np.array(self.deltas_list))
|
||||
# ema_cum = tb.EMA(np.array(self.delta_cumsum))
|
||||
# 增加 T3指标测试(效果非常好)
|
||||
# t3 = tb.T3(np.array(self.deltas_list))
|
||||
# t3_cum = tb.T3(np.array(self.delta_cumsum))
|
||||
# ————jerome注释:增加Boll函数测试
|
||||
# jerome注释:self.signal[0] >1 1为堆积信号
|
||||
# 开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] >1 and self.data.delta[0]>middle[-1] and self.delta_cumsum[-1]>middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]>0 and self.delta_cumsum[-1]>2000
|
||||
# 开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-1 and self.data.delta[0]<middle[-1] and self.delta_cumsum[-1]<middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]<-0 and self.delta_cumsum[-1]<-2000
|
||||
开多组合 = (
|
||||
self.reniei_bop[-1] > 0
|
||||
and self.signal[0] > 2
|
||||
and self.data.delta[0] > max(self.deltas_list[-30:-1], default=0) # 1.1 * middle[-1]
|
||||
and self.delta_cumsum[-1] > max(self.delta_cumsum[-31:-2], default=0) # 1.1 * middle_cum[-1]
|
||||
# and apo[-1] > 10
|
||||
# and apo_cum[-1] > 10
|
||||
)
|
||||
开空组合 = (
|
||||
self.reniei_bop[-1] < 0
|
||||
and self.signal[0] < -2
|
||||
and self.data.delta[0] < min(self.deltas_list[-30:-1], default=0) # 0.9 * middle[-1]
|
||||
and self.delta_cumsum[-1] < min(self.delta_cumsum[-31:-2], default=0) # 0.9 * middle_cum[-1]
|
||||
# and apo[-1] < -10
|
||||
# and apo_cum[-1] < -10
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > 2
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -2
|
||||
if self.pos != 1: #
|
||||
if 平多条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合: #
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存多头价格: ',self.long_trailing_stop_price)
|
||||
|
||||
if self.pos != -1: #
|
||||
if 平空条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合: #
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存空头价格: ',self.short_trailing_stop_price)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 公众号:松鼠Quant
|
||||
# 主页:www.quant789.com
|
||||
# 本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
# 版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
# 创建Cerebro实例
|
||||
|
||||
cerebro = bt.Cerebro()
|
||||
# 数据
|
||||
csv_file = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IF888\IF888_rs_2022_5T_back_ofdata_dj.csv" #
|
||||
png_filepath = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IF888\部分回测报告"
|
||||
# 从CSV文件加载数据
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2022, 1, 1),
|
||||
todate=datetime(2022, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
|
||||
# 添加数据到Cerebro实例
|
||||
cerebro.adddata(data)
|
||||
|
||||
# 添加策略到Cerebro实例
|
||||
cerebro.addstrategy(MyStrategy_固定止损_跟踪止盈)
|
||||
|
||||
# 添加观察者和分析器到Cerebro实例
|
||||
# cerebro.addobserver(bt.observers.BuySell)
|
||||
cerebro.addobserver(bt.observers.Value)
|
||||
cerebro.addanalyzer(bt.analyzers.Returns, _name="returns")
|
||||
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
|
||||
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trades")
|
||||
# cerebro.addanalyzer(bt.analyzers.sharpe, __name_= "sharpe")
|
||||
初始资金 = 300000
|
||||
cerebro.broker.setcash(初始资金) # 设置初始资金
|
||||
|
||||
# 手续费,单手保证金,合约倍数
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300) # 回测参数
|
||||
|
||||
# 运行回测
|
||||
result = cerebro.run()
|
||||
|
||||
# 获取策略分析器中的结果
|
||||
analyzer = result[0].analyzers
|
||||
total_trades = analyzer.trades.get_analysis()["total"]["total"]
|
||||
winning_trades = analyzer.trades.get_analysis()["won"]["total"]
|
||||
# 获取TradeAnalyzer分析器的结果
|
||||
trade_analyzer_result = analyzer.trades.get_analysis()
|
||||
# 获取总收益额
|
||||
total_profit = trade_analyzer_result.pnl.net.total
|
||||
|
||||
if total_trades > 0:
|
||||
win_rate = winning_trades / total_trades
|
||||
else:
|
||||
win_rate = 0.0
|
||||
# 打印回测报告
|
||||
print("回测报告:")
|
||||
print("期初权益", 初始资金)
|
||||
print("期末权益", 初始资金 + round(total_profit))
|
||||
print("盈亏额", round(total_profit))
|
||||
print("最大回撤率,", round(analyzer.drawdown.get_analysis()["drawdown"], 2), "%")
|
||||
print("胜率,", round(win_rate * 100, 2), "%")
|
||||
print("交易次数,", total_trades)
|
||||
print("盈利次数,", winning_trades)
|
||||
print("亏损次数,", total_trades - winning_trades)
|
||||
print("总手续费+滑点,", 手续费汇总)
|
||||
手续费汇总 = 0
|
||||
|
||||
# 保存回测图像文件
|
||||
plot = cerebro.plot()[0][0]
|
||||
plot_filename = os.path.splitext(os.path.basename(csv_file))[0] + "ss" + "_plot.png"
|
||||
# plot_path = os.path.join('部分回测报告', plot_filename)
|
||||
if not os.path.exists(png_filepath):
|
||||
# os.mkdir(png_filepath)
|
||||
os.makedirs(png_filepath)
|
||||
plot_path = os.path.join(png_filepath, plot_filename)
|
||||
plot.savefig(plot_path)
|
||||
|
||||
|
||||
# 公众号:松鼠Quant
|
||||
# 主页:www.quant789.com
|
||||
# 本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
@@ -0,0 +1,514 @@
|
||||
"""
|
||||
以下是代码的详细说明:
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
1.
|
||||
导入必要的模块和库:
|
||||
backtrader 用于回测功能
|
||||
datetime 用于处理日期和时间
|
||||
GenericCSVData 用于从CSV文件加载数据
|
||||
numpy 用于数值操作
|
||||
time 用于时间相关操作
|
||||
matplotlib.pyplot 用于绘图
|
||||
|
||||
2. 定义自定义手续费模板MyCommission
|
||||
继承自bt.CommInfoBase
|
||||
|
||||
3.
|
||||
定义自定义数据源类 GenericCSV_SIG:
|
||||
继承自 GenericCSVData,并添加了两个额外的行:'sig'和'delta'
|
||||
定义了参数 'sig'和'delta'
|
||||
|
||||
4.
|
||||
定义 MyStrategy_固定止损_跟踪止盈 类:
|
||||
继承自 bt.Strategy(backtrader的基础策略类)
|
||||
定义了两个参数:trailing_stop_percent 和 fixed_stop_loss_percent
|
||||
初始化策略并设置各种变量和指标
|
||||
实现了 next 方法,该方法在数据源的每个新的K线出现时被调用
|
||||
根据当前K线数据更新跟踪止盈价格
|
||||
实现了跟踪止盈出场和固定止损出场
|
||||
根据信号处理多头和空头仓位
|
||||
在策略执行过程中打印调试信息
|
||||
|
||||
5.
|
||||
if __name__ == "__main__": 代码块:
|
||||
使用 Cerebro 实例设置回测环境
|
||||
使用 GenericCSV_SIG 数据源从CSV文件加载数据
|
||||
将数据源和策略添加到 Cerebro 实例中
|
||||
添加观察者和分析器以评估性能
|
||||
设置初始资金和经纪人参数
|
||||
运行回测并获取结果
|
||||
打印回测报告,包括收益率、回撤、胜率和交易统计数据
|
||||
|
||||
6.使用前事项:
|
||||
1、主程序中修改ofdata_dj文件地址、png_filepath地址
|
||||
2、修改clearing_time2_start、clearing_time2_stop
|
||||
3、修改交易参数:lots、跟踪止损百分、固定止损百分比、duiji、cout_delta、delta
|
||||
4、修改资金参数:初始资金;回测参数:回测时间段、佣金、单边保证金、手续费;
|
||||
"""
|
||||
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import os
|
||||
|
||||
import talib as tb # jerom注释: 增加talib库
|
||||
|
||||
手续费汇总 = 0
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
# 从基类继承,添加一个 'sig',‘delta’行
|
||||
lines = ("sig", "delta")
|
||||
# 添加参数为从基类继承的参数
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.010), # 跟踪止盈百分比
|
||||
("fixed_stop_loss_percent", 0.02), # 固定止损百分比
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1 # 下单手数
|
||||
|
||||
self.signal = self.datas[0].sig # 使用sig字段作为策略的信号字段
|
||||
self.delta = self.datas[0].delta
|
||||
# 获取数据序列别名列表
|
||||
line_aliases = self.datas[0].getlinealiases()
|
||||
self.pos = 0
|
||||
print(line_aliases)
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
# 240884432
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.reniei_sar = []
|
||||
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
|
||||
self.barN = 0
|
||||
self.df = pd.DataFrame(columns=["datetime", "high", "low", "close", "open", "delta", "delta_cumsum"])
|
||||
|
||||
self.trader_df = pd.DataFrame(columns=["open", "high", "low", "close", "volume", "openInterest", "delta"])
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
"""可选,构建策略打印日志的函数:可用于打印订单记录或交易记录等"""
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def notify_order(self, order):
|
||||
# 未被处理的订单
|
||||
if order.status in [order.Submitted, order.Accepted]:
|
||||
return
|
||||
# 已经处理的订单
|
||||
if order.status in [order.Completed, order.Canceled, order.Margin]:
|
||||
global 手续费汇总
|
||||
if order.isbuy():
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"BUY EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref, # 订单编号
|
||||
order.executed.price, # 成交价
|
||||
order.executed.comm, # 佣金
|
||||
order.executed.size, # 成交量
|
||||
order.data._name, # 品种名称
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
else: # Sell
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"SELL EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref,
|
||||
order.executed.price,
|
||||
order.executed.comm,
|
||||
order.executed.size,
|
||||
order.data._name,
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
def next(self):
|
||||
# 公众号:松鼠Quant
|
||||
# 主页:www.quant789.com
|
||||
# 本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
# 版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
# bar线计数初始化
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
# 时间轴
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
# 更新跟踪止损价格
|
||||
def 每日重置数据():
|
||||
# 获取当前时间
|
||||
current_time = dt.time()
|
||||
# print(current_time)
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
|
||||
# 创建一个标志变量
|
||||
clearing_executed = False
|
||||
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
# 如果不在任何时间范围内,可以执行其他操作
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.renei_high_ma.append(self.high[0])
|
||||
self.renei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.reniei_sar = tb.SAR(np.array(self.renei_high_ma), np.array(self.renei_low_ma), 0.02, 0.2)
|
||||
# self.delta_cumsum=[]
|
||||
# self.deltas_list=[]
|
||||
# print('rinei_ma',self.rinei_ma)
|
||||
clearing_executed = False
|
||||
pass
|
||||
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
# 过滤成交量为0或小于0
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
# print(f'volume,{self.data.volume[0]}')
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
# print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = (
|
||||
self.low[0] if self.long_trailing_stop_price < self.low[0] else self.long_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
# print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = (
|
||||
self.high[0] if self.high[0] < self.short_trailing_stop_price else self.short_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
# print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
# print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long > 0:
|
||||
if (
|
||||
self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
print(
|
||||
"--多头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position",
|
||||
"TR",
|
||||
self.out_long,
|
||||
"low",
|
||||
self.low[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if self.out_short > 0:
|
||||
if (
|
||||
self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
print(
|
||||
"--空头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position: ",
|
||||
"TR",
|
||||
self.out_short,
|
||||
"high",
|
||||
self.high[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_shor = 0
|
||||
self.pos = 0
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
print(
|
||||
"--多头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_L,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
print(
|
||||
"--空头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_S,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
# 更新最高价和最低价的列表
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
# 计算delta累计
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
# 将当前行数据添加到 DataFrame
|
||||
# new_row = {
|
||||
# 'datetime': dt,
|
||||
# 'high': self.data.high[0],
|
||||
# 'low': self.data.low[0],
|
||||
# 'close': self.data.close[0],
|
||||
# 'open': self.data.open[0],
|
||||
# 'delta': self.data.delta[0],
|
||||
# 'delta_cumsum': sum(self.deltas_list)
|
||||
# }
|
||||
# # 使用pandas.concat代替append
|
||||
# self.df = pd.concat([self.df, pd.DataFrame([new_row])], ignore_index=True)
|
||||
|
||||
# # 检查文件是否存在
|
||||
# csv_file_path = f"output.csv"
|
||||
# if os.path.exists(csv_file_path):
|
||||
# # 仅保存最后一行数据
|
||||
# self.df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
# else:
|
||||
# # 创建新文件并保存整个DataFrame
|
||||
# self.df.to_csv(csv_file_path, index=False)
|
||||
|
||||
#
|
||||
if run_kg == False: #
|
||||
# ————jerome注释:增加Boll函数测试
|
||||
upper, middle, lower = tb.BBANDS(np.array(self.deltas_list), timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
|
||||
upper_cum, middle_cum, lower_cum = tb.BBANDS(
|
||||
np.array(self.delta_cumsum), timeperiod=5, nbdevup=2, nbdevdn=2, matype=0
|
||||
)
|
||||
# ————jerome注释:增加Boll函数测试
|
||||
# jerome注释:self.signal[0] >1 1为堆积信号
|
||||
# 开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] >1 and self.data.delta[0]>middle[-1] and self.delta_cumsum[-1]>middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]>0 and self.delta_cumsum[-1]>2000
|
||||
# 开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-1 and self.data.delta[0]<middle[-1] and self.delta_cumsum[-1]<middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]<-0 and self.delta_cumsum[-1]<-2000
|
||||
开多组合 = (
|
||||
self.reniei_sar[-1] > self.closes[0]
|
||||
and self.signal[0] > 3
|
||||
and self.data.delta[0] > 700000
|
||||
and self.delta_cumsum[-1] > 700000
|
||||
)
|
||||
开空组合 = (
|
||||
self.reniei_sar[-1] < self.closes[0]
|
||||
and self.signal[0] < -3
|
||||
and self.data.delta[0] < -700000
|
||||
and self.delta_cumsum[-1] < -700000
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > 3
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -3
|
||||
if self.pos != 1: #
|
||||
if 平多条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合: #
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存多头价格: ',self.long_trailing_stop_price)
|
||||
|
||||
if self.pos != -1: #
|
||||
if 平空条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合: #
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存空头价格: ',self.short_trailing_stop_price)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 公众号:松鼠Quant
|
||||
# 主页:www.quant789.com
|
||||
# 本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
# 版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
# 创建Cerebro实例
|
||||
|
||||
cerebro = bt.Cerebro()
|
||||
# 数据
|
||||
csv_file = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IM888\IM888_rs_2022_5T_back_ofdata_dj.csv" #
|
||||
png_filepath = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IM888\部分回测报告"
|
||||
# 从CSV文件加载数据
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2022, 1, 1),
|
||||
todate=datetime(2022, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
|
||||
# 添加数据到Cerebro实例
|
||||
cerebro.adddata(data)
|
||||
|
||||
# 添加策略到Cerebro实例
|
||||
cerebro.addstrategy(MyStrategy_固定止损_跟踪止盈)
|
||||
|
||||
# 添加观察者和分析器到Cerebro实例
|
||||
# cerebro.addobserver(bt.observers.BuySell)
|
||||
cerebro.addobserver(bt.observers.Value)
|
||||
cerebro.addanalyzer(bt.analyzers.Returns, _name="returns")
|
||||
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
|
||||
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trades")
|
||||
# cerebro.addanalyzer(bt.analyzers.sharpe, __name_= "sharpe")
|
||||
初始资金 = 300000
|
||||
cerebro.broker.setcash(初始资金) # 设置初始资金
|
||||
|
||||
# 手续费,单手保证金,合约倍数
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300) # 回测参数
|
||||
|
||||
# 运行回测
|
||||
result = cerebro.run()
|
||||
|
||||
# 获取策略分析器中的结果
|
||||
analyzer = result[0].analyzers
|
||||
total_trades = analyzer.trades.get_analysis()["total"]["total"]
|
||||
winning_trades = analyzer.trades.get_analysis()["won"]["total"]
|
||||
# 获取TradeAnalyzer分析器的结果
|
||||
trade_analyzer_result = analyzer.trades.get_analysis()
|
||||
# 获取总收益额
|
||||
total_profit = trade_analyzer_result.pnl.net.total
|
||||
|
||||
if total_trades > 0:
|
||||
win_rate = winning_trades / total_trades
|
||||
else:
|
||||
win_rate = 0.0
|
||||
# 打印回测报告
|
||||
print("回测报告:")
|
||||
print("期初权益", 初始资金)
|
||||
print("期末权益", 初始资金 + round(total_profit))
|
||||
print("盈亏额", round(total_profit))
|
||||
print("最大回撤率,", round(analyzer.drawdown.get_analysis()["drawdown"], 2), "%")
|
||||
print("胜率,", round(win_rate * 100, 2), "%")
|
||||
print("交易次数,", total_trades)
|
||||
print("盈利次数,", winning_trades)
|
||||
print("亏损次数,", total_trades - winning_trades)
|
||||
print("总手续费+滑点,", 手续费汇总)
|
||||
手续费汇总 = 0
|
||||
|
||||
# 保存回测图像文件
|
||||
plot = cerebro.plot()[0][0]
|
||||
plot_filename = os.path.splitext(os.path.basename(csv_file))[0] + "ss" + "_plot.png"
|
||||
# plot_path = os.path.join('部分回测报告', plot_filename)
|
||||
if not os.path.exists(png_filepath):
|
||||
# os.mkdir(png_filepath)
|
||||
os.makedirs(png_filepath)
|
||||
plot_path = os.path.join(png_filepath, plot_filename)
|
||||
plot.savefig(plot_path)
|
||||
|
||||
|
||||
# 公众号:松鼠Quant
|
||||
# 主页:www.quant789.com
|
||||
# 本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
@@ -0,0 +1,679 @@
|
||||
"""
|
||||
以下是代码的详细说明:
|
||||
1.
|
||||
导入必要的模块和库:
|
||||
backtrader 用于回测功能
|
||||
datetime 用于处理日期和时间
|
||||
GenericCSVData 用于从CSV文件加载数据
|
||||
numpy 用于数值操作
|
||||
time 用于时间相关操作
|
||||
matplotlib.pyplot 用于绘图
|
||||
|
||||
2. 定义自定义手续费模板MyCommission
|
||||
继承自bt.CommInfoBase
|
||||
|
||||
3.
|
||||
定义自定义数据源类 GenericCSV_SIG:
|
||||
继承自 GenericCSVData,并添加了两个额外的行:'sig'和'delta'
|
||||
定义了参数 'sig'和'delta'
|
||||
|
||||
4.
|
||||
定义 MyStrategy_固定止损_跟踪止盈 类:
|
||||
继承自 bt.Strategy(backtrader的基础策略类)
|
||||
定义了两个参数:trailing_stop_percent 和 fixed_stop_loss_percent
|
||||
初始化策略并设置各种变量和指标
|
||||
实现了 next 方法,该方法在数据源的每个新的K线出现时被调用
|
||||
根据当前K线数据更新跟踪止盈价格
|
||||
实现了跟踪止盈出场和固定止损出场
|
||||
根据信号处理多头和空头仓位
|
||||
在策略执行过程中打印调试信息
|
||||
|
||||
5.
|
||||
if __name__ == "__main__": 代码块:
|
||||
使用 Cerebro 实例设置回测环境
|
||||
使用 GenericCSV_SIG 数据源从CSV文件加载数据
|
||||
将数据源和策略添加到 Cerebro 实例中
|
||||
添加观察者和分析器以评估性能
|
||||
设置初始资金和经纪人参数
|
||||
运行回测并获取结果
|
||||
打印回测报告,包括收益率、回撤、胜率和交易统计数据
|
||||
|
||||
6.使用前事项:
|
||||
1、主程序中修改ofdata_dj文件地址、png_filepath地址
|
||||
2、修改clearing_time2_start、clearing_time2_stop
|
||||
3、修改交易参数:lots、跟踪止损百分、固定止损百分比、duiji、cout_delta、delta
|
||||
4、修改资金参数:初始资金;回测参数:回测时间段、佣金、单边保证金、手续费;
|
||||
"""
|
||||
|
||||
import backtrader as bt
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import os
|
||||
import matplotlib.pyplot as plt
|
||||
import talib as tb # jerom注释: 增加talib库
|
||||
|
||||
# import akshare as ak
|
||||
|
||||
# 下面是需要设置的参数.其他需要设置参数在函数中:每日重置数据时间、回测开始时间、结束时间、初始资金、手续费,单手保证金,合约倍数
|
||||
手续费汇总 = 0
|
||||
trailing_stop_value = 0.02
|
||||
fixed_stop_loss_value = 0.01
|
||||
deltas_windows = 240
|
||||
deltas_cum_windows = 240
|
||||
duji_value = 2
|
||||
csv_file_path = r"E:\of_data\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IM888\IM888_rs_2023_5T_back_ofdata_dj.csv"
|
||||
png_file_path = (
|
||||
r"E:\of_data\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IM888\部分回测报告"
|
||||
)
|
||||
start_date = datetime(2023, 1, 1)
|
||||
end_date = datetime(2023, 12, 31)
|
||||
回测资金 = 3000000
|
||||
单手手续费 = 60
|
||||
单手保证金 = 15000
|
||||
交易乘率 = 300
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
# 从基类继承,添加一个 'sig',‘delta’行
|
||||
lines = ("sig", "delta")
|
||||
# 添加参数为从基类继承的参数
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
# jerome注释增加
|
||||
def ultimate_smoother(price, period):
|
||||
# 初始化变量
|
||||
a1 = np.exp(-1.414 * np.pi / period)
|
||||
b1 = 2 * a1 * np.cos(1.414 * 180 / period)
|
||||
c2 = b1
|
||||
c3 = -a1 * a1
|
||||
c1 = (1 + c2 - c3) / 4
|
||||
|
||||
# 准备输出结果的序列
|
||||
us = np.zeros(len(price))
|
||||
|
||||
# 计算 Ultimate Smoother
|
||||
for i in range(len(price)):
|
||||
if i < 4:
|
||||
us[i] = price[i]
|
||||
else:
|
||||
us[i] = (
|
||||
(1 - c1) * price[i]
|
||||
+ (2 * c1 - c2) * price[i - 1]
|
||||
- (c1 + c3) * price[i - 2]
|
||||
+ c2 * us[i - 1]
|
||||
+ c3 * us[i - 2]
|
||||
)
|
||||
|
||||
return us
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", trailing_stop_value), # 跟踪止盈百分比
|
||||
("fixed_stop_loss_percent", fixed_stop_loss_value), # 固定止损百分比
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1 # 下单手数
|
||||
|
||||
self.signal = self.datas[0].sig # 使用sig字段作为策略的信号字段
|
||||
self.delta = self.datas[0].delta
|
||||
# 获取数据序列别名列表
|
||||
line_aliases = self.datas[0].getlinealiases()
|
||||
self.pos = 0
|
||||
print(line_aliases)
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
|
||||
self.ultimate_smoother_value = []
|
||||
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.rinei_open_ma = []
|
||||
self.rinei_high_ma = []
|
||||
self.rinei_low_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.rinei_T3 = []
|
||||
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
self.duiji_list = []
|
||||
|
||||
self.barN = 0
|
||||
self.df = pd.DataFrame(
|
||||
columns=[
|
||||
"datetime",
|
||||
"high",
|
||||
"low",
|
||||
"close",
|
||||
"open",
|
||||
"delta",
|
||||
"delta_cumsum",
|
||||
]
|
||||
)
|
||||
|
||||
self.trader_df = pd.DataFrame(
|
||||
columns=["open", "high", "low", "close", "volume", "openInterest", "delta"]
|
||||
)
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
"""可选,构建策略打印日志的函数:可用于打印订单记录或交易记录等"""
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def notify_order(self, order):
|
||||
# 未被处理的订单
|
||||
if order.status in [order.Submitted, order.Accepted]:
|
||||
return
|
||||
# 已经处理的订单
|
||||
if order.status in [order.Completed, order.Canceled, order.Margin]:
|
||||
global 手续费汇总
|
||||
if order.isbuy():
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"BUY EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref, # 订单编号
|
||||
order.executed.price, # 成交价
|
||||
order.executed.comm, # 佣金
|
||||
order.executed.size, # 成交量
|
||||
order.data._name, # 品种名称
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
else: # Sell
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"SELL EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref,
|
||||
order.executed.price,
|
||||
order.executed.comm,
|
||||
order.executed.size,
|
||||
order.data._name,
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
def next(self):
|
||||
# bar线计数初始化
|
||||
self.barN += 1
|
||||
# position = self.getposition(self.datas[0]).size
|
||||
# 时间轴
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
# 更新跟踪止损价格
|
||||
def 每日重置数据():
|
||||
# 获取当前时间
|
||||
current_time = dt.time()
|
||||
# print(current_time)
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
|
||||
# 创建一个标志变量
|
||||
clearing_executed = False
|
||||
|
||||
if (
|
||||
clearing_time1_start <= current_time <= clearing_time1_end
|
||||
and not clearing_executed
|
||||
):
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.rinei_open_ma = []
|
||||
self.rinei_high_ma = []
|
||||
self.rinei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
self.duiji_list = []
|
||||
elif (
|
||||
clearing_time2_start <= current_time <= clearing_time2_end
|
||||
and not clearing_executed
|
||||
):
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.rinei_open_ma = []
|
||||
self.rinei_high_ma = []
|
||||
self.rinei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
self.duiji_list = []
|
||||
# 如果不在任何时间范围内,可以执行其他操作
|
||||
else:
|
||||
self.rinei_open_ma.append(self.open[0])
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.rinei_high_ma.append(self.high[0])
|
||||
self.rinei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
# self.rinei_T3 = tb.HT_TRENDLINE(np.array(self.rinei_ma),timeperiod=5)
|
||||
self.rinei_T3 = tb.T3(
|
||||
np.array(self.rinei_ma), 3
|
||||
) # , timeperiod=5, vfactor=0.7
|
||||
# self.riniei_bop = tb.BOP(
|
||||
# np.array(self.rinei_open_ma),
|
||||
# np.array(self.rinei_high_ma),
|
||||
# np.array(self.rinei_low_ma),
|
||||
# np.array(self.rinei_ma),
|
||||
# )
|
||||
# self.delta_cumsum=[]
|
||||
# self.deltas_list=[]
|
||||
# print('rinei_ma',self.rinei_ma)
|
||||
clearing_executed = False
|
||||
pass
|
||||
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
# 过滤成交量为0或小于0
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
# print(f'volume,{self.data.volume[0]}')
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
# print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = (
|
||||
self.low[0]
|
||||
if self.long_trailing_stop_price < self.low[0]
|
||||
else self.long_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
# print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = (
|
||||
self.high[0]
|
||||
if self.high[0] < self.short_trailing_stop_price
|
||||
else self.short_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
# self.out_long = self.long_trailing_stop_price * (
|
||||
# 1 - self.trailing_stop_percent)
|
||||
# self.out_short = self.short_trailing_stop_price * (
|
||||
# 1 + self.trailing_stop_percent)
|
||||
self.ultimate_smoother_value = ultimate_smoother(self.closes, 20)
|
||||
self.out_long = self.ultimate_smoother_value[-1]
|
||||
self.out_short = self.ultimate_smoother_value[-1]
|
||||
# print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
# print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long > 0:
|
||||
if (
|
||||
self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
print(
|
||||
"--多头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position",
|
||||
"TR",
|
||||
self.out_long,
|
||||
"low",
|
||||
self.low[0],
|
||||
)
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=self.Lots,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if self.out_short > 0:
|
||||
if (
|
||||
self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
print(
|
||||
"--空头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position: ",
|
||||
"TR",
|
||||
self.out_short,
|
||||
"high",
|
||||
self.high[0],
|
||||
)
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=self.Lots,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_shor = 0
|
||||
self.pos = 0
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
print(
|
||||
"--多头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_L,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=self.Lots,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
print(
|
||||
"--空头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_S,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=self.Lots,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
# 更新最高价和最低价的列表
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
# 计算delta累计
|
||||
self.delta_cumsum.append(sum(self.deltas_list[-20:]))
|
||||
self.duiji_list.append(self.data.sig[0])
|
||||
|
||||
# 将当前行数据添加到 DataFrame
|
||||
# new_row = {
|
||||
# 'datetime': dt,
|
||||
# 'high': self.data.high[0],
|
||||
# 'low': self.data.low[0],
|
||||
# 'close': self.data.close[0],
|
||||
# 'open': self.data.open[0],
|
||||
# 'delta': self.data.delta[0],
|
||||
# 'delta_cumsum': sum(self.deltas_list)
|
||||
# }
|
||||
# # 使用pandas.concat代替append
|
||||
# self.df = pd.concat([self.df, pd.DataFrame([new_row])], ignore_index=True)
|
||||
|
||||
# # 检查文件是否存在
|
||||
# csv_file_path = f"output.csv"
|
||||
# if os.path.exists(csv_file_path):
|
||||
# # 仅保存最后一行数据
|
||||
# self.df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
# else:
|
||||
# # 创建新文件并保存整个DataFrame
|
||||
# self.df.to_csv(csv_file_path, index=False)
|
||||
|
||||
#
|
||||
if run_kg is False:
|
||||
# ————jerome注释:增加指标测试
|
||||
# 增加Boll指标测试
|
||||
# upper, middle, lower = tb.BBANDS(np.array(self.deltas_list), timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
|
||||
# upper_cum, middle_cum, lower_cum = tb.BBANDS(
|
||||
# np.array(self.delta_cumsum), timeperiod=20, nbdevup=2, nbdevdn=2, matype=0
|
||||
# )
|
||||
# 增加PPO指标测试
|
||||
# ppo = tb.PPO(np.array(self.deltas_list))
|
||||
# PPO_cum = tb.PPO(np.array(self.delta_cumsum))
|
||||
# 增加MOM指标测试
|
||||
# mom = tb.MOM(np.array(self.deltas_list), 30)
|
||||
# mom_cum = tb.MOM(np.array(self.delta_cumsum), 30)
|
||||
# 增加 MACDFIX指标测试
|
||||
# macdfix = tb.MACDFIX(np.array(self.deltas_list), 9)
|
||||
# macdfix_cum = tb.MACDFIX(np.array(self.delta_cumsum), 9)
|
||||
# 增加 CMO指标测试
|
||||
# cmo = tb.CMO(np.array(self.deltas_list))
|
||||
# cmo_cum = tb.CMO(np.array(self.delta_cumsum))
|
||||
# 增加 APO指标测试
|
||||
# apo = tb.APO(np.array(self.deltas_list))
|
||||
# apo_cum = tb.APO(np.array(self.delta_cumsum))
|
||||
# 增加 WMA指标测试
|
||||
# wma = tb.WMA(np.array(self.deltas_list))
|
||||
# wma_cum = tb.WMA(np.array(self.delta_cumsum))
|
||||
# 增加 WMA指标测试
|
||||
# ema = tb.EMA(np.array(self.deltas_list))
|
||||
# ema_cum = tb.EMA(np.array(self.delta_cumsum))
|
||||
# 增加 T3指标测试(效果非常好)
|
||||
t3 = tb.T3(np.array(self.deltas_list))
|
||||
t3_cum = tb.T3(np.array(self.delta_cumsum))
|
||||
# futures_main_sina_hist = ak.futures_main_sina(
|
||||
# symbol="IM0", start_date=start_date, end_date="20231231"
|
||||
# )
|
||||
# futures_main_sina_hist["5day_ma"] = (
|
||||
# futures_main_sina_hist["收盘价"].rolling(window=5).mean()
|
||||
# )
|
||||
# ——jerome注释:self.signal[0] >1 1为堆积信号
|
||||
# 开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] >1 and self.data.delta[0]>middle[-1] and self.delta_cumsum[-1]>middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]>0 and self.delta_cumsum[-1]>2000
|
||||
# 开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-1 and self.data.delta[0]<middle[-1] and self.delta_cumsum[-1]<middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]<-0 and self.delta_cumsum[-1]<-2000
|
||||
开多组合 = (
|
||||
self.closes[0] > self.rinei_T3[-1]
|
||||
# futures_main_sina_hist["收盘价"].iloc[0]
|
||||
# > futures_main_sina_hist["5day_ma"].iloc[-1]
|
||||
# self.riniei_bop[-1] > 0
|
||||
and self.signal[0]
|
||||
> max(self.duiji_list[-deltas_windows:-1], default=0) # duji_value
|
||||
and self.data.delta[0] > t3[-1] # max(
|
||||
# self.deltas_list[-deltas_windows:-1], default=0
|
||||
# ) # 1.1 * middle[-1]
|
||||
and self.delta_cumsum[-1] > t3_cum[-1] # max(
|
||||
# self.delta_cumsum[-deltas_cum_windows - 1 : -2], default=0
|
||||
# ) # 1.1 * middle_cum[-1]
|
||||
# and apo[-1] > 10
|
||||
# and apo_cum[-1] > 10
|
||||
)
|
||||
开空组合 = (
|
||||
self.closes[0] < self.rinei_T3[-1]
|
||||
# self.riniei_bop[-1] < 0
|
||||
# futures_main_sina_hist["收盘价"].iloc[0]
|
||||
# < futures_main_sina_hist["5day_ma"].iloc[-1]
|
||||
and self.signal[0]
|
||||
< min(self.duiji_list[-deltas_windows:-1], default=0) # -duji_value
|
||||
and self.data.delta[0] < t3[-1] # min(
|
||||
# self.deltas_list[-deltas_windows:-1], default=0
|
||||
# ) # 0.9 * middle[-1]
|
||||
and self.delta_cumsum[-1] < t3_cum[-1] # min(
|
||||
# self.delta_cumsum[-deltas_cum_windows - 1 : -2], default=0
|
||||
# ) # 0.9 * middle_cum[-1]
|
||||
# and apo[-1] < -10
|
||||
# and apo_cum[-1] < -10
|
||||
)
|
||||
平空条件 = self.pos < 0 and self.signal[0] > max(
|
||||
self.duiji_list[-deltas_windows:-1], default=0
|
||||
) # duji_value
|
||||
平多条件 = self.pos > 0 and self.signal[0] < min(
|
||||
self.duiji_list[-deltas_windows:-1], default=0
|
||||
) # -duji_value
|
||||
if self.pos != 1: #
|
||||
if 平空条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合: #
|
||||
self.buy(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=1,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存多头价格: ',self.long_trailing_stop_price)
|
||||
|
||||
if self.pos != -1: #
|
||||
if 平多条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合: #
|
||||
self.sell(
|
||||
data=self.data,
|
||||
price=self.data.close[0],
|
||||
size=1,
|
||||
exectype=bt.Order.Market,
|
||||
)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存空头价格: ',self.short_trailing_stop_price)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 创建Cerebro实例
|
||||
|
||||
cerebro = bt.Cerebro()
|
||||
# 数据
|
||||
csv_file = csv_file_path
|
||||
png_filepath = png_file_path
|
||||
# 从CSV文件加载数据
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=start_date, # datetime(2023, 1, 1),
|
||||
todate=end_date, # datetime(2023, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
|
||||
# 添加数据到Cerebro实例
|
||||
cerebro.adddata(data)
|
||||
|
||||
# 添加策略到Cerebro实例
|
||||
cerebro.addstrategy(MyStrategy_固定止损_跟踪止盈)
|
||||
|
||||
# 添加观察者和分析器到Cerebro实例
|
||||
# cerebro.addobserver(bt.observers.BuySell)
|
||||
cerebro.addobserver(bt.observers.Value)
|
||||
cerebro.addanalyzer(bt.analyzers.Returns, _name="returns")
|
||||
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
|
||||
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trades")
|
||||
# cerebro.addanalyzer(bt.analyzers.sharpe, __name_= "sharpe")
|
||||
初始资金 = 回测资金
|
||||
cerebro.broker.setcash(初始资金) # 设置初始资金
|
||||
|
||||
# 手续费,单手保证金,合约倍数
|
||||
cerebro.broker.setcommission(
|
||||
commission=单手手续费, margin=单手保证金, mult=交易乘率
|
||||
) # 回测参数
|
||||
|
||||
# 运行回测
|
||||
result = cerebro.run()
|
||||
|
||||
# 获取策略分析器中的结果
|
||||
analyzer = result[0].analyzers
|
||||
total_trades = analyzer.trades.get_analysis()["total"]["total"]
|
||||
winning_trades = analyzer.trades.get_analysis()["won"]["total"]
|
||||
# 获取TradeAnalyzer分析器的结果
|
||||
trade_analyzer_result = analyzer.trades.get_analysis()
|
||||
# 获取总收益额
|
||||
total_profit = trade_analyzer_result.pnl.net.total
|
||||
|
||||
if total_trades > 0:
|
||||
win_rate = winning_trades / total_trades
|
||||
else:
|
||||
win_rate = 0.0
|
||||
# 打印回测报告
|
||||
print("回测报告:")
|
||||
print("期初权益", 初始资金)
|
||||
print("期末权益", 初始资金 + round(total_profit))
|
||||
print("盈亏额", round(total_profit))
|
||||
print("最大回撤率,", round(analyzer.drawdown.get_analysis()["drawdown"], 2), "%")
|
||||
print("胜率,", round(win_rate * 100, 2), "%")
|
||||
print("交易次数,", total_trades)
|
||||
print("盈利次数,", winning_trades)
|
||||
print("亏损次数,", total_trades - winning_trades)
|
||||
print("总手续费+滑点,", 手续费汇总)
|
||||
手续费汇总 = 0
|
||||
|
||||
# 保存回测图像文件
|
||||
plot = cerebro.plot()[0][0]
|
||||
plot_filename = os.path.splitext(os.path.basename(csv_file))[0] + "ss" + "_plot.png"
|
||||
# plot_path = os.path.join('部分回测报告', plot_filename)
|
||||
if not os.path.exists(png_filepath):
|
||||
# os.mkdir(png_filepath)
|
||||
os.makedirs(png_filepath)
|
||||
plot_path = os.path.join(png_filepath, plot_filename)
|
||||
plot.savefig(plot_path)
|
||||
@@ -0,0 +1,406 @@
|
||||
'''
|
||||
以下是代码的详细说明:
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
1.
|
||||
导入必要的模块和库:
|
||||
backtrader 用于回测功能
|
||||
datetime 用于处理日期和时间
|
||||
GenericCSVData 用于从CSV文件加载数据
|
||||
numpy 用于数值操作
|
||||
time 用于时间相关操作
|
||||
matplotlib.pyplot 用于绘图
|
||||
|
||||
2. 定义自定义手续费模板MyCommission
|
||||
继承自bt.CommInfoBase
|
||||
|
||||
3.
|
||||
定义自定义数据源类 GenericCSV_SIG:
|
||||
继承自 GenericCSVData,并添加了两个额外的行:'sig'和'delta'
|
||||
定义了参数 'sig'和'delta'
|
||||
|
||||
4.
|
||||
定义 MyStrategy_固定止损_跟踪止盈 类:
|
||||
继承自 bt.Strategy(backtrader的基础策略类)
|
||||
定义了两个参数:trailing_stop_percent 和 fixed_stop_loss_percent
|
||||
初始化策略并设置各种变量和指标
|
||||
实现了 next 方法,该方法在数据源的每个新的K线出现时被调用
|
||||
根据当前K线数据更新跟踪止盈价格
|
||||
实现了跟踪止盈出场和固定止损出场
|
||||
根据信号处理多头和空头仓位
|
||||
在策略执行过程中打印调试信息
|
||||
|
||||
5.
|
||||
if __name__ == "__main__": 代码块:
|
||||
使用 Cerebro 实例设置回测环境
|
||||
使用 GenericCSV_SIG 数据源从CSV文件加载数据
|
||||
将数据源和策略添加到 Cerebro 实例中
|
||||
添加观察者和分析器以评估性能
|
||||
设置初始资金和经纪人参数
|
||||
运行回测并获取结果
|
||||
打印回测报告,包括收益率、回撤、胜率和交易统计数据
|
||||
使用 matplotlib 绘制回测结果
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
'''
|
||||
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import os
|
||||
import itertools
|
||||
from scipy.optimize import brute
|
||||
|
||||
|
||||
手续费汇总=0
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
# 从基类继承,添加一个 'sig',‘delta’行
|
||||
lines = ('sig','delta')
|
||||
# 添加参数为从基类继承的参数
|
||||
params = (('sig',6),('delta', 8))
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
('trailing_stop_percent', 0.02), # 跟踪止盈百分比
|
||||
('fixed_stop_loss_percent', 0.01), # 固定止损百分比
|
||||
('duiji', 1), # 堆积
|
||||
('cout_delta', 1), # 日累计delta
|
||||
('delta', 1), # delta单bar
|
||||
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots=1 #下单手数
|
||||
|
||||
self.signal = self.datas[0].sig # 使用sig字段作为策略的信号字段
|
||||
self.delta= self.datas[0].delta
|
||||
# 获取数据序列别名列表
|
||||
line_aliases = self.datas[0].getlinealiases()
|
||||
self.pos=0
|
||||
print(line_aliases)
|
||||
self.high=self.datas[0].high
|
||||
self.low=self.datas[0].low
|
||||
self.closes=self.datas[0].close
|
||||
self.open=self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price=0
|
||||
self.sl_shor_price=0
|
||||
self.out_long=0
|
||||
self.out_short=0
|
||||
self.rinei_ma=[]
|
||||
self.rinei_mean=0
|
||||
|
||||
self.datetime_list= []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum=[]
|
||||
|
||||
self.barN = 0
|
||||
self.df = pd.DataFrame(columns=['datetime', 'high', 'low', 'close', 'open', 'delta', 'delta_cumsum'])
|
||||
|
||||
self.trader_df=pd.DataFrame(columns=['open', 'high', 'low', 'close', 'volume', 'openInterest','delta'])
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
'''可选,构建策略打印日志的函数:可用于打印订单记录或交易记录等'''
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print('%s, %s' % (dt.isoformat(), txt))
|
||||
|
||||
# def notify_order(self, order):
|
||||
# # 未被处理的订单
|
||||
# if order.status in [order.Submitted, order.Accepted]:
|
||||
# return
|
||||
# # 已经处理的订单
|
||||
# if order.status in [order.Completed, order.Canceled, order.Margin]:
|
||||
# global 手续费汇总
|
||||
# if order.isbuy():
|
||||
# 手续费汇总 +=order.executed.comm
|
||||
# self.log(
|
||||
# 'BUY EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f' %
|
||||
# (order.ref, # 订单编号
|
||||
# order.executed.price, # 成交价
|
||||
# order.executed.comm, # 佣金
|
||||
# order.executed.size, # 成交量
|
||||
# order.data._name,# 品种名称
|
||||
# 手续费汇总))
|
||||
|
||||
# else: # Sell
|
||||
# 手续费汇总 +=order.executed.comm
|
||||
# self.log('SELL EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f' %
|
||||
# (order.ref,
|
||||
# order.executed.price,
|
||||
# order.executed.comm,
|
||||
# order.executed.size,
|
||||
# order.data._name,
|
||||
# 手续费汇总))
|
||||
|
||||
def next(self):
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
#bar线计数初始化
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
#时间轴
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
#更新跟踪止损价格
|
||||
def 每日重置数据():
|
||||
# 获取当前时间
|
||||
current_time = dt.time()
|
||||
#print(current_time)
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
|
||||
# 创建一个标志变量
|
||||
clearing_executed = False
|
||||
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed :
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma=[]
|
||||
self.delta_cumsum=[]
|
||||
self.deltas_list=[]
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed :
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma=[]
|
||||
self.delta_cumsum=[]
|
||||
self.deltas_list=[]
|
||||
# 如果不在任何时间范围内,可以执行其他操作
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
#self.delta_cumsum=[]
|
||||
#self.deltas_list=[]
|
||||
#print('rinei_ma',self.rinei_ma)
|
||||
clearing_executed = False
|
||||
pass
|
||||
|
||||
return clearing_executed
|
||||
|
||||
run_kg=每日重置数据()
|
||||
|
||||
#过滤成交量为0或小于0
|
||||
if self.data.volume[0] <= 0 :
|
||||
return
|
||||
#print(f'volume,{self.data.volume[0]}')
|
||||
if self.long_trailing_stop_price >0 and self.pos>0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = self.low[0] if self.long_trailing_stop_price<self.low[0] else self.long_trailing_stop_price
|
||||
|
||||
#print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price >0 and self.pos<0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = self.high[0] if self.high[0] <self.short_trailing_stop_price else self.short_trailing_stop_price
|
||||
|
||||
#print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
self.out_long=self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short=self.short_trailing_stop_price*(1 + self.trailing_stop_percent)
|
||||
#print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
#print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long >0:
|
||||
if self.low[0] < self.out_long and self.pos>0 and self.sl_long_price>0 and self.low[0]>self.sl_long_price:
|
||||
#print('--多头止盈出场datetime+sig: ',dt,'Trailing stop triggered: Closing position','TR',self.out_long,'low', self.low[0])
|
||||
self.close(data=self.data, price=self.data.close[0],size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long=0
|
||||
self.pos = 0
|
||||
|
||||
if self.out_short>0:
|
||||
if self.high[0] > self.out_short and self.pos<0 and self.sl_shor_price>0 and self.high[0]<self.sl_shor_price:
|
||||
#print('--空头止盈出场datetime+sig: ',dt,'Trailing stop triggered: Closing position: ','TR',self.out_short,'high', self.high[0])
|
||||
self.close(data=self.data, price=self.data.close[0],size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_shor=0
|
||||
self.pos = 0
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if self.sl_long_price>0 and self.fixed_stop_loss_L>0 and self.pos > 0 and self.closes[0] < self.fixed_stop_loss_L:
|
||||
#print('--多头止损datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0],size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if self.sl_shor_price>0 and self.fixed_stop_loss_S>0 and self.pos < 0 and self.closes[0] > self.fixed_stop_loss_S:
|
||||
#print('--空头止损datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots,exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
|
||||
# 更新最高价和最低价的列表
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
# 计算delta累计
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
|
||||
# 将当前行数据添加到 DataFrame
|
||||
# new_row = {
|
||||
# 'datetime': dt,
|
||||
# 'high': self.data.high[0],
|
||||
# 'low': self.data.low[0],
|
||||
# 'close': self.data.close[0],
|
||||
# 'open': self.data.open[0],
|
||||
# 'delta': self.data.delta[0],
|
||||
# 'delta_cumsum': sum(self.deltas_list)
|
||||
# }
|
||||
# # 使用pandas.concat代替append
|
||||
# self.df = pd.concat([self.df, pd.DataFrame([new_row])], ignore_index=True)
|
||||
|
||||
# # 检查文件是否存在
|
||||
# csv_file_path = f"output.csv"
|
||||
# if os.path.exists(csv_file_path):
|
||||
# # 仅保存最后一行数据
|
||||
# self.df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
# else:
|
||||
# # 创建新文件并保存整个DataFrame
|
||||
# self.df.to_csv(csv_file_path, index=False)
|
||||
|
||||
|
||||
#
|
||||
if run_kg==False : #
|
||||
#print(self.delta_cumsum)
|
||||
开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] >self.params.duiji and self.data.delta[0]>self.params.delta and self.delta_cumsum[-1]>self.params.cout_delta
|
||||
开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-self.params.duiji and self.data.delta[0]<-self.params.delta and self.delta_cumsum[-1]<-self.params.cout_delta
|
||||
平多条件=self.pos<0 and self.signal[0] >self.params.duiji
|
||||
平空条件=self.pos>0 and self.signal[0] <-self.params.duiji
|
||||
if self.pos !=1 : #
|
||||
if 平多条件:
|
||||
#print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合 : #
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos=1
|
||||
self.long_trailing_stop_price=self.low[0]
|
||||
self.sl_long_price=self.data.open[0]
|
||||
#print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存多头价格: ',self.long_trailing_stop_price)
|
||||
|
||||
if self.pos !=-1 : #
|
||||
if 平空条件:
|
||||
#print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合: #
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos=-1
|
||||
self.short_trailing_stop_price=self.high[0]
|
||||
self.sl_shor_price=self.data.open[0]
|
||||
#print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存空头价格: ',self.short_trailing_stop_price)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
# 创建Cerebro实例
|
||||
|
||||
cerebro = bt.Cerebro()
|
||||
#数据
|
||||
csv_file='E:/of_data/tick生成的OF数据/data_rs_merged/上期所/ag888/ag888_rs_2023_5M_back_ofdata_dj.csv' #
|
||||
# 从CSV文件加载数据
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2023,1,1),
|
||||
todate=datetime(2023,12,29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat='%Y-%m-%d %H:%M:%S',
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8
|
||||
)
|
||||
|
||||
# 评估函数,输入参数,返回评估函数值,这里是总市值,要求最大化
|
||||
def evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent,duiji,cout_delta,delta):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(MyStrategy_固定止损_跟踪止盈)
|
||||
cerebro.adddata(data) # 确保你有一个有效的数据源
|
||||
cerebro.broker.setcash(10000.0)
|
||||
#手续费,单手保证金,合约倍数
|
||||
cerebro.broker.setcommission(commission=14, margin=5000.0,mult=10)#回测参数
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue()
|
||||
|
||||
# 创建参数网格
|
||||
trailing_stop_percents = np.arange(0.005, 0.025, 0.005)
|
||||
fixed_stop_loss_percents = np.arange(0.01, 0.050, 0.01)
|
||||
duiji= np.arange(1, 3, 1) #
|
||||
cout_delta= np.arange(500, 3500, 500)
|
||||
delta=np.arange(500, 3500, 500)
|
||||
|
||||
# 生成所有参数组合
|
||||
combinations = list(itertools.product(trailing_stop_percents, fixed_stop_loss_percents,duiji,cout_delta,delta))
|
||||
|
||||
# 评估所有参数组合并找到最佳参数
|
||||
best_value = 0
|
||||
best_parameters = None
|
||||
for combo in combinations:
|
||||
value = evaluate_strategy(*combo)
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_parameters = combo
|
||||
print(f'combo: {combo},best_value: {best_value},best_parameters: {best_parameters}')
|
||||
|
||||
# 打印最佳参数组合
|
||||
print(f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%")
|
||||
print(f"最大市值: {best_value}")
|
||||
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
@@ -0,0 +1,218 @@
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import itertools
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
lines = ('sig', 'delta')
|
||||
params = (('sig', 6), ('delta', 8))
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
('trailing_stop_percent', 0.02),
|
||||
('fixed_stop_loss_percent', 0.01),
|
||||
('duiji', 1),
|
||||
('cout_delta', 1),
|
||||
('delta', 1),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1
|
||||
self.signal = self.datas[0].sig
|
||||
self.delta = self.datas[0].delta
|
||||
self.pos = 0
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
self.barN = 0
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print('%s, %s' % (dt.isoformat(), txt))
|
||||
|
||||
def next(self):
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
def 每日重置数据():
|
||||
current_time = dt.time()
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
clearing_executed = False
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
clearing_executed = False
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
self.long_trailing_stop_price = max(self.low[0], self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
self.short_trailing_stop_price = min(self.high[0], self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
|
||||
if self.out_long > 0 and self.low[0] < self.out_long and self.pos > 0 and self.sl_long_price > 0 and self.low[0] > self.sl_long_price:
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if self.out_short > 0 and self.high[0] > self.out_short and self.pos < 0 and self.sl_shor_price > 0 and self.high[0] < self.sl_shor_price:
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if self.sl_long_price > 0 and self.fixed_stop_loss_L > 0 and self.pos > 0 and self.closes[0] < self.fixed_stop_loss_L:
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if self.sl_shor_price > 0 and self.fixed_stop_loss_S > 0 and self.pos < 0 and self.closes[0] > self.fixed_stop_loss_S:
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
if run_kg == False:
|
||||
开多组合 = self.rinei_mean > 0 and self.closes[0] > self.rinei_mean and self.signal[0] > self.params.duiji and self.data.delta[0] > self.params.delta and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
开空组合 = self.rinei_mean > 0 and self.closes[0] < self.rinei_mean and self.signal[0] < -self.params.duiji and self.data.delta[0] < -self.params.delta and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
平多条件 = self.pos < 0 and self.signal[0] > self.params.duiji
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -self.params.duiji
|
||||
|
||||
if self.pos != 1:
|
||||
if 平多条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合:
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
|
||||
if self.pos != -1:
|
||||
if 平空条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合:
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
|
||||
if __name__ == "__main__":
|
||||
def evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(MyStrategy_固定止损_跟踪止盈,
|
||||
trailing_stop_percent=trailing_stop_percent,
|
||||
fixed_stop_loss_percent=fixed_stop_loss_percent,
|
||||
duiji=duiji,
|
||||
cout_delta=cout_delta,
|
||||
delta=delta)
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2023, 1, 1),
|
||||
todate=datetime(2023, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat='%Y-%m-%d %H:%M:%S',
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8
|
||||
)
|
||||
cerebro.adddata(data)
|
||||
cerebro.broker.setcash(10000.0)
|
||||
cerebro.broker.setcommission(commission=14, margin=5000.0, mult=10)
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue()
|
||||
|
||||
csv_file = 'E:/of_data/tick生成的OF数据/data_rs_merged/上期所/ag888/ag888_rs_2023_5M_back_ofdata_dj.csv'
|
||||
|
||||
trailing_stop_percents = np.arange(0.005, 0.025, 0.005)
|
||||
fixed_stop_loss_percents = np.arange(0.01, 0.050, 0.01)
|
||||
duiji = np.arange(1, 3, 1)
|
||||
cout_delta = np.arange(500, 3500, 500)
|
||||
delta = np.arange(500, 3500, 500)
|
||||
|
||||
combinations = list(itertools.product(trailing_stop_percents, fixed_stop_loss_percents, duiji, cout_delta, delta))
|
||||
best_value = 0
|
||||
best_parameters = None
|
||||
|
||||
for combo in combinations:
|
||||
value = evaluate_strategy(*combo)
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_parameters = combo
|
||||
print(f'combo: {combo}, best_value: {best_value}, best_parameters: {best_parameters}')
|
||||
|
||||
print(f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%")
|
||||
print(f"最大市值: {best_value}")
|
||||
|
||||
@@ -0,0 +1,302 @@
|
||||
import backtrader as bt
|
||||
from datetime import datetime, time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
from deap import base, creator, tools, algorithms
|
||||
import random
|
||||
|
||||
|
||||
# 自定义CSV数据类
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
lines = ("sig", "delta")
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
# 自定义策略类
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.01),
|
||||
("fixed_stop_loss_percent", 0.005),
|
||||
("duiji", 1),
|
||||
("cout_delta", 1),
|
||||
("delta", 1),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
# 初始化变量
|
||||
self.Lots = 1
|
||||
self.signal = self.datas[0].sig
|
||||
self.delta = self.datas[0].delta
|
||||
self.pos = 0
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
self.barN = 0
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def next(self):
|
||||
self.barN += 1
|
||||
# position = self.getposition(self.datas[0]).size
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
def reset_daily_data():
|
||||
current_time = dt.time()
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
clearing_time2_start = s_time(22, 55)
|
||||
clearing_time2_end = s_time(23, 0)
|
||||
clearing_executed = False
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
clearing_executed = False
|
||||
return clearing_executed
|
||||
|
||||
run_kg = reset_daily_data()
|
||||
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
self.long_trailing_stop_price = max(self.low[0], self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
self.short_trailing_stop_price = min(self.high[0], self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
|
||||
if (
|
||||
self.out_long > 0
|
||||
and self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if (
|
||||
self.out_short > 0
|
||||
and self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
if not run_kg:
|
||||
开多组合 = (
|
||||
self.rinei_mean > 0
|
||||
and self.closes[0] > self.rinei_mean
|
||||
and self.signal[0] > self.params.duiji
|
||||
and self.data.delta[0] > self.params.delta
|
||||
and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
)
|
||||
开空组合 = (
|
||||
self.rinei_mean > 0
|
||||
and self.closes[0] < self.rinei_mean
|
||||
and self.signal[0] < -self.params.duiji
|
||||
and self.data.delta[0] < -self.params.delta
|
||||
and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > self.params.duiji
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -self.params.duiji
|
||||
|
||||
if self.pos != 1:
|
||||
if 平多条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合:
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
|
||||
if self.pos != -1:
|
||||
if 平空条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合:
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
|
||||
|
||||
# 评估策略函数
|
||||
def evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(
|
||||
MyStrategy_固定止损_跟踪止盈,
|
||||
trailing_stop_percent=trailing_stop_percent,
|
||||
fixed_stop_loss_percent=fixed_stop_loss_percent,
|
||||
duiji=duiji,
|
||||
cout_delta=cout_delta,
|
||||
delta=delta,
|
||||
)
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2023, 1, 1),
|
||||
todate=datetime(2023, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
cerebro.adddata(data)
|
||||
cerebro.broker.setcash(500000.0)
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300)
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue()
|
||||
|
||||
|
||||
# 遗传算法优化部分
|
||||
def optimize_with_ga(csv_file):
|
||||
# 创建适应度和个体
|
||||
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
|
||||
creator.create("Individual", list, fitness=creator.FitnessMax)
|
||||
|
||||
# 定义个体生成和变异操作
|
||||
toolbox = base.Toolbox()
|
||||
toolbox.register("attr_trailing_stop_percent", random.uniform, 0.002, 0.01)
|
||||
toolbox.register("attr_fixed_stop_loss_percent", random.uniform, 0.002, 0.01)
|
||||
toolbox.register("attr_duiji", random.randint, 3, 5)
|
||||
toolbox.register("attr_cout_delta", random.randint, 20, 400)
|
||||
toolbox.register("attr_delta", random.randint, 20, 400)
|
||||
|
||||
toolbox.register(
|
||||
"individual",
|
||||
tools.initCycle,
|
||||
creator.Individual,
|
||||
(
|
||||
toolbox.attr_trailing_stop_percent,
|
||||
toolbox.attr_fixed_stop_loss_percent,
|
||||
toolbox.attr_duiji,
|
||||
toolbox.attr_cout_delta,
|
||||
toolbox.attr_delta,
|
||||
),
|
||||
)
|
||||
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
|
||||
|
||||
# 定义评价函数
|
||||
def evaluate(individual):
|
||||
trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta = individual
|
||||
result = evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file)
|
||||
if isinstance(result, complex):
|
||||
print(f"Complex result encountered: {result}")
|
||||
return (result,)
|
||||
|
||||
toolbox.register("evaluate", evaluate)
|
||||
toolbox.register("mate", tools.cxBlend, alpha=0.5)
|
||||
toolbox.register(
|
||||
"mutate",
|
||||
tools.mutPolynomialBounded,
|
||||
low=[0.002, 0.002, 3, 20, 20],
|
||||
up=[0.01, 0.01, 5, 400, 400],
|
||||
eta=0.1,
|
||||
indpb=0.2,
|
||||
)
|
||||
toolbox.register("select", tools.selTournament, tournsize=3)
|
||||
|
||||
# 遗传算法主循环
|
||||
population = toolbox.population(n=50)
|
||||
ngen, cxpb, mutpb = 40, 0.5, 0.2
|
||||
algorithms.eaSimple(population, toolbox, cxpb, mutpb, ngen, verbose=True)
|
||||
|
||||
# 获取最佳个体
|
||||
best_individual = tools.selBest(population, 1)[0]
|
||||
return best_individual
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
csv_file = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IM888\IM888_rs_2023_5T_back_ofdata_dj.csv"
|
||||
|
||||
best_parameters = optimize_with_ga(csv_file)
|
||||
print(f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%")
|
||||
print(f"对冲 {best_parameters[2]}, 策略 {best_parameters[3]}, 增量 {best_parameters[4]}")
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import itertools
|
||||
import multiprocessing
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
lines = ("sig", "delta")
|
||||
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.02),
|
||||
("fixed_stop_loss_percent", 0.01),
|
||||
("duiji", 1),
|
||||
("cout_delta", 1),
|
||||
("delta", 1),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1
|
||||
self.signal = self.datas[0].sig
|
||||
self.delta = self.datas[0].delta
|
||||
self.pos = 0
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
self.barN = 0
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def next(self):
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
def 每日重置数据():
|
||||
current_time = dt.time()
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
clearing_time2_start = s_time(22, 55)
|
||||
clearing_time2_end = s_time(23, 00)
|
||||
clearing_executed = False
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
clearing_executed = False
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
self.long_trailing_stop_price = max(self.low[0], self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
self.short_trailing_stop_price = min(self.high[0], self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
|
||||
if (
|
||||
self.out_long > 0
|
||||
and self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if (
|
||||
self.out_short > 0
|
||||
and self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
if run_kg == False:
|
||||
开多组合 = (
|
||||
self.rinei_mean > 0
|
||||
and self.closes[0] > self.rinei_mean
|
||||
and self.signal[0] > self.params.duiji
|
||||
and self.data.delta[0] > self.params.delta
|
||||
and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
)
|
||||
开空组合 = (
|
||||
self.rinei_mean > 0
|
||||
and self.closes[0] < self.rinei_mean
|
||||
and self.signal[0] < -self.params.duiji
|
||||
and self.data.delta[0] < -self.params.delta
|
||||
and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > self.params.duiji
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -self.params.duiji
|
||||
|
||||
if self.pos != 1:
|
||||
if 平多条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合:
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
|
||||
if self.pos != -1:
|
||||
if 平空条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合:
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
|
||||
|
||||
def evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(
|
||||
MyStrategy_固定止损_跟踪止盈,
|
||||
trailing_stop_percent=trailing_stop_percent,
|
||||
fixed_stop_loss_percent=fixed_stop_loss_percent,
|
||||
duiji=duiji,
|
||||
cout_delta=cout_delta,
|
||||
delta=delta,
|
||||
)
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2023, 1, 1),
|
||||
todate=datetime(2023, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
cerebro.adddata(data)
|
||||
cerebro.broker.setcash(500000.0)
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300)
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue(), (trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta)
|
||||
|
||||
|
||||
def run_backtest(params):
|
||||
trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file = params
|
||||
return evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
csv_file = (
|
||||
r"E:\of_data\主力连续\tick生成的OF数据(1M)\data_rs_merged\中金所\IF888\IF888_rs_2023_1T_back_ofdata_dj.csv"
|
||||
)
|
||||
|
||||
trailing_stop_percents = np.arange(0.005, 0.020, 0.005)
|
||||
fixed_stop_loss_percents = np.arange(0.01, 0.040, 0.01)
|
||||
duiji = np.arange(1, 3, 1)
|
||||
cout_delta = np.arange(20, 220, 20) # (500, 3500, 500)
|
||||
delta = np.arange(20, 220, 20) # (500, 3500, 500)
|
||||
|
||||
combinations = list(itertools.product(trailing_stop_percents, fixed_stop_loss_percents, duiji, cout_delta, delta))
|
||||
combinations = [(tsp, fslp, d, cd, dl, csv_file) for tsp, fslp, d, cd, dl in combinations]
|
||||
|
||||
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
|
||||
results = pool.map(run_backtest, combinations)
|
||||
|
||||
best_value = 0
|
||||
best_parameters = None
|
||||
|
||||
for value, params in results:
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_parameters = params
|
||||
print(f"combo: {params}, value: {value}, best_value: {best_value}, best_parameters: {best_parameters}")
|
||||
|
||||
print(f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%")
|
||||
print(f"最大市值: {best_value}")
|
||||
+291
@@ -0,0 +1,291 @@
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import itertools
|
||||
import multiprocessing
|
||||
|
||||
import talib as tb
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
lines = ("sig", "delta")
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.02),
|
||||
("fixed_stop_loss_percent", 0.01),
|
||||
("duiji", 1),
|
||||
("cout_delta", 1),
|
||||
("delta", 1),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1
|
||||
self.signal = self.datas[0].sig
|
||||
self.delta = self.datas[0].delta
|
||||
self.pos = 0
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.reniei_aroon_up = []
|
||||
self.reniei_aroon_down = []
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
self.barN = 0
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def next(self):
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
def 每日重置数据():
|
||||
current_time = dt.time()
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
clearing_executed = False
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.renei_high_ma.append(self.high[0])
|
||||
self.renei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.reniei_aroon_up, self.reniei_aroon_down = tb.AROON(
|
||||
np.array(self.renei_high_ma), np.array(self.renei_low_ma), 14
|
||||
)
|
||||
clearing_executed = False
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
self.long_trailing_stop_price = max(self.low[0], self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
self.short_trailing_stop_price = min(self.high[0], self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
|
||||
if (
|
||||
self.out_long > 0
|
||||
and self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if (
|
||||
self.out_short > 0
|
||||
and self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
if run_kg == False:
|
||||
# 开多组合 = self.rinei_mean > 0 and self.closes[0] > self.rinei_mean and self.signal[0] > self.params.duiji and self.data.delta[0] > self.params.delta and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
# 开空组合 = self.rinei_mean > 0 and self.closes[0] < self.rinei_mean and self.signal[0] < -self.params.duiji and self.data.delta[0] < -self.params.delta and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
开多组合 = (
|
||||
# self.reniei_aroon_up[-1] > 50
|
||||
self.reniei_aroon_up[-1] > self.reniei_aroon_down[-1]
|
||||
and self.signal[0] > self.params.duiji
|
||||
and self.data.delta[0] > self.params.delta
|
||||
and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
)
|
||||
开空组合 = (
|
||||
# self.reniei_aroon_down[-1] > 50
|
||||
self.reniei_aroon_up[-1] < self.reniei_aroon_down[-1]
|
||||
and self.signal[0] < -self.params.duiji
|
||||
and self.data.delta[0] < -self.params.delta
|
||||
and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > self.params.duiji
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -self.params.duiji
|
||||
|
||||
if self.pos != 1:
|
||||
if 平多条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合:
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
|
||||
if self.pos != -1:
|
||||
if 平空条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合:
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
|
||||
|
||||
def evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(
|
||||
MyStrategy_固定止损_跟踪止盈,
|
||||
trailing_stop_percent=trailing_stop_percent,
|
||||
fixed_stop_loss_percent=fixed_stop_loss_percent,
|
||||
duiji=duiji,
|
||||
cout_delta=cout_delta,
|
||||
delta=delta,
|
||||
)
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2020, 1, 1),
|
||||
todate=datetime(2023, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
cerebro.adddata(data)
|
||||
cerebro.broker.setcash(300000.0)
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300)
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue(), (trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta)
|
||||
|
||||
|
||||
def run_backtest(params):
|
||||
trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file = params
|
||||
return evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, csv_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
csv_file = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(5M)\data_rs_merged\中金所\IM888\IM888_rs_2023_5T_back_ofdata_dj.csv"
|
||||
|
||||
trailing_stop_percents = np.arange(0.005, 0.025, 0.005)
|
||||
fixed_stop_loss_percents = np.arange(0.01, 0.050, 0.01)
|
||||
duiji = np.arange(1, 4, 1)
|
||||
cout_delta = np.arange(100000, 800000, 100000) # (500, 3500, 500)
|
||||
delta = np.arange(100000, 800000, 100000) # (500, 3500, 500)
|
||||
|
||||
combinations = list(itertools.product(trailing_stop_percents, fixed_stop_loss_percents, duiji, cout_delta, delta))
|
||||
combinations = [(tsp, fslp, d, cd, dl, csv_file) for tsp, fslp, d, cd, dl in combinations]
|
||||
|
||||
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
|
||||
results = pool.map(run_backtest, combinations)
|
||||
|
||||
best_value = 0
|
||||
best_parameters = None
|
||||
|
||||
for value, params in results:
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_parameters = params
|
||||
print(f"combo: {params}, value: {value}, best_value: {best_value}, best_parameters: {best_parameters}")
|
||||
|
||||
print(f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%")
|
||||
print(f"最大市值: {best_value}")
|
||||
|
||||
# trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta
|
||||
# IM
|
||||
# 5M:(0.01, 0.02, 2, 700000, 500000)
|
||||
# 1M:(0.005, 0.02, 3, 100000, 200000)
|
||||
# IF
|
||||
# 5M:(0.005, 0.02, 1, 100000, 400000)
|
||||
+307
@@ -0,0 +1,307 @@
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import itertools
|
||||
import multiprocessing
|
||||
|
||||
import talib as tb
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
lines = ("sig", "delta")
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.02),
|
||||
("fixed_stop_loss_percent", 0.01),
|
||||
("duiji", 1),
|
||||
("cout_delta", 1),
|
||||
("delta", 1),
|
||||
("aroon_timeperiod", 14),
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1
|
||||
self.signal = self.datas[0].sig
|
||||
self.delta = self.datas[0].delta
|
||||
self.pos = 0
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.reniei_aroon_up = []
|
||||
self.reniei_aroon_down = []
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
self.barN = 0
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def next(self):
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
def 每日重置数据():
|
||||
current_time = dt.time()
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
clearing_executed = False
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.renei_high_ma.append(self.high[0])
|
||||
self.renei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.reniei_aroon_up, self.reniei_aroon_down = tb.AROON(
|
||||
np.array(self.renei_high_ma), np.array(self.renei_low_ma), self.params.aroon_timeperiod
|
||||
)
|
||||
clearing_executed = False
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
self.long_trailing_stop_price = max(self.low[0], self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
self.short_trailing_stop_price = min(self.high[0], self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
|
||||
if (
|
||||
self.out_long > 0
|
||||
and self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if (
|
||||
self.out_short > 0
|
||||
and self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
if run_kg == False:
|
||||
# 开多组合 = self.rinei_mean > 0 and self.closes[0] > self.rinei_mean and self.signal[0] > self.params.duiji and self.data.delta[0] > self.params.delta and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
# 开空组合 = self.rinei_mean > 0 and self.closes[0] < self.rinei_mean and self.signal[0] < -self.params.duiji and self.data.delta[0] < -self.params.delta and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
开多组合 = (
|
||||
# self.reniei_aroon_up[-1] > 50
|
||||
self.reniei_aroon_up[-1] > self.reniei_aroon_down[-1]
|
||||
and self.signal[0] > self.params.duiji
|
||||
and self.data.delta[0] > self.params.delta
|
||||
and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
)
|
||||
开空组合 = (
|
||||
# self.reniei_aroon_down[-1] > 50
|
||||
self.reniei_aroon_up[-1] < self.reniei_aroon_down[-1]
|
||||
and self.signal[0] < -self.params.duiji
|
||||
and self.data.delta[0] < -self.params.delta
|
||||
and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > self.params.duiji
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -self.params.duiji
|
||||
|
||||
if self.pos != 1:
|
||||
if 平多条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合:
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
|
||||
if self.pos != -1:
|
||||
if 平空条件:
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合:
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
|
||||
|
||||
def evaluate_strategy(
|
||||
trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, aroon_timeperiod, csv_file
|
||||
):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(
|
||||
MyStrategy_固定止损_跟踪止盈,
|
||||
trailing_stop_percent=trailing_stop_percent,
|
||||
fixed_stop_loss_percent=fixed_stop_loss_percent,
|
||||
duiji=duiji,
|
||||
cout_delta=cout_delta,
|
||||
delta=delta,
|
||||
aroon_timeperiod=aroon_timeperiod,
|
||||
)
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2022, 1, 1),
|
||||
todate=datetime(2022, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
cerebro.adddata(data)
|
||||
cerebro.broker.setcash(300000.0)
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300)
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue(), (
|
||||
trailing_stop_percent,
|
||||
fixed_stop_loss_percent,
|
||||
duiji,
|
||||
cout_delta,
|
||||
delta,
|
||||
aroon_timeperiod,
|
||||
)
|
||||
|
||||
|
||||
def run_backtest(params):
|
||||
trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, aroon_timeperiod, csv_file = params
|
||||
return evaluate_strategy(
|
||||
trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta, aroon_timeperiod, csv_file
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
csv_file = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(2M)\data_rs_merged\中金所\IM888\IM888_rs_2022_2T_back_ofdata_dj_new.csv"
|
||||
|
||||
trailing_stop_percents = np.arange(0.005, 0.025, 0.005)
|
||||
fixed_stop_loss_percents = np.arange(0.01, 0.030, 0.01)
|
||||
duiji = np.arange(2, 4, 1)
|
||||
cout_delta = np.arange(500000, 4000000, 500000) # (500, 3500, 500)
|
||||
delta = np.arange(500000, 4000000, 500000) # (500, 3500, 500)
|
||||
aroon_timeperiod = np.arange(4, 20, 4)
|
||||
|
||||
combinations = list(
|
||||
itertools.product(trailing_stop_percents, fixed_stop_loss_percents, duiji, cout_delta, delta, aroon_timeperiod)
|
||||
)
|
||||
combinations = [(tsp, fslp, d, cd, dl, d2, csv_file) for tsp, fslp, d, cd, dl, d2 in combinations]
|
||||
|
||||
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
|
||||
results = pool.map(run_backtest, combinations)
|
||||
|
||||
best_value = 0
|
||||
best_parameters = None
|
||||
|
||||
for value, params in results:
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_parameters = params
|
||||
print(f"combo: {params}, value: {value}, best_value: {best_value}, best_parameters: {best_parameters}")
|
||||
|
||||
print(f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%")
|
||||
print(f"最大市值: {best_value}")
|
||||
|
||||
# trailing_stop_percent, fixed_stop_loss_percent, duiji, cout_delta, delta
|
||||
# IM
|
||||
# 5M:(0.01, 0.02, 2, 700000, 500000)
|
||||
# 1M:(0.005, 0.02, 3, 100000, 200000)
|
||||
# IF
|
||||
# 5M:(0.005, 0.02, 1, 100000, 400000)
|
||||
@@ -0,0 +1,422 @@
|
||||
'''
|
||||
以下是代码的详细说明:
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
1.
|
||||
导入必要的模块和库:
|
||||
backtrader 用于回测功能
|
||||
datetime 用于处理日期和时间
|
||||
GenericCSVData 用于从CSV文件加载数据
|
||||
numpy 用于数值操作
|
||||
time 用于时间相关操作
|
||||
matplotlib.pyplot 用于绘图
|
||||
|
||||
2. 定义自定义手续费模板MyCommission
|
||||
继承自bt.CommInfoBase
|
||||
|
||||
3.
|
||||
定义自定义数据源类 GenericCSV_SIG:
|
||||
继承自 GenericCSVData,并添加了两个额外的行:'sig'和'delta'
|
||||
定义了参数 'sig'和'delta'
|
||||
|
||||
4.
|
||||
定义 MyStrategy_固定止损_跟踪止盈 类:
|
||||
继承自 bt.Strategy(backtrader的基础策略类)
|
||||
定义了两个参数:trailing_stop_percent 和 fixed_stop_loss_percent
|
||||
初始化策略并设置各种变量和指标
|
||||
实现了 next 方法,该方法在数据源的每个新的K线出现时被调用
|
||||
根据当前K线数据更新跟踪止盈价格
|
||||
实现了跟踪止盈出场和固定止损出场
|
||||
根据信号处理多头和空头仓位
|
||||
在策略执行过程中打印调试信息
|
||||
|
||||
5.
|
||||
if __name__ == "__main__": 代码块:
|
||||
使用 Cerebro 实例设置回测环境
|
||||
使用 GenericCSV_SIG 数据源从CSV文件加载数据
|
||||
将数据源和策略添加到 Cerebro 实例中
|
||||
添加观察者和分析器以评估性能
|
||||
设置初始资金和经纪人参数
|
||||
运行回测并获取结果
|
||||
打印回测报告,包括收益率、回撤、胜率和交易统计数据
|
||||
使用 matplotlib 绘制回测结果
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
'''
|
||||
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import os
|
||||
import itertools
|
||||
from scipy.optimize import brute
|
||||
|
||||
import talib as tb
|
||||
|
||||
|
||||
手续费汇总=0
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
# 从基类继承,添加一个 'sig',‘delta’行
|
||||
lines = ('sig','delta')
|
||||
# 添加参数为从基类继承的参数
|
||||
params = (('sig',6),('delta', 8))
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
('trailing_stop_percent', 0.02), # 跟踪止盈百分比
|
||||
('fixed_stop_loss_percent', 0.01), # 固定止损百分比
|
||||
('duiji', 1), # 堆积
|
||||
('cout_delta', 1), # 日累计delta
|
||||
('delta', 1), # delta单bar
|
||||
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots=1 #下单手数
|
||||
|
||||
self.signal = self.datas[0].sig # 使用sig字段作为策略的信号字段
|
||||
self.delta= self.datas[0].delta
|
||||
# 获取数据序列别名列表
|
||||
line_aliases = self.datas[0].getlinealiases()
|
||||
self.pos=0
|
||||
print(line_aliases)
|
||||
self.high=self.datas[0].high
|
||||
self.low=self.datas[0].low
|
||||
self.closes=self.datas[0].close
|
||||
self.open=self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price=0
|
||||
self.sl_shor_price=0
|
||||
self.out_long=0
|
||||
self.out_short=0
|
||||
self.rinei_ma=[]
|
||||
self.rinei_mean=0
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.reniei_aroon_up = []
|
||||
self.reniei_aroon_down = []
|
||||
|
||||
self.datetime_list= []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum=[]
|
||||
|
||||
self.barN = 0
|
||||
self.df = pd.DataFrame(columns=['datetime', 'high', 'low', 'close', 'open', 'delta', 'delta_cumsum'])
|
||||
|
||||
self.trader_df=pd.DataFrame(columns=['open', 'high', 'low', 'close', 'volume', 'openInterest','delta'])
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
'''可选,构建策略打印日志的函数:可用于打印订单记录或交易记录等'''
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print('%s, %s' % (dt.isoformat(), txt))
|
||||
|
||||
# def notify_order(self, order):
|
||||
# # 未被处理的订单
|
||||
# if order.status in [order.Submitted, order.Accepted]:
|
||||
# return
|
||||
# # 已经处理的订单
|
||||
# if order.status in [order.Completed, order.Canceled, order.Margin]:
|
||||
# global 手续费汇总
|
||||
# if order.isbuy():
|
||||
# 手续费汇总 +=order.executed.comm
|
||||
# self.log(
|
||||
# 'BUY EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f' %
|
||||
# (order.ref, # 订单编号
|
||||
# order.executed.price, # 成交价
|
||||
# order.executed.comm, # 佣金
|
||||
# order.executed.size, # 成交量
|
||||
# order.data._name,# 品种名称
|
||||
# 手续费汇总))
|
||||
|
||||
# else: # Sell
|
||||
# 手续费汇总 +=order.executed.comm
|
||||
# self.log('SELL EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f' %
|
||||
# (order.ref,
|
||||
# order.executed.price,
|
||||
# order.executed.comm,
|
||||
# order.executed.size,
|
||||
# order.data._name,
|
||||
# 手续费汇总))
|
||||
|
||||
def next(self):
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
#bar线计数初始化
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
#时间轴
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
#更新跟踪止损价格
|
||||
def 每日重置数据():
|
||||
# 获取当前时间
|
||||
current_time = dt.time()
|
||||
#print(current_time)
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
|
||||
# 创建一个标志变量
|
||||
clearing_executed = False
|
||||
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed :
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma=[]
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum=[]
|
||||
self.deltas_list=[]
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed :
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma=[]
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum=[]
|
||||
self.deltas_list=[]
|
||||
# 如果不在任何时间范围内,可以执行其他操作
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.renei_high_ma.append(self.high[0])
|
||||
self.renei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.reniei_aroon_up, self.reniei_aroon_down = tb.AROON(np.array(self.renei_high_ma), np.array(self.renei_low_ma), 14)
|
||||
#self.delta_cumsum=[]
|
||||
#self.deltas_list=[]
|
||||
#print('rinei_ma',self.rinei_ma)
|
||||
clearing_executed = False
|
||||
pass
|
||||
|
||||
return clearing_executed
|
||||
|
||||
run_kg=每日重置数据()
|
||||
|
||||
#过滤成交量为0或小于0
|
||||
if self.data.volume[0] <= 0 :
|
||||
return
|
||||
#print(f'volume,{self.data.volume[0]}')
|
||||
if self.long_trailing_stop_price >0 and self.pos>0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = self.low[0] if self.long_trailing_stop_price<self.low[0] else self.long_trailing_stop_price
|
||||
|
||||
#print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price >0 and self.pos<0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = self.high[0] if self.high[0] <self.short_trailing_stop_price else self.short_trailing_stop_price
|
||||
|
||||
#print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
self.out_long=self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short=self.short_trailing_stop_price*(1 + self.trailing_stop_percent)
|
||||
#print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
#print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long >0:
|
||||
if self.low[0] < self.out_long and self.pos>0 and self.sl_long_price>0 and self.low[0]>self.sl_long_price:
|
||||
#print('--多头止盈出场datetime+sig: ',dt,'Trailing stop triggered: Closing position','TR',self.out_long,'low', self.low[0])
|
||||
self.close(data=self.data, price=self.data.close[0],size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long=0
|
||||
self.pos = 0
|
||||
|
||||
if self.out_short>0:
|
||||
if self.high[0] > self.out_short and self.pos<0 and self.sl_shor_price>0 and self.high[0]<self.sl_shor_price:
|
||||
#print('--空头止盈出场datetime+sig: ',dt,'Trailing stop triggered: Closing position: ','TR',self.out_short,'high', self.high[0])
|
||||
self.close(data=self.data, price=self.data.close[0],size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_shor=0
|
||||
self.pos = 0
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if self.sl_long_price>0 and self.fixed_stop_loss_L>0 and self.pos > 0 and self.closes[0] < self.fixed_stop_loss_L:
|
||||
#print('--多头止损datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0],size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if self.sl_shor_price>0 and self.fixed_stop_loss_S>0 and self.pos < 0 and self.closes[0] > self.fixed_stop_loss_S:
|
||||
#print('--空头止损datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots,exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
|
||||
# 更新最高价和最低价的列表
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
# 计算delta累计
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
|
||||
# 将当前行数据添加到 DataFrame
|
||||
# new_row = {
|
||||
# 'datetime': dt,
|
||||
# 'high': self.data.high[0],
|
||||
# 'low': self.data.low[0],
|
||||
# 'close': self.data.close[0],
|
||||
# 'open': self.data.open[0],
|
||||
# 'delta': self.data.delta[0],
|
||||
# 'delta_cumsum': sum(self.deltas_list)
|
||||
# }
|
||||
# # 使用pandas.concat代替append
|
||||
# self.df = pd.concat([self.df, pd.DataFrame([new_row])], ignore_index=True)
|
||||
|
||||
# # 检查文件是否存在
|
||||
# csv_file_path = f"output.csv"
|
||||
# if os.path.exists(csv_file_path):
|
||||
# # 仅保存最后一行数据
|
||||
# self.df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
# else:
|
||||
# # 创建新文件并保存整个DataFrame
|
||||
# self.df.to_csv(csv_file_path, index=False)
|
||||
|
||||
|
||||
#
|
||||
if run_kg==False : #
|
||||
#print(self.delta_cumsum)
|
||||
# 开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] >self.params.duiji and self.data.delta[0]>self.params.delta and self.delta_cumsum[-1]>self.params.cout_delta
|
||||
# 开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-self.params.duiji and self.data.delta[0]<-self.params.delta and self.delta_cumsum[-1]<-self.params.cout_delta
|
||||
开多组合 = self.reniei_aroon_up[-1] > 50 and self.reniei_aroon_up[-1] > self.reniei_aroon_down[-1] and self.signal[0] > self.params.duiji and self.data.delta[0] > self.params.delta and self.delta_cumsum[-1] > self.params.cout_delta
|
||||
开空组合 = self.reniei_aroon_down[-1] > 50 and self.reniei_aroon_up[-1] < self.reniei_aroon_down[-1] and self.signal[0] < -self.params.duiji and self.data.delta[0] < -self.params.delta and self.delta_cumsum[-1] < -self.params.cout_delta
|
||||
平多条件=self.pos<0 and self.signal[0] >self.params.duiji
|
||||
平空条件=self.pos>0 and self.signal[0] <-self.params.duiji
|
||||
if self.pos !=1 : #
|
||||
if 平多条件:
|
||||
#print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合 : #
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos=1
|
||||
self.long_trailing_stop_price=self.low[0]
|
||||
self.sl_long_price=self.data.open[0]
|
||||
#print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存多头价格: ',self.long_trailing_stop_price)
|
||||
|
||||
if self.pos !=-1 : #
|
||||
if 平空条件:
|
||||
#print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合: #
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos=-1
|
||||
self.short_trailing_stop_price=self.high[0]
|
||||
self.sl_shor_price=self.data.open[0]
|
||||
#print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存空头价格: ',self.short_trailing_stop_price)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
# 创建Cerebro实例
|
||||
|
||||
cerebro = bt.Cerebro()
|
||||
#数据
|
||||
csv_file='E:/of_data/主力连续/tick生成的OF数据(1M)/data_rs_merged/上期所/ag888/ag888_rs_2023_1T_back_ofdata_dj.csv' #
|
||||
# 从CSV文件加载数据
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2023,1,1),
|
||||
todate=datetime(2023,12,29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat='%Y-%m-%d %H:%M:%S',
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8
|
||||
)
|
||||
|
||||
# 评估函数,输入参数,返回评估函数值,这里是总市值,要求最大化
|
||||
def evaluate_strategy(trailing_stop_percent, fixed_stop_loss_percent,duiji,cout_delta,delta):
|
||||
cerebro = bt.Cerebro()
|
||||
cerebro.addstrategy(MyStrategy_固定止损_跟踪止盈)
|
||||
cerebro.adddata(data) # 确保你有一个有效的数据源
|
||||
cerebro.broker.setcash(10000.0)
|
||||
#手续费,单手保证金,合约倍数
|
||||
cerebro.broker.setcommission(commission=14, margin=5000.0,mult=10)#回测参数
|
||||
cerebro.run()
|
||||
return cerebro.broker.getvalue()
|
||||
|
||||
# 创建参数网格
|
||||
trailing_stop_percents = np.arange(0.005, 0.025, 0.005)
|
||||
fixed_stop_loss_percents = np.arange(0.01, 0.050, 0.01)
|
||||
duiji= np.arange(1, 3, 1) #
|
||||
cout_delta= np.arange(500, 3500, 500)
|
||||
delta=np.arange(500, 3500, 500)
|
||||
|
||||
# 生成所有参数组合
|
||||
combinations = list(itertools.product(trailing_stop_percents, fixed_stop_loss_percents,duiji,cout_delta,delta))
|
||||
|
||||
# 评估所有参数组合并找到最佳参数
|
||||
best_value = 0
|
||||
best_parameters = None
|
||||
for combo in combinations:
|
||||
value = evaluate_strategy(*combo)
|
||||
if value > best_value:
|
||||
best_value = value
|
||||
best_parameters = combo
|
||||
print(f'combo: {combo},best_value: {best_value},best_parameters: {best_parameters}')
|
||||
|
||||
# 打印最佳参数组合
|
||||
print(f"最佳参数组合: 跟踪止损百分比 {best_parameters[0]}%, 固定止损百分比 {best_parameters[1]}%")
|
||||
print(f"最大市值: {best_value}")
|
||||
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
@@ -0,0 +1,489 @@
|
||||
"""
|
||||
以下是代码的详细说明:
|
||||
1.
|
||||
导入必要的模块和库:
|
||||
backtrader 用于回测功能
|
||||
datetime 用于处理日期和时间
|
||||
GenericCSVData 用于从CSV文件加载数据
|
||||
numpy 用于数值操作
|
||||
time 用于时间相关操作
|
||||
matplotlib.pyplot 用于绘图
|
||||
|
||||
2. 定义自定义手续费模板MyCommission
|
||||
继承自bt.CommInfoBase
|
||||
|
||||
3.
|
||||
定义自定义数据源类 GenericCSV_SIG:
|
||||
继承自 GenericCSVData,并添加了两个额外的行:'sig'和'delta'
|
||||
定义了参数 'sig'和'delta'
|
||||
|
||||
4.
|
||||
定义 MyStrategy_固定止损_跟踪止盈 类:
|
||||
继承自 bt.Strategy(backtrader的基础策略类)
|
||||
定义了两个参数:trailing_stop_percent 和 fixed_stop_loss_percent
|
||||
初始化策略并设置各种变量和指标
|
||||
实现了 next 方法,该方法在数据源的每个新的K线出现时被调用
|
||||
根据当前K线数据更新跟踪止盈价格
|
||||
实现了跟踪止盈出场和固定止损出场
|
||||
根据信号处理多头和空头仓位
|
||||
在策略执行过程中打印调试信息
|
||||
|
||||
5.
|
||||
if __name__ == "__main__": 代码块:
|
||||
使用 Cerebro 实例设置回测环境
|
||||
使用 GenericCSV_SIG 数据源从CSV文件加载数据
|
||||
将数据源和策略添加到 Cerebro 实例中
|
||||
添加观察者和分析器以评估性能
|
||||
设置初始资金和经纪人参数
|
||||
运行回测并获取结果
|
||||
打印回测报告,包括收益率、回撤、胜率和交易统计数据
|
||||
|
||||
6.使用前事项:
|
||||
1、主程序中修改ofdata_dj文件地址、png_filepath地址
|
||||
2、修改clearing_time2_start、clearing_time2_stop
|
||||
3、修改交易参数:lots、跟踪止损百分、固定止损百分比、duiji、cout_delta、delta
|
||||
4、修改资金参数:初始资金;回测参数:回测时间段、佣金、单边保证金、手续费;
|
||||
"""
|
||||
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import os
|
||||
import talib as tb # jerom注释: 增加talib库
|
||||
|
||||
手续费汇总 = 0
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
# 从基类继承,添加一个 'sig',‘delta’行
|
||||
lines = ("sig", "delta")
|
||||
# 添加参数为从基类继承的参数
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.01), # 跟踪止盈百分比
|
||||
("fixed_stop_loss_percent", 0.01), # 固定止损百分比
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1 # 下单手数
|
||||
|
||||
self.signal = self.datas[0].sig # 使用sig字段作为策略的信号字段
|
||||
self.delta = self.datas[0].delta
|
||||
# 获取数据序列别名列表
|
||||
line_aliases = self.datas[0].getlinealiases()
|
||||
self.pos = 0
|
||||
print(line_aliases)
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
# 240884432
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.rinei_mean = 0
|
||||
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
|
||||
self.barN = 0
|
||||
self.df = pd.DataFrame(columns=["datetime", "high", "low", "close", "open", "delta", "delta_cumsum"])
|
||||
|
||||
self.trader_df = pd.DataFrame(columns=["open", "high", "low", "close", "volume", "openInterest", "delta"])
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
"""可选,构建策略打印日志的函数:可用于打印订单记录或交易记录等"""
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def notify_order(self, order):
|
||||
# 未被处理的订单
|
||||
if order.status in [order.Submitted, order.Accepted]:
|
||||
return
|
||||
# 已经处理的订单
|
||||
if order.status in [order.Completed, order.Canceled, order.Margin]:
|
||||
global 手续费汇总
|
||||
if order.isbuy():
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"BUY EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref, # 订单编号
|
||||
order.executed.price, # 成交价
|
||||
order.executed.comm, # 佣金
|
||||
order.executed.size, # 成交量
|
||||
order.data._name, # 品种名称
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
else: # Sell
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"SELL EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref,
|
||||
order.executed.price,
|
||||
order.executed.comm,
|
||||
order.executed.size,
|
||||
order.data._name,
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
def next(self):
|
||||
# bar线计数初始化
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
# 时间轴
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
# 更新跟踪止损价格
|
||||
def 每日重置数据():
|
||||
# 获取当前时间
|
||||
current_time = dt.time()
|
||||
# print(current_time)
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
|
||||
# 创建一个标志变量
|
||||
clearing_executed = False
|
||||
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
# 如果不在任何时间范围内,可以执行其他操作
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
# self.delta_cumsum=[]
|
||||
# self.deltas_list=[]
|
||||
# print('rinei_ma',self.rinei_ma)
|
||||
clearing_executed = False
|
||||
pass
|
||||
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
# 过滤成交量为0或小于0
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
# print(f'volume,{self.data.volume[0]}')
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
# print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = (
|
||||
self.low[0] if self.long_trailing_stop_price < self.low[0] else self.long_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
# print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = (
|
||||
self.high[0] if self.high[0] < self.short_trailing_stop_price else self.short_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
# print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
# print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long > 0:
|
||||
if (
|
||||
self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
print(
|
||||
"--多头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position",
|
||||
"TR",
|
||||
self.out_long,
|
||||
"low",
|
||||
self.low[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if self.out_short > 0:
|
||||
if (
|
||||
self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
print(
|
||||
"--空头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position: ",
|
||||
"TR",
|
||||
self.out_short,
|
||||
"high",
|
||||
self.high[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_shor = 0
|
||||
self.pos = 0
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
print(
|
||||
"--多头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_L,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
print(
|
||||
"--空头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_S,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
# 更新最高价和最低价的列表
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
# 计算delta累计
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
# 将当前行数据添加到 DataFrame
|
||||
# new_row = {
|
||||
# 'datetime': dt,
|
||||
# 'high': self.data.high[0],
|
||||
# 'low': self.data.low[0],
|
||||
# 'close': self.data.close[0],
|
||||
# 'open': self.data.open[0],
|
||||
# 'delta': self.data.delta[0],
|
||||
# 'delta_cumsum': sum(self.deltas_list)
|
||||
# }
|
||||
# # 使用pandas.concat代替append
|
||||
# self.df = pd.concat([self.df, pd.DataFrame([new_row])], ignore_index=True)
|
||||
|
||||
# # 检查文件是否存在
|
||||
# csv_file_path = f"output.csv"
|
||||
# if os.path.exists(csv_file_path):
|
||||
# # 仅保存最后一行数据
|
||||
# self.df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
# else:
|
||||
# # 创建新文件并保存整个DataFrame
|
||||
# self.df.to_csv(csv_file_path, index=False)
|
||||
|
||||
#
|
||||
if run_kg == False: #
|
||||
# ————jerome注释:增加Boll函数测试
|
||||
upper, middle, lower = tb.BBANDS(np.array(self.deltas_list), timeperiod=14, nbdevup=2, nbdevdn=2, matype=0)
|
||||
upper_cum, middle_cum, lower_cum = tb.BBANDS(
|
||||
np.array(self.delta_cumsum), timeperiod=14, nbdevup=2, nbdevdn=2, matype=0
|
||||
)
|
||||
# ————jerome注释:增加Boll函数测试
|
||||
# jerome注释:self.signal[0] >1 1为堆积信号
|
||||
# 开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] >1 and self.data.delta[0]>middle[-1] and self.delta_cumsum[-1]>middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]>0 and self.delta_cumsum[-1]>2000
|
||||
# 开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-1 and self.data.delta[0]<middle[-1] and self.delta_cumsum[-1]<middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]<-0 and self.delta_cumsum[-1]<-2000
|
||||
# 平多条件=self.pos<0 and self.signal[0] >1
|
||||
# 平空条件=self.pos>0 and self.signal[0] <-1
|
||||
开多组合 = (
|
||||
self.rinei_mean > 0
|
||||
and self.closes[0] > self.rinei_mean
|
||||
and self.signal[0] > 2
|
||||
and self.data.delta[0] > 600
|
||||
and self.delta_cumsum[-1] > 200
|
||||
) # jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]>0 and self.delta_cumsum[-1]>2000
|
||||
开空组合 = (
|
||||
self.rinei_mean > 0
|
||||
and self.closes[0] < self.rinei_mean
|
||||
and self.signal[0] < -2
|
||||
and self.data.delta[0] < -600
|
||||
and self.delta_cumsum[-1] < -200
|
||||
) # jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]<-0 and self.delta_cumsum[-1]<-2000
|
||||
平多条件 = self.pos < 0 and self.signal[0] > 2
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -2
|
||||
if self.pos != 1: #
|
||||
if 平多条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合: #
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存多头价格: ',self.long_trailing_stop_price)
|
||||
|
||||
if self.pos != -1: #
|
||||
if 平空条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合: #
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存空头价格: ',self.short_trailing_stop_price)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 创建Cerebro实例
|
||||
|
||||
cerebro = bt.Cerebro()
|
||||
# 数据
|
||||
csv_file = (
|
||||
r"E:\of_data\主力连续\tick生成的OF数据(1M)\data_rs_merged\中金所\IM888\IM888_rs_2023_1T_back_ofdata_dj.csv"
|
||||
)
|
||||
png_filepath = r"E:\of_data\主力连续\tick生成的OF数据(1M)\data_rs_merged\中金所\IM888\部分回测报告"
|
||||
# 从CSV文件加载数据
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2023, 1, 1),
|
||||
todate=datetime(2023, 12, 29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
|
||||
# 添加数据到Cerebro实例
|
||||
cerebro.adddata(data)
|
||||
|
||||
# 添加策略到Cerebro实例
|
||||
cerebro.addstrategy(MyStrategy_固定止损_跟踪止盈)
|
||||
|
||||
# 添加观察者和分析器到Cerebro实例
|
||||
# cerebro.addobserver(bt.observers.BuySell)
|
||||
cerebro.addobserver(bt.observers.Value)
|
||||
cerebro.addanalyzer(bt.analyzers.Returns, _name="returns")
|
||||
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
|
||||
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trades")
|
||||
初始资金 = 300000
|
||||
cerebro.broker.setcash(初始资金) # 设置初始资金
|
||||
|
||||
# 手续费,单手保证金,合约倍数
|
||||
cerebro.broker.setcommission(commission=30, margin=180000.0, mult=300) # 回测参数
|
||||
|
||||
# 运行回测
|
||||
result = cerebro.run()
|
||||
|
||||
# 获取策略分析器中的结果
|
||||
analyzer = result[0].analyzers
|
||||
total_trades = analyzer.trades.get_analysis()["total"]["total"]
|
||||
winning_trades = analyzer.trades.get_analysis()["won"]["total"]
|
||||
# 获取TradeAnalyzer分析器的结果
|
||||
trade_analyzer_result = analyzer.trades.get_analysis()
|
||||
# 获取总收益额
|
||||
total_profit = trade_analyzer_result.pnl.net.total
|
||||
|
||||
if total_trades > 0:
|
||||
win_rate = winning_trades / total_trades
|
||||
else:
|
||||
win_rate = 0.0
|
||||
# 打印回测报告
|
||||
print("回测报告:")
|
||||
print("期初权益", 初始资金)
|
||||
print("期末权益", 初始资金 + round(total_profit))
|
||||
print("盈亏额", round(total_profit))
|
||||
print("最大回撤率,", round(analyzer.drawdown.get_analysis()["drawdown"], 2), "%")
|
||||
print("胜率,", round(win_rate * 100, 2), "%")
|
||||
print("交易次数,", total_trades)
|
||||
print("盈利次数,", winning_trades)
|
||||
print("亏损次数,", total_trades - winning_trades)
|
||||
print("总手续费+滑点,", 手续费汇总)
|
||||
手续费汇总 = 0
|
||||
|
||||
# 保存回测图像文件
|
||||
plot = cerebro.plot()[0][0]
|
||||
plot_filename = os.path.splitext(os.path.basename(csv_file))[0] + "ss" + "_plot.png"
|
||||
# plot_path = os.path.join('部分回测报告', plot_filename)
|
||||
if not os.path.exists(png_filepath):
|
||||
# os.mkdir(png_filepath)
|
||||
os.makedirs(png_filepath)
|
||||
plot_path = os.path.join(png_filepath, plot_filename)
|
||||
plot.savefig(plot_path)
|
||||
@@ -0,0 +1,523 @@
|
||||
"""
|
||||
以下是代码的详细说明:
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
1.
|
||||
导入必要的模块和库:
|
||||
backtrader 用于回测功能
|
||||
datetime 用于处理日期和时间
|
||||
GenericCSVData 用于从CSV文件加载数据
|
||||
numpy 用于数值操作
|
||||
time 用于时间相关操作
|
||||
matplotlib.pyplot 用于绘图
|
||||
|
||||
2. 定义自定义手续费模板MyCommission
|
||||
继承自bt.CommInfoBase
|
||||
|
||||
3.
|
||||
定义自定义数据源类 GenericCSV_SIG:
|
||||
继承自 GenericCSVData,并添加了两个额外的行:'sig'和'delta'
|
||||
定义了参数 'sig'和'delta'
|
||||
|
||||
4.
|
||||
定义 MyStrategy_固定止损_跟踪止盈 类:
|
||||
继承自 bt.Strategy(backtrader的基础策略类)
|
||||
定义了两个参数:trailing_stop_percent 和 fixed_stop_loss_percent
|
||||
初始化策略并设置各种变量和指标
|
||||
实现了 next 方法,该方法在数据源的每个新的K线出现时被调用
|
||||
根据当前K线数据更新跟踪止盈价格
|
||||
实现了跟踪止盈出场和固定止损出场
|
||||
根据信号处理多头和空头仓位
|
||||
在策略执行过程中打印调试信息
|
||||
|
||||
5.
|
||||
if __name__ == "__main__": 代码块:
|
||||
使用 Cerebro 实例设置回测环境
|
||||
使用 GenericCSV_SIG 数据源从CSV文件加载数据
|
||||
将数据源和策略添加到 Cerebro 实例中
|
||||
添加观察者和分析器以评估性能
|
||||
设置初始资金和经纪人参数
|
||||
运行回测并获取结果
|
||||
打印回测报告,包括收益率、回撤、胜率和交易统计数据
|
||||
|
||||
6.使用前事项:
|
||||
1、主程序中修改ofdata_dj文件地址、png_filepath地址
|
||||
2、修改clearing_time2_start、clearing_time2_stop
|
||||
3、修改交易参数:lots、跟踪止损百分、固定止损百分比、duiji、cout_delta、delta
|
||||
4、修改资金参数:初始资金;回测参数:回测时间段、佣金、单边保证金、手续费;
|
||||
"""
|
||||
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import os
|
||||
|
||||
import talib as tb # jerom注释: 增加talib库
|
||||
|
||||
手续费汇总 = 0
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
# 从基类继承,添加一个 'sig',‘delta’行
|
||||
lines = ("sig", "delta")
|
||||
# 添加参数为从基类继承的参数
|
||||
params = (("sig", 6), ("delta", 8))
|
||||
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
("trailing_stop_percent", 0.005), # 跟踪止盈百分比
|
||||
("fixed_stop_loss_percent", 0.01), # 固定止损百分比
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots = 1 # 下单手数
|
||||
|
||||
self.signal = self.datas[0].sig # 使用sig字段作为策略的信号字段
|
||||
self.delta = self.datas[0].delta
|
||||
# 获取数据序列别名列表
|
||||
line_aliases = self.datas[0].getlinealiases()
|
||||
self.pos = 0
|
||||
print(line_aliases)
|
||||
self.high = self.datas[0].high
|
||||
self.low = self.datas[0].low
|
||||
self.closes = self.datas[0].close
|
||||
self.open = self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
# 240884432
|
||||
self.out_short = 0
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.rinei_mean = 0
|
||||
self.reniei_aroon_up = []
|
||||
self.reniei_aroon_down = []
|
||||
|
||||
self.datetime_list = []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum = []
|
||||
|
||||
self.barN = 0
|
||||
self.df = pd.DataFrame(columns=["datetime", "high", "low", "close", "open", "delta", "delta_cumsum"])
|
||||
|
||||
self.trader_df = pd.DataFrame(columns=["open", "high", "low", "close", "volume", "openInterest", "delta"])
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
"""可选,构建策略打印日志的函数:可用于打印订单记录或交易记录等"""
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print("%s, %s" % (dt.isoformat(), txt))
|
||||
|
||||
def notify_order(self, order):
|
||||
# 未被处理的订单
|
||||
if order.status in [order.Submitted, order.Accepted]:
|
||||
return
|
||||
# 已经处理的订单
|
||||
if order.status in [order.Completed, order.Canceled, order.Margin]:
|
||||
global 手续费汇总
|
||||
if order.isbuy():
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"BUY EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref, # 订单编号
|
||||
order.executed.price, # 成交价
|
||||
order.executed.comm, # 佣金
|
||||
order.executed.size, # 成交量
|
||||
order.data._name, # 品种名称
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
else: # Sell
|
||||
手续费汇总 += order.executed.comm
|
||||
self.log(
|
||||
"SELL EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f"
|
||||
% (
|
||||
order.ref,
|
||||
order.executed.price,
|
||||
order.executed.comm,
|
||||
order.executed.size,
|
||||
order.data._name,
|
||||
手续费汇总,
|
||||
)
|
||||
)
|
||||
|
||||
def next(self):
|
||||
# 公众号:松鼠Quant
|
||||
# 主页:www.quant789.com
|
||||
# 本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
# 版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
# bar线计数初始化
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
# 时间轴
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
# 更新跟踪止损价格
|
||||
def 每日重置数据():
|
||||
# 获取当前时间
|
||||
current_time = dt.time()
|
||||
# print(current_time)
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(2, 25)
|
||||
clearing_time2_end = s_time(2, 30)
|
||||
|
||||
# 创建一个标志变量
|
||||
clearing_executed = False
|
||||
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed:
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed:
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma = []
|
||||
self.renei_high_ma = []
|
||||
self.renei_low_ma = []
|
||||
self.delta_cumsum = []
|
||||
self.deltas_list = []
|
||||
# 如果不在任何时间范围内,可以执行其他操作
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.renei_high_ma.append(self.high[0])
|
||||
self.renei_low_ma.append(self.low[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
self.reniei_aroon_up, self.reniei_aroon_down = tb.AROON(
|
||||
np.array(self.renei_high_ma), np.array(self.renei_low_ma), 10
|
||||
)
|
||||
# self.delta_cumsum=[]
|
||||
# self.deltas_list=[]
|
||||
# print('rinei_ma',self.rinei_ma)
|
||||
clearing_executed = False
|
||||
pass
|
||||
|
||||
return clearing_executed
|
||||
|
||||
run_kg = 每日重置数据()
|
||||
|
||||
# 过滤成交量为0或小于0
|
||||
if self.data.volume[0] <= 0:
|
||||
return
|
||||
# print(f'volume,{self.data.volume[0]}')
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
# print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = (
|
||||
self.low[0] if self.long_trailing_stop_price < self.low[0] else self.long_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
# print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = (
|
||||
self.high[0] if self.high[0] < self.short_trailing_stop_price else self.short_trailing_stop_price
|
||||
)
|
||||
|
||||
# print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short = self.short_trailing_stop_price * (1 + self.trailing_stop_percent)
|
||||
# print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
# print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long > 0:
|
||||
if (
|
||||
self.low[0] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and self.low[0] > self.sl_long_price
|
||||
):
|
||||
print(
|
||||
"--多头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position",
|
||||
"TR",
|
||||
self.out_long,
|
||||
"low",
|
||||
self.low[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
|
||||
if self.out_short > 0:
|
||||
if (
|
||||
self.high[0] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and self.high[0] < self.sl_shor_price
|
||||
):
|
||||
print(
|
||||
"--空头止盈出场datetime+sig: ",
|
||||
dt,
|
||||
"Trailing stop triggered: Closing position: ",
|
||||
"TR",
|
||||
self.out_short,
|
||||
"high",
|
||||
self.high[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_shor = 0
|
||||
self.pos = 0
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and self.closes[0] < self.fixed_stop_loss_L
|
||||
):
|
||||
print(
|
||||
"--多头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_L,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and self.closes[0] > self.fixed_stop_loss_S
|
||||
):
|
||||
print(
|
||||
"--空头止损datetime+sig: ",
|
||||
dt,
|
||||
"Fixed stop loss triggered: Closing position",
|
||||
"SL",
|
||||
self.fixed_stop_loss_S,
|
||||
"close",
|
||||
self.closes[0],
|
||||
)
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
# 更新最高价和最低价的列表
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
# 计算delta累计
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
# 将当前行数据添加到 DataFrame
|
||||
# new_row = {
|
||||
# 'datetime': dt,
|
||||
# 'high': self.data.high[0],
|
||||
# 'low': self.data.low[0],
|
||||
# 'close': self.data.close[0],
|
||||
# 'open': self.data.open[0],
|
||||
# 'delta': self.data.delta[0],
|
||||
# 'delta_cumsum': sum(self.deltas_list)
|
||||
# }
|
||||
# # 使用pandas.concat代替append
|
||||
# self.df = pd.concat([self.df, pd.DataFrame([new_row])], ignore_index=True)
|
||||
|
||||
# # 检查文件是否存在
|
||||
# csv_file_path = f"output.csv"
|
||||
# if os.path.exists(csv_file_path):
|
||||
# # 仅保存最后一行数据
|
||||
# self.df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
# else:
|
||||
# # 创建新文件并保存整个DataFrame
|
||||
# self.df.to_csv(csv_file_path, index=False)
|
||||
|
||||
#
|
||||
if run_kg is False: #
|
||||
# ————jerome注释:增加Boll函数测试
|
||||
upper, middle, lower = tb.BBANDS(np.array(self.deltas_list), timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
|
||||
upper_cum, middle_cum, lower_cum = tb.BBANDS(
|
||||
np.array(self.delta_cumsum), timeperiod=5, nbdevup=2, nbdevdn=2, matype=0
|
||||
)
|
||||
# ————jerome注释:增加Boll函数测试
|
||||
# jerome注释:self.signal[0] >1 1为堆积信号
|
||||
# 开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] >1 and self.data.delta[0]>middle[-1] and self.delta_cumsum[-1]>middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]>0 and self.delta_cumsum[-1]>2000
|
||||
# 开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-1 and self.data.delta[0]<middle[-1] and self.delta_cumsum[-1]<middle_cum[-1]#jerome注释:self.signal[0] >1 1为堆积信号,and self.data.delta[0]<-0 and self.delta_cumsum[-1]<-2000
|
||||
开多组合 = (
|
||||
self.reniei_aroon_up[-1] > 50
|
||||
and self.reniei_aroon_up[-1] > self.reniei_aroon_down[-1]
|
||||
# self.rinei_mean > 0
|
||||
# and self.closes[0] > self.rinei_mean
|
||||
and self.signal[0] > 2
|
||||
and self.data.delta[0] > 500000
|
||||
and self.delta_cumsum[-1] > 500000
|
||||
)
|
||||
开空组合 = (
|
||||
self.reniei_aroon_down[-1] > 50
|
||||
and self.reniei_aroon_up[-1] < self.reniei_aroon_down[-1]
|
||||
# self.rinei_mean > 0
|
||||
# and self.closes[0] < self.rinei_mean
|
||||
and self.signal[0] < -2
|
||||
and self.data.delta[0] < -500000
|
||||
and self.delta_cumsum[-1] < -500000
|
||||
)
|
||||
平多条件 = self.pos < 0 and self.signal[0] > 2
|
||||
平空条件 = self.pos > 0 and self.signal[0] < -2
|
||||
if self.pos != 1: #
|
||||
if 平多条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合: #
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = self.low[0]
|
||||
self.sl_long_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存多头价格: ',self.long_trailing_stop_price)
|
||||
|
||||
if self.pos != -1: #
|
||||
if 平空条件:
|
||||
# print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合: #
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = self.high[0]
|
||||
self.sl_shor_price = self.data.open[0]
|
||||
# print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存空头价格: ',self.short_trailing_stop_price)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 公众号:松鼠Quant
|
||||
# 主页:www.quant789.com
|
||||
# 本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
# 版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
# 创建Cerebro实例
|
||||
|
||||
cerebro = bt.Cerebro()
|
||||
# 数据
|
||||
csv_file = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(2M)\data_rs_merged\中金所\IM888\IM888_rs_2022_2T_back_ofdata_dj_new.csv"
|
||||
png_filepath = r"D:\BaiduNetdiskDownload\主力连续\tick生成的OF数据(2M)\data_rs_merged\中金所\IM888\部分回测报告"
|
||||
# 从CSV文件加载数据
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2022, 1, 1),
|
||||
todate=datetime(2022, 12, 31),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat="%Y-%m-%d %H:%M:%S",
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8,
|
||||
)
|
||||
|
||||
# 添加数据到Cerebro实例
|
||||
cerebro.adddata(data)
|
||||
|
||||
# 添加策略到Cerebro实例
|
||||
cerebro.addstrategy(MyStrategy_固定止损_跟踪止盈)
|
||||
|
||||
# 添加观察者和分析器到Cerebro实例
|
||||
# cerebro.addobserver(bt.observers.BuySell)
|
||||
cerebro.addobserver(bt.observers.Value)
|
||||
cerebro.addanalyzer(bt.analyzers.Returns, _name="returns")
|
||||
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
|
||||
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trades")
|
||||
# cerebro.addanalyzer(bt.analyzers.sharpe, __name_= "sharpe")
|
||||
初始资金 = 300000
|
||||
cerebro.broker.setcash(初始资金) # 设置初始资金
|
||||
|
||||
# 手续费,单手保证金,合约倍数
|
||||
cerebro.broker.setcommission(commission=14, margin=150000.0, mult=300) # 回测参数
|
||||
|
||||
# 运行回测
|
||||
result = cerebro.run()
|
||||
|
||||
# 获取策略分析器中的结果
|
||||
analyzer = result[0].analyzers
|
||||
total_trades = analyzer.trades.get_analysis()["total"]["total"]
|
||||
winning_trades = analyzer.trades.get_analysis()["won"]["total"]
|
||||
# 获取TradeAnalyzer分析器的结果
|
||||
trade_analyzer_result = analyzer.trades.get_analysis()
|
||||
# 获取总收益额
|
||||
total_profit = trade_analyzer_result.pnl.net.total
|
||||
|
||||
if total_trades > 0:
|
||||
win_rate = winning_trades / total_trades
|
||||
else:
|
||||
win_rate = 0.0
|
||||
# 打印回测报告
|
||||
print("回测报告:")
|
||||
print("期初权益", 初始资金)
|
||||
print("期末权益", 初始资金 + round(total_profit))
|
||||
print("盈亏额", round(total_profit))
|
||||
print("最大回撤率,", round(analyzer.drawdown.get_analysis()["drawdown"], 2), "%")
|
||||
print("胜率,", round(win_rate * 100, 2), "%")
|
||||
print("交易次数,", total_trades)
|
||||
print("盈利次数,", winning_trades)
|
||||
print("亏损次数,", total_trades - winning_trades)
|
||||
print("总手续费+滑点,", 手续费汇总)
|
||||
手续费汇总 = 0
|
||||
|
||||
# 保存回测图像文件
|
||||
plot = cerebro.plot()[0][0]
|
||||
plot_filename = os.path.splitext(os.path.basename(csv_file))[0] + "ss" + "_plot.png"
|
||||
# plot_path = os.path.join('部分回测报告', plot_filename)
|
||||
if not os.path.exists(png_filepath):
|
||||
# os.mkdir(png_filepath)
|
||||
os.makedirs(png_filepath)
|
||||
plot_path = os.path.join(png_filepath, plot_filename)
|
||||
plot.savefig(plot_path)
|
||||
|
||||
|
||||
# 公众号:松鼠Quant
|
||||
# 主页:www.quant789.com
|
||||
# 本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
@@ -0,0 +1 @@
|
||||
IF2023:combo: (0.008, 0.008, 5, 200, 200), value: 433379.9999999999, best_value: 563755.9999999976, best_parameters: (0.002, 0.004, 3, 0, 0)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 231 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
for /f "tokens=2 delims=," %%a in ('tasklist /v /fo csv ^| findstr /i "real.py"') do taskkill /pid %%~a
|
||||
@@ -0,0 +1,74 @@
|
||||
'''
|
||||
Author: zhoujie2104231 zhoujie@me.com
|
||||
Date: 2024-03-02 16:20:40
|
||||
LastEditors: zhoujie2104231 zhoujie@me.com
|
||||
LastEditTime: 2024-04-10 10:02:34
|
||||
Description:
|
||||
|
||||
'''
|
||||
import subprocess
|
||||
import schedule
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
import os
|
||||
|
||||
# 获取当前工作目录
|
||||
current_directory = os.getcwd()
|
||||
print("当前工作目录:", current_directory)
|
||||
# 设置新的工作目录
|
||||
new_directory = "C:/real_trader"
|
||||
os.chdir(new_directory)
|
||||
# 验证新的工作目录
|
||||
updated_directory = os.getcwd()
|
||||
print("已更改为新的工作目录:", updated_directory)
|
||||
|
||||
|
||||
# 定义要启动的文件['real-a.py','real-ag.py','real-rb.py','real-hc.py']
|
||||
files_to_run = ['real.py']
|
||||
|
||||
|
||||
def run_scripts():
|
||||
print("启动程序...")
|
||||
for file in files_to_run:
|
||||
time.sleep(1)
|
||||
# 使用subprocess模块运行命令
|
||||
subprocess.Popen(['start', 'cmd', '/k', 'python', file], shell=True)
|
||||
print(file)
|
||||
print(datetime.now(),'程序重新启动完成,等待明天关闭重启')
|
||||
|
||||
|
||||
def close_scripts():
|
||||
print("关闭程序...")
|
||||
# 通过创建一个包含关闭指定窗口命令的批处理文件来关闭CMD窗口
|
||||
def close_specific_cmd_window(cmd_window_title):
|
||||
with open("close_cmd_window.bat", "w") as batch_file:
|
||||
batch_file.write(f'@echo off\nfor /f "tokens=2 delims=," %%a in (\'tasklist /v /fo csv ^| findstr /i "{cmd_window_title}"\') do taskkill /pid %%~a')
|
||||
|
||||
# 运行批处理文件
|
||||
subprocess.run("close_cmd_window.bat", shell=True)
|
||||
|
||||
|
||||
# 循环关闭所有脚本对应的CMD窗口
|
||||
for title in files_to_run:
|
||||
close_specific_cmd_window(title)
|
||||
print(datetime.now(),'已关闭程序,等待重新运行程序')
|
||||
|
||||
|
||||
|
||||
# 设置定时任务,关闭程序
|
||||
schedule.every().day.at("15:30").do(close_scripts)
|
||||
schedule.every().day.at("03:00").do(close_scripts)
|
||||
|
||||
# 设置定时任务,启动程序
|
||||
schedule.every().day.at("08:55").do(run_scripts)
|
||||
schedule.every().day.at("20:55").do(run_scripts)
|
||||
|
||||
|
||||
|
||||
# 保持脚本运行,等待定时任务触发
|
||||
#240884432
|
||||
while True:
|
||||
schedule.run_pending()
|
||||
time.sleep(1)
|
||||
#240884432
|
||||
@@ -0,0 +1,895 @@
|
||||
'''
|
||||
该代码的主要目的是处理Tick数据并生成交易信号。代码中定义了一个tickcome函数,它接收到Tick数据后会进行一系列的处理,包括构建Tick字典、更新上一个Tick的成交量、保存Tick数据、生成K线数据等。其中涉及到的一些函数有:
|
||||
|
||||
on_tick(tick): 处理单个Tick数据,根据Tick数据生成K线数据。
|
||||
tickdata(df, symbol): 处理Tick数据,生成K线数据。
|
||||
orderflow_df_new(df_tick, df_min, symbol): 处理Tick和K线数据,生成订单流数据。
|
||||
GetOrderFlow_dj(kData): 计算订单流的信号指标。
|
||||
除此之外,代码中还定义了一个MyTrader类,继承自TraderApiBase,用于实现交易相关的功能。
|
||||
'''
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from multiprocessing import Process, Queue
|
||||
import queue
|
||||
import threading
|
||||
from AlgoPlus.CTP.MdApi import run_tick_engine
|
||||
from AlgoPlus.CTP.FutureAccount import get_simulate_account
|
||||
from AlgoPlus.CTP.FutureAccount import FutureAccount
|
||||
from AlgoPlus.CTP.TraderApiBase import TraderApiBase
|
||||
from AlgoPlus.ta.time_bar import tick_to_bar
|
||||
import pandas as pd
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import time as s_time
|
||||
import operator
|
||||
import time
|
||||
import numpy as np
|
||||
import os
|
||||
import re
|
||||
|
||||
# 加入邮件通知
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText # 导入 MIMEText 类发送纯文本邮件
|
||||
from email.mime.multipart import MIMEMultipart # 导入 MIMEMultipart 类发送带有附件的邮件
|
||||
from email.mime.application import MIMEApplication # 导入 MIMEApplication 类发送二进制附件
|
||||
|
||||
## 配置邮件信息
|
||||
receivers = ["240884432@qq.com"] # 设置邮件接收人地址
|
||||
subject = "订单流策略交易信号" # 设置邮件主题
|
||||
#text = " " # 设置邮件正文
|
||||
# file_path = "test.txt" # 设置邮件附件文件路径
|
||||
|
||||
## 配置邮件服务器信息
|
||||
smtp_server = "smtp.qq.com" # 设置发送邮件的 SMTP 服务器地址
|
||||
smtp_port = 465 # 设置发送邮件的 SMTP 服务器端口号,一般为 25 端口 465
|
||||
sender = "240884432@qq.com" # 设置发送邮件的邮箱地址
|
||||
username = "240884432@qq.com" # 设置发送邮件的邮箱用户名
|
||||
password = "osjyjmbqrzxtbjbf" #zrmpcgttataabhjh,设置发送邮件的邮箱密码或授权码
|
||||
|
||||
tickdatadict = {} # 存储Tick数据的字典
|
||||
quotedict = {} # 存储行情数据的字典
|
||||
ofdatadict = {} # 存储K线数据的字典
|
||||
trade_dfs = {} #pd.DataFrame({}) # 存储交易数据的DataFrame对象
|
||||
previous_volume = {} # 上一个Tick的成交量
|
||||
tsymbollist={}
|
||||
|
||||
# 日盘商品期货交易品种
|
||||
commodity_day_dict = {'bb': s_time(15,00), 'jd': s_time(15,00), 'lh': s_time(15,00), 'l': s_time(15,00), 'fb': s_time(15,00), 'ec': s_time(15,00),
|
||||
'AP': s_time(15,00), 'CJ': s_time(15,00), 'JR': s_time(15,00), 'LR': s_time(15,00), 'RS': s_time(15,00), 'PK': s_time(15,00),
|
||||
'PM': s_time(15,00), 'PX': s_time(15,00), 'RI': s_time(15,00), 'SF': s_time(15,00), 'SM': s_time(15,00), 'UR': s_time(15,00),
|
||||
'WH': s_time(15,00), 'ao': s_time(15,00), 'br': s_time(15,00), 'wr': s_time(15,00),}
|
||||
|
||||
# 夜盘商品期货交易品种
|
||||
commodity_night_dict = {'sc': s_time(2,30), 'bc': s_time(1,0), 'lu': s_time(23,0), 'nr': s_time(23,0),'au': s_time(2,30), 'ag': s_time(2,30),
|
||||
'ss': s_time(1,0), 'sn': s_time(1,0), 'ni': s_time(1,0), 'pb': s_time(1,0),'zn': s_time(1,0), 'al': s_time(1,0), 'cu': s_time(1,0),
|
||||
'ru': s_time(23,0), 'rb': s_time(23,0), 'hc': s_time(23,0), 'fu': s_time(23,0), 'bu': s_time(23,0), 'sp': s_time(23,0),
|
||||
'PF': s_time(23,0), 'SR': s_time(23,0), 'CF': s_time(23,0), 'CY': s_time(23,0), 'RM': s_time(23,0), 'MA': s_time(23,0),
|
||||
'TA': s_time(23,0), 'ZC': s_time(23,0), 'FG': s_time(23,0), 'OI': s_time(23,0), 'SA': s_time(23,0),
|
||||
'p': s_time(23,0), 'j': s_time(23,0), 'jm': s_time(23,0), 'i': s_time(23,0), 'l': s_time(23,0), 'v': s_time(23,0),
|
||||
'pp': s_time(23,0), 'eg': s_time(23,0), 'c': s_time(23,0), 'cs': s_time(23,0), 'y': s_time(23,0), 'm': s_time(23,0),
|
||||
'a': s_time(23,0), 'b': s_time(23,0), 'rr': s_time(23,0), 'eb': s_time(23,0), 'pg': s_time(23,0), 'SH': s_time(23,00)}
|
||||
|
||||
# 金融期货交易品种
|
||||
financial_time_dict = {'IH': s_time(15,00), 'IF': s_time(15,00), 'IC': s_time(15,00), 'IM': s_time(15,00),'T': s_time(15,15), 'TS': s_time(15,15),
|
||||
'TF': s_time(15,15), 'TL': s_time(15,15)}
|
||||
|
||||
fees_df = pd.read_csv('./futures_fees_info.csv', header = 0, usecols= [1, 4, 17, 19, 25],names=['合约', '合约乘数', '做多保证金率', '做空保证金率', '品种代码'])
|
||||
contacts_df = pd.read_csv('./main_contacts.csv', header = 0, usecols= [16, 17],names=['主连代码', '品种代码'])
|
||||
|
||||
#交易程序---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
class ParamObj:
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
symbol = None #合约名称
|
||||
Lots = None #下单手数
|
||||
py = None #设置委托价格的偏移,更加容易促成成交
|
||||
trailing_stop_percent = None #跟踪出场参数
|
||||
fixed_stop_loss_percent = None #固定出场参数
|
||||
dj_X = None #开仓的堆积参数
|
||||
delta = None #开仓的delta参数
|
||||
sum_delta = None #开仓的delta累积参数
|
||||
失衡=None
|
||||
堆积=None
|
||||
周期=None
|
||||
|
||||
# 策略需要用到的变量
|
||||
cont_df = 0
|
||||
pos = 0
|
||||
short_trailing_stop_price = 0
|
||||
long_trailing_stop_price = 0
|
||||
sl_long_price = 0
|
||||
sl_shor_price = 0
|
||||
out_long = 0
|
||||
out_short = 0
|
||||
clearing_executed = False
|
||||
kgdata = True
|
||||
|
||||
def __init__(self, symbol, Lots, py, trailing_stop_percent, fixed_stop_loss_percent, dj_X, delta, sum_delta,失衡,堆积,周期):
|
||||
self.symbol = symbol
|
||||
self.Lots = Lots
|
||||
self.py = py
|
||||
self.trailing_stop_percent = trailing_stop_percent
|
||||
self.fixed_stop_loss_percent = fixed_stop_loss_percent
|
||||
self.dj_X = dj_X
|
||||
self.delta = delta
|
||||
self.sum_delta = sum_delta
|
||||
self.失衡=失衡
|
||||
self.堆积=堆积
|
||||
self.周期=周期
|
||||
|
||||
class MyTrader(TraderApiBase):
|
||||
def __init__(self, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
self.param_dict = {}
|
||||
self.queue_dict = {}
|
||||
self.品种=' '
|
||||
|
||||
def tickcome(self,md_queue):
|
||||
global previous_volume
|
||||
data=md_queue
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
ActionDay = data['ActionDay'].decode() # 交易日日期
|
||||
update_time = data['UpdateTime'].decode() # 更新时间
|
||||
|
||||
update_millisec = str(data['UpdateMillisec']) # 更新毫秒数
|
||||
created_at = ActionDay[:4] + '-' + ActionDay[4:6] + '-' + ActionDay[6:] + ' ' + update_time + '.' + update_millisec #创建时间
|
||||
# 构建tick字典
|
||||
tick = {
|
||||
'symbol': instrument_id, # 品种代码和交易所ID
|
||||
'created_at':datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S.%f"),
|
||||
#'created_at': created_at, # 创建时间
|
||||
'price': float(data['LastPrice']), # 最新价
|
||||
'last_volume': int(data['Volume']) - previous_volume.get(instrument_id, 0) if previous_volume.get(instrument_id, 0) != 0 else 0, # 瞬时成交量
|
||||
'bid_p': float(data['BidPrice1']), # 买价
|
||||
'bid_v': int(data['BidVolume1']), # 买量
|
||||
'ask_p': float(data['AskPrice1']), # 卖价
|
||||
'ask_v': int(data['AskVolume1']), # 卖量
|
||||
'UpperLimitPrice': float(data['UpperLimitPrice']), # 涨停价
|
||||
'LowerLimitPrice': float(data['LowerLimitPrice']), # 跌停价
|
||||
'TradingDay': data['TradingDay'].decode(), # 交易日日期
|
||||
'cum_volume': int(data['Volume']), # 最新总成交量
|
||||
'cum_amount': float(data['Turnover']), # 最新总成交额
|
||||
'cum_position': int(data['OpenInterest']), # 合约持仓量
|
||||
}
|
||||
# print('&&&&&&&&',instrument_id, tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 更新上一个Tick的成交量
|
||||
previous_volume[instrument_id] = int(data['Volume'])
|
||||
if tick['last_volume']>0:
|
||||
#print(tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 处理Tick数据
|
||||
self.on_tick(tick)
|
||||
|
||||
def can_time(self,hour, minute):
|
||||
hour = str(hour)
|
||||
minute = str(minute)
|
||||
if len(minute) == 1:
|
||||
minute = "0" + minute
|
||||
return int(hour + minute)
|
||||
|
||||
def on_tick(self,tick):
|
||||
|
||||
tm=self.can_time(tick['created_at'].hour,tick['created_at'].minute)
|
||||
#print(tick['symbol'])
|
||||
#print(1)
|
||||
#if tm>1500 and tm<2100 :
|
||||
# return
|
||||
if tick['last_volume']==0:
|
||||
return
|
||||
quotes = tick
|
||||
timetick=str(tick['created_at']).replace('+08:00', '')
|
||||
tsymbol=tick['symbol']
|
||||
if tsymbol not in tsymbollist.keys():
|
||||
# 获取tick的买卖价和买卖量
|
||||
|
||||
tsymbollist[tsymbol]=tick
|
||||
bid_p=quotes['bid_p']
|
||||
ask_p=quotes['ask_p']
|
||||
bid_v=quotes['bid_v']
|
||||
ask_v=quotes['ask_v']
|
||||
else:
|
||||
# 获取上一个tick的买卖价和买卖量
|
||||
rquotes =tsymbollist[tsymbol]
|
||||
bid_p=rquotes['bid_p']
|
||||
ask_p=rquotes['ask_p']
|
||||
bid_v=rquotes['bid_v']
|
||||
ask_v=rquotes['ask_v']
|
||||
tsymbollist[tsymbol]=tick
|
||||
tick_dt=pd.DataFrame({'datetime':timetick,'symbol':tick['symbol'],'mainsym':tick['symbol'].rstrip('0123456789').upper(),'lastprice':tick['price'],
|
||||
'vol':tick['last_volume'],
|
||||
'bid_p':bid_p,'ask_p':ask_p,'bid_v':bid_v,'ask_v':ask_v},index=[0])
|
||||
sym = tick_dt['symbol'][0]
|
||||
#print(tick_dt)
|
||||
self.tickdata(tick_dt,sym)
|
||||
|
||||
def data_of(self,symbol, df):
|
||||
global trade_dfs
|
||||
# 将df数据合并到trader_df中
|
||||
# if symbol not in trade_dfs.keys():
|
||||
# trade_df = pd.DataFrame({})
|
||||
# else:
|
||||
# trade_df = trade_dfs[symbol]
|
||||
trade_dfs[symbol] = pd.concat([trade_dfs[symbol], df], ignore_index=True)
|
||||
# print('!!!!!!!!!!!trader_df: ', symbol, df['datetime'].iloc[-1])
|
||||
#print(trader_df)
|
||||
|
||||
def process(self,bidDict, askDict, symbol):
|
||||
try:
|
||||
# 尝试从quotedict中获取对应品种的报价数据
|
||||
dic = quotedict[symbol]
|
||||
bidDictResult = dic['bidDictResult']
|
||||
askDictResult = dic['askDictResult']
|
||||
except:
|
||||
# 如果获取失败,则初始化bidDictResult和askDictResult为空字典
|
||||
bidDictResult, askDictResult = {}, {}
|
||||
|
||||
# 将所有买盘字典和卖盘字典的key合并,并按升序排序
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
|
||||
# 遍历所有的key,将相同key的值进行累加
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
if s in bidDictResult:
|
||||
bidDictResult[s] = int(bidDict[s]) + bidDictResult[s]
|
||||
else:
|
||||
bidDictResult[s] = int(bidDict[s])
|
||||
if s not in askDictResult:
|
||||
askDictResult[s] = 0
|
||||
else:
|
||||
if s in askDictResult:
|
||||
askDictResult[s] = int(askDict[s]) + askDictResult[s]
|
||||
else:
|
||||
askDictResult[s] = int(askDict[s])
|
||||
if s not in bidDictResult:
|
||||
bidDictResult[s] = 0
|
||||
|
||||
# 构建包含bidDictResult和askDictResult的字典,并存入quotedict中
|
||||
df = {'bidDictResult': bidDictResult, 'askDictResult': askDictResult}
|
||||
quotedict[symbol] = df
|
||||
|
||||
return bidDictResult, askDictResult
|
||||
|
||||
def tickdata(self,df,symbol):
|
||||
tickdata =pd.DataFrame({'datetime':df['datetime'],'symbol':df['symbol'],'lastprice':df['lastprice'],
|
||||
'volume':df['vol'],'bid_p':df['bid_p'],'bid_v':df['bid_v'],'ask_p':df['ask_p'],'ask_v':df['ask_v']})
|
||||
try:
|
||||
if symbol in tickdatadict.keys():
|
||||
rdf=tickdatadict[symbol]
|
||||
rdftm=pd.to_datetime(rdf['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
now=str(tickdata['datetime'][0])
|
||||
if now>rdftm:
|
||||
try:
|
||||
oo=ofdatadict[symbol]
|
||||
self.data_of(symbol, oo)
|
||||
#print('oo',oo)
|
||||
if symbol in quotedict.keys():
|
||||
quotedict.pop(symbol)
|
||||
if symbol in tickdatadict.keys():
|
||||
tickdatadict.pop(symbol)
|
||||
if symbol in ofdatadict.keys():
|
||||
ofdatadict.pop(symbol)
|
||||
except IOError as e:
|
||||
print('rdftm捕获到异常',e)
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
else:
|
||||
tickdata['bartime'] = rdf['bartime']
|
||||
tickdata['open'] = rdf['open']
|
||||
tickdata['high'] = max(tickdata['lastprice'].values,rdf['high'].values)
|
||||
tickdata['low'] = min(tickdata['lastprice'].values,rdf['low'].values)
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['volume']=df['vol']+rdf['volume'].values
|
||||
tickdata['starttime'] = rdf['starttime']
|
||||
else :
|
||||
print('新bar的第一个tick进入')
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
except IOError as e:
|
||||
print('捕获到异常',e)
|
||||
|
||||
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['bartime'])
|
||||
param = self.param_dict[self.品种]
|
||||
bardata = tickdata.resample(on = 'bartime',rule = param.周期,label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
bardata['bartime'] = pd.to_datetime(bardata['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
tickdatadict[symbol]=bardata
|
||||
tickdata['volume']=df['vol'].values
|
||||
#print(bardata['symbol'].values,bardata['bartime'].values)
|
||||
self.orderflow_df_new(tickdata,bardata,symbol)
|
||||
# time.sleep(0.5)
|
||||
|
||||
def orderflow_df_new(self,df_tick,df_min,symbol):
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
#endArray = pd.to_datetime(df_min['bartime']).values
|
||||
endArray = df_min['bartime'].values
|
||||
#print(endArray)
|
||||
deltaArray = np.zeros((len(endArray),))
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
dt=endArray[index]
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
# for indexTick in range(indexFinal,len(df_tick)):
|
||||
# if tTickArray[indexTick] >= tEnd:
|
||||
# break
|
||||
# elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] < tEnd):
|
||||
Bp = round(bp1TickArray[0],4)
|
||||
Ap = round(ap1TickArray[0],4)
|
||||
LastPrice = round(lastTickArray[0],4)
|
||||
Volume = volumeTickArray[0]
|
||||
if LastPrice >= Ap:
|
||||
if str(LastPrice) in askDict.keys():
|
||||
askDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
askDict[str(LastPrice)] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if str(LastPrice) in bidDict.keys():
|
||||
bidDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
bidDict[str(LastPrice)] = Volume
|
||||
# indexFinal = indexTick
|
||||
bidDictResult,askDictResult = self.process(bidDict,askDict,symbol)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
#print(prinslist,asklist,bidlist)
|
||||
#print(len(prinslist),len(bidDictResult),len(askDictResult))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
#df=pd.DataFrame({'price':pd.Series(bidDictResult.keys()),'Ask':pd.Series(askDictResult.values()),'Bid':pd.Series(bidDictResult.values())})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
#df['ticktime']=tTickArray[0]
|
||||
df['dj'] = self.GetOrderFlow_dj(df)
|
||||
ofdatadict[symbol]=df
|
||||
|
||||
def GetOrderFlow_dj(self,kData):
|
||||
param = self.param_dict[self.品种]
|
||||
Config = {
|
||||
'Value1': param.失衡,
|
||||
'Value2': param.堆积,
|
||||
'Value4': True,
|
||||
}
|
||||
aryData = kData
|
||||
djcout = 0
|
||||
|
||||
# 遍历kData中的每一行,计算djcout指标
|
||||
for index, row in aryData.iterrows():
|
||||
kItem = aryData.iloc[index]
|
||||
high = kItem['high']
|
||||
low = kItem['low']
|
||||
close = kItem['close']
|
||||
open = kItem['open']
|
||||
dtime = kItem['datetime']
|
||||
price_s = kItem['price']
|
||||
Ask_s = kItem['Ask']
|
||||
Bid_s = kItem['Bid']
|
||||
delta = kItem['delta']
|
||||
|
||||
price_s = price_s
|
||||
Ask_s = Ask_s
|
||||
Bid_s = Bid_s
|
||||
|
||||
gj = 0
|
||||
xq = 0
|
||||
gxx = 0
|
||||
xxx = 0
|
||||
|
||||
# 遍历price_s中的每一个元素,计算相关指标
|
||||
for i in np.arange(0, len(price_s), 1):
|
||||
duiji = {
|
||||
'price': 0,
|
||||
'time': 0,
|
||||
'longshort': 0,
|
||||
}
|
||||
|
||||
if i == 0:
|
||||
delta = delta
|
||||
|
||||
order= {
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
#空头堆积
|
||||
if i >= 0 and i < len(price_s) - 1:
|
||||
if (order["Bid"]["Value"] > Ask_s[i + 1] * int(Config['Value1'])):
|
||||
gxx += 1
|
||||
gj += 1
|
||||
if gj >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = -1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += -1
|
||||
else:
|
||||
gj = 0
|
||||
#多头堆积
|
||||
if i >= 1 and i < len(price_s) - 1:
|
||||
if (order["Ask"]["Value"] > Bid_s[i - 1] * int(Config['Value1'])):
|
||||
xq += 1
|
||||
xxx += 1
|
||||
if xq >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = 1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += 1
|
||||
else:
|
||||
xq = 0
|
||||
|
||||
# 返回计算得到的djcout值
|
||||
return djcout
|
||||
|
||||
#读取保存的数据
|
||||
def read_to_csv(self,symbol):
|
||||
# 文件夹路径和文件路径
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
param = self.param_dict[symbol]
|
||||
# symbol = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
folder_path = "traderdata"
|
||||
file_path = os.path.join(folder_path, f"{str(symbol)}_traderdata.csv")
|
||||
# 如果文件夹不存在则创建
|
||||
if not os.path.exists(folder_path):
|
||||
os.makedirs(folder_path)
|
||||
|
||||
# 读取保留的模型数据CSV文件
|
||||
if os.path.exists(file_path):
|
||||
df = pd.read_csv(file_path)
|
||||
if not df.empty and param.kgdata==True:
|
||||
# 选择最后一行数据
|
||||
row = df.iloc[-1]
|
||||
|
||||
# 根据CSV文件的列名将数据赋值给相应的属性
|
||||
param.pos = int(row['pos'])
|
||||
param.short_trailing_stop_price = float(row['short_trailing_stop_price'])
|
||||
param.long_trailing_stop_price = float(row['long_trailing_stop_price'])
|
||||
param.sl_long_price = float(row['sl_long_price'])
|
||||
param.sl_shor_price = float(row['sl_shor_price'])
|
||||
# param.out_long = int(row['out_long'])
|
||||
# param.out_short = int(row['out_short'])
|
||||
print("找到历史交易数据文件,已经更新持仓,止损止盈数据", df.iloc[-1])
|
||||
param.kgdata=False
|
||||
else:
|
||||
pass
|
||||
#print("没有找到历史交易数据文件", file_path)
|
||||
#如果没有找到CSV,则初始化变量
|
||||
|
||||
pass
|
||||
|
||||
#保存数据
|
||||
def save_to_csv(self,symbol):
|
||||
param = self.param_dict[symbol]
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
# symbol = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
# 创建DataFrame
|
||||
|
||||
data = {
|
||||
'datetime': [trade_dfs[symbol]['datetime'].iloc[-1]],
|
||||
'pos': [param.pos],
|
||||
'short_trailing_stop_price': [param.short_trailing_stop_price],
|
||||
'long_trailing_stop_price': [param.long_trailing_stop_price],
|
||||
'sl_long_price': [param.sl_long_price],
|
||||
'sl_shor_price': [param.sl_shor_price],
|
||||
# 'out_long': [param.out_long],
|
||||
# 'out_short': [param.out_short]
|
||||
}
|
||||
|
||||
df = pd.DataFrame(data)
|
||||
|
||||
# 将DataFrame保存到CSV文件
|
||||
df.to_csv(f"traderdata/{str(symbol)}_traderdata.csv", index=False)
|
||||
|
||||
#每日收盘重置数据
|
||||
def day_data_reset(self, symbol):
|
||||
param = self.param_dict[symbol]
|
||||
sec = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
# 获取当前时间
|
||||
current_time = datetime.now().time()
|
||||
|
||||
# 第一时间范围(日盘收盘)
|
||||
clearing_time1_start = s_time(15,00)
|
||||
clearing_time1_end = s_time(15,15)
|
||||
|
||||
# 创建一个标志变量,用于记录是否已经执行过
|
||||
param.clearing_executed = False
|
||||
# 检查当前时间第一个操作的时间范围内
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not param.clearing_executed :
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
trade_dfs[symbol].drop(trade_dfs[symbol].index,inplace=True)#清除当天的行情数据
|
||||
|
||||
# 检查当前时间是否在第二个操作的时间范围内(夜盘收盘)
|
||||
elif sec in commodity_night_dict.keys():
|
||||
clearing_time2_start = commodity_night_dict[sec]
|
||||
clearing_time2_end = s_time(clearing_time2_start.hour, clearing_time2_start.minute+15)
|
||||
if clearing_time2_start <= current_time <= clearing_time2_end and not param.clearing_executed :
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
trade_dfs[symbol].drop(trade_dfs[symbol].index,inplace=True) #清除当天的行情数据
|
||||
else:
|
||||
param.clearing_executed = False
|
||||
pass
|
||||
return param.clearing_executed
|
||||
|
||||
def OnRtnTrade(self, pTrade):
|
||||
print("||成交回报||", pTrade)
|
||||
|
||||
def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast):
|
||||
print("||OnRspOrderInsert||", pInputOrder, pRspInfo, nRequestID, bIsLast)
|
||||
|
||||
# 订单状态通知
|
||||
def OnRtnOrder(self, pOrder):
|
||||
print("||订单回报||", pOrder)
|
||||
|
||||
def cal_sig(self, symbol_queue):
|
||||
while True:
|
||||
try:
|
||||
data = symbol_queue.get(block=True, timeout=5) # 如果5秒没收到新的tick行情,则抛出异常
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
size = symbol_queue.qsize()
|
||||
if size > 1:
|
||||
print(f'当前{instrument_id}共享队列长度为{size}, 有点阻塞!!!!!')
|
||||
self.read_to_csv(instrument_id)
|
||||
self.day_data_reset(instrument_id)
|
||||
param = self.param_dict[instrument_id]
|
||||
self.品种=instrument_id
|
||||
self.tickcome(data)
|
||||
trade_df = trade_dfs[instrument_id]
|
||||
#新K线开始,启动交易程序 and 保存行情数据
|
||||
self.read_to_csv(instrument_id)
|
||||
# size = symbol_queue.qsize()
|
||||
# if size > 2:
|
||||
# print(f'!!!!!当前{instrument_id}共享队列长度为:',size)
|
||||
if len(trade_df)>param.cont_df:
|
||||
# 检查文件是否存在
|
||||
csv_file_path = f"traderdata/{instrument_id}_ofdata.csv"
|
||||
if os.path.exists(csv_file_path):
|
||||
# 仅保存最后一行数据
|
||||
trade_df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
else:
|
||||
# 创建新文件并保存整个DataFrame
|
||||
trade_df.to_csv(csv_file_path, index=False)
|
||||
|
||||
# 更新跟踪止损价格
|
||||
if param.long_trailing_stop_price >0 and param.pos>0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧多头出线',param.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
param.long_trailing_stop_price = trade_df['low'].iloc[-1] if param.long_trailing_stop_price<trade_df['low'].iloc[-1] else param.long_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#print('datetime+sig: ',dt,'多头出线',param.long_trailing_stop_price)
|
||||
if param.short_trailing_stop_price >0 and param.pos<0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧空头出线',param.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
param.short_trailing_stop_price = trade_df['high'].iloc[-1] if trade_df['high'].iloc[-1] <param.short_trailing_stop_price else param.short_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#print('datetime+sig: ',dt,'空头出线',param.short_trailing_stop_price)
|
||||
|
||||
param.out_long=param.long_trailing_stop_price * (1 - param.trailing_stop_percent)
|
||||
param.out_short=param.short_trailing_stop_price*(1 + param.trailing_stop_percent)
|
||||
#print('datetime+sig: ',dt,'空头出线',param.out_short)
|
||||
#print('datetime+sig: ',dt,'多头出线',param.out_long)
|
||||
# 跟踪出场
|
||||
if param.out_long >0:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'预设——多头止盈——','TR',param.out_long,'low', trade_df['low'].iloc[-1])
|
||||
if trade_df['low'].iloc[-1] < param.out_long and param.pos>0 and param.sl_long_price>0 and trade_df['low'].iloc[-1]>param.sl_long_price:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'多头止盈','TR',param.out_long,'low', trade_df['low'].iloc[-1])
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.long_trailing_stop_price = 0
|
||||
param.out_long=0
|
||||
param.sl_long_price=0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
if param.out_short>0:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'预设——空头止盈——: ','TR',param.out_short,'high', trade_df['high'].iloc[-1])
|
||||
if trade_df['high'].iloc[-1] > param.out_short and param.pos<0 and param.sl_shor_price>0 and trade_df['high'].iloc[-1]<param.sl_shor_price:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'空头止盈: ','TR',param.out_short,'high', trade_df['high'].iloc[-1])
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.short_trailing_stop_price = 0
|
||||
param.sl_shor_price=0
|
||||
self.out_shor=0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 固定止损
|
||||
fixed_stop_loss_L = param.sl_long_price * (1 - param.fixed_stop_loss_percent)
|
||||
if param.pos>0:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '预设——多头止损', 'SL', fixed_stop_loss_L, 'close', trade_df['close'].iloc[-1])
|
||||
if param.sl_long_price>0 and fixed_stop_loss_L>0 and param.pos > 0 and trade_df['close'].iloc[-1] < fixed_stop_loss_L:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '多头止损', 'SL', fixed_stop_loss_L, 'close', trade_df['close'].iloc[-1])
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.long_trailing_stop_price = 0
|
||||
param.sl_long_price=0
|
||||
param.out_long = 0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
fixed_stop_loss_S = param.sl_shor_price * (1 + param.fixed_stop_loss_percent)
|
||||
if param.pos<0:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '预设——空头止损', 'SL', fixed_stop_loss_S, 'close', trade_df['close'].iloc[-1])
|
||||
if param.sl_shor_price>0 and fixed_stop_loss_S>0 and param.pos < 0 and trade_df['close'].iloc[-1] > fixed_stop_loss_S:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '空头止损', 'SL', fixed_stop_loss_S, 'close', trade_df['close'].iloc[-1])
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.short_trailing_stop_price = 0
|
||||
param.sl_shor_price=0
|
||||
param.out_short = 0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#日均线
|
||||
trade_df['dayma']=trade_df['close'].mean()
|
||||
|
||||
# 计算累积的delta值
|
||||
trade_df['delta'] = trade_df['delta'].astype(float)
|
||||
trade_df['delta累计'] = trade_df['delta'].cumsum()
|
||||
|
||||
#大于日均线
|
||||
开多1=trade_df['dayma'].iloc[-1] > 0 and trade_df['close'].iloc[-1] > trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量大于X
|
||||
开多4=trade_df['delta累计'].iloc[-1] > param.sum_delta and trade_df['delta'].iloc[-1] > param.delta
|
||||
|
||||
#小于日均线
|
||||
开空1=trade_df['dayma'].iloc[-1]>0 and trade_df['close'].iloc[-1] < trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量小于X
|
||||
开空4=trade_df['delta累计'].iloc[-1] < -param.sum_delta and trade_df['delta'].iloc[-1] < -param.delta
|
||||
开多组合= 开多1 and 开多4 and trade_df['dj'].iloc[-1]>param.dj_X
|
||||
开空条件= 开空1 and 开空4 and trade_df['dj'].iloc[-1]<-param.dj_X
|
||||
|
||||
平多条件=trade_df['dj'].iloc[-1]<-param.dj_X
|
||||
平空条件=trade_df['dj'].iloc[-1]>param.dj_X
|
||||
#开仓
|
||||
#多头开仓条件
|
||||
if param.pos<0 and 平空条件 :
|
||||
print('平空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+param.py)
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
param.sl_shor_price=0
|
||||
param.short_trailing_stop_price=0
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '反手平空:', '平仓价格:', data['AskPrice1']+param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 发送邮件
|
||||
text = f"平空交易: 交易品种为{data['InstrumentID']}, 交易时间为{trade_df['datetime'].iloc[-1]}, 反手平空的平仓价格为{data['AskPrice1']+param.py}, 交易手数位{param.Lots}"
|
||||
send_mail(text)
|
||||
|
||||
if param.pos==0 and 开多组合:
|
||||
print('开多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+param.py)
|
||||
#开多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'0')
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '多头开仓', '开仓价格:', data['AskPrice1']+param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
param.pos=1
|
||||
param.long_trailing_stop_price=data['AskPrice1']
|
||||
param.sl_long_price=data['AskPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 发送邮件
|
||||
text = f"开多交易: 交易品种为{data['InstrumentID']}, 交易时间为{trade_df['datetime'].iloc[-1]}, 多头开仓的开仓价格{data['AskPrice1']+param.py}, 交易手数位{param.Lots}"
|
||||
send_mail(text)
|
||||
|
||||
if param.pos>0 and 平多条件 :
|
||||
print('平多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1']-param.py)
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
param.long_trailing_stop_price=0
|
||||
param.sl_long_price=0
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '反手平多', '平仓价格:', data['BidPrice1']-param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#发送邮件
|
||||
text = f"平多交易: 交易品种为{data['InstrumentID']}, 交易时间为{trade_df['datetime'].iloc[-1]}, 反手平多的平仓价格{data['BidPrice1']-param.py}, 交易手数位{param.Lots}"
|
||||
send_mail(text)
|
||||
|
||||
if param.pos==0 and 开空条件 :
|
||||
print('开空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1'])
|
||||
#开空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'0')
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '空头开仓', '开仓价格:', data['BidPrice1']-param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
param.pos=-1
|
||||
param.short_trailing_stop_price=data['BidPrice1']
|
||||
param.sl_shor_price=data['BidPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 发送邮件
|
||||
text = f"开空交易: 交易品种为{data['InstrumentID']}, 交易时间为{trade_df['datetime'].iloc[-1]}, 空头开仓的开仓价格{data['BidPrice1']-param.py}, 交易手数位{param.Lots}"
|
||||
send_mail(text)
|
||||
|
||||
print(trade_df)
|
||||
param.cont_df=len(trade_df)
|
||||
except queue.Empty:
|
||||
# print(f"当前合约队列为空,等待新数据插入。")
|
||||
pass
|
||||
|
||||
# 将CTP推送的行情数据分发给对应线程队列去执行
|
||||
def distribute_tick(self):
|
||||
while True:
|
||||
if self.status == 0:
|
||||
data = None
|
||||
while not self.md_queue.empty():
|
||||
data = self.md_queue.get(block=False)
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
try:
|
||||
self.queue_dict[instrument_id].put(data, block=False) # 往对应合约队列中插入行情
|
||||
# print(f"{instrument_id}合约数据插入。")
|
||||
except queue.Full:
|
||||
# 当某个线程阻塞导致对应队列容量超限时抛出异常,不会影响其他合约的信号计算
|
||||
print(f"{instrument_id}合约信号计算阻塞导致对应队列已满,请检查对应代码逻辑后重启。")
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
def start(self, param_dict):
|
||||
threads = []
|
||||
self.param_dict = param_dict
|
||||
for symbol in param_dict.keys():
|
||||
trade_dfs[symbol] = pd.DataFrame({})
|
||||
self.queue_dict[symbol] = queue.Queue(20) #为每个合约创建一个限制数为10的队列,当计算发生阻塞导致队列达到限制数时会抛出异常
|
||||
t = threading.Thread(target=self.cal_sig, args=(self.queue_dict[symbol],)) # 为每个合约单独创建一个线程计算开仓逻辑
|
||||
threads.append(t)
|
||||
t.start()
|
||||
self.distribute_tick()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
# 发送邮件
|
||||
def send_mail(text):
|
||||
msg = MIMEMultipart()
|
||||
msg["From"] = sender
|
||||
msg["To"] = ";".join(receivers)
|
||||
msg["Subject"] = subject
|
||||
msg.attach(MIMEText(text, "plain", "utf-8"))
|
||||
smtp = smtplib.SMTP_SSL(smtp_server, smtp_port)
|
||||
smtp.login(username, password)
|
||||
smtp.sendmail(sender, receivers, msg.as_string())
|
||||
smtp.quit()
|
||||
|
||||
# 获取主力连续代码
|
||||
def get_main_contact_on_time(main_symbol_code,contacts_df):
|
||||
main_symbol = contacts_df[contacts_df['品种代码'] == main_symbol_code]['主连代码'].iloc[0]
|
||||
print("最终使用的主连代码:",main_symbol)
|
||||
return main_symbol
|
||||
|
||||
def run_trader(param_dict, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
my_trader = MyTrader(broker_id, td_server, investor_id, password, app_id, auth_code, md_queue, page_dir, private_resume_type, public_resume_type)
|
||||
my_trader.start(param_dict)
|
||||
|
||||
if __name__ == '__main__':
|
||||
#global symbol
|
||||
|
||||
#注意:运行前请先安装好algoplus,
|
||||
# pip install AlgoPlus
|
||||
#http://www.algo.plus/ctp/python/0103001.html
|
||||
|
||||
sb_1 = get_main_contact_on_time('IH', contacts_df)
|
||||
sb_2 = get_main_contact_on_time('ag', contacts_df)
|
||||
sb_3 = get_main_contact_on_time('eb', contacts_df)
|
||||
sb_4 = get_main_contact_on_time('si', contacts_df)
|
||||
sb_5 = get_main_contact_on_time('sc', contacts_df)
|
||||
sb_6 = get_main_contact_on_time('SA', contacts_df)
|
||||
sb_7 = get_main_contact_on_time('rb', contacts_df)
|
||||
sb_8 = get_main_contact_on_time('ru', contacts_df)
|
||||
sb_9 = get_main_contact_on_time('ni', contacts_df)
|
||||
sb_10 = get_main_contact_on_time('m', contacts_df)
|
||||
|
||||
# 实盘参数字典,需要实盘交易的合约,新建对应的参数对象即可,以下参数仅供测试使用,不作为实盘参考!!!!
|
||||
param_dict = {}
|
||||
param_dict[sb_1] = ParamObj(symbol=sb_1, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict[sb_2] = ParamObj(symbol=sb_2, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict[sb_3] = ParamObj(symbol=sb_4, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict[sb_4] = ParamObj(symbol=sb_4, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict[sb_5] = ParamObj(symbol=sb_5, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict[sb_6] = ParamObj(symbol=sb_6, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict[sb_7] = ParamObj(symbol=sb_7, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict[sb_8] = ParamObj(symbol=sb_8, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict[sb_9] = ParamObj(symbol=sb_9, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict[sb_10] = ParamObj(symbol=sb_10, Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
|
||||
# param_dict['ag2408'] = ParamObj(symbol='ag2408', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=500,sum_delta=1000,失衡=3,堆积=3,周期='5T')
|
||||
# param_dict['j2405'] = ParamObj(symbol='j2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['TA405'] = ParamObj(symbol='TA405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['au2406'] = ParamObj(symbol='au2406', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['sc2405'] = ParamObj(symbol='sc2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['bc2406'] = ParamObj(symbol='bc2406', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['lu2406'] = ParamObj(symbol='lu2406', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
|
||||
#用simnow模拟,不要忘记屏蔽下方实盘的future_account字典
|
||||
# future_account = get_simulate_account(
|
||||
# investor_id='135858', # simnow账户,注意是登录账户的ID,SIMNOW个人首页查看
|
||||
# password='Zj82334475', # simnow密码
|
||||
# server_name='电信1', # 电信1、电信2、移动、TEST、N视界
|
||||
# subscribe_list=list(param_dict.keys()), # 合约列表
|
||||
# )
|
||||
|
||||
#实盘用这个,不要忘记屏蔽上方simnow的future_account字典
|
||||
future_account = FutureAccount(
|
||||
broker_id='8888', # 期货公司BrokerID
|
||||
server_dict={'TDServer': "103.140.14.210:43205", 'MDServer': '103.140.14.210:43173'}, # TDServer为交易服务器,MDServer为行情服务器。服务器地址格式为"ip:port。"
|
||||
reserve_server_dict={}, # 备用服务器地址
|
||||
investor_id='******', # 账户
|
||||
password='******', # 密码
|
||||
app_id='vntech_vnpy_2.0', # 认证使用AppID
|
||||
auth_code='N46EKN6TJ9U7V06V', # 认证使用授权码
|
||||
subscribe_list=list(param_dict.keys()), # 订阅合约列表
|
||||
md_flow_path='./log', # MdApi流文件存储地址,默认MD_LOCATION
|
||||
td_flow_path='./log', # TraderApi流文件存储地址,默认TD_LOCATION
|
||||
)
|
||||
|
||||
if datetime.time == time(15, 5):
|
||||
df =
|
||||
|
||||
|
||||
print('开始',len(future_account.subscribe_list))
|
||||
# 共享队列
|
||||
share_queue = Queue(maxsize=200)
|
||||
|
||||
# 行情进程
|
||||
md_process = Process(target=run_tick_engine, args=(future_account, [share_queue]))
|
||||
|
||||
|
||||
# 交易进程
|
||||
trader_process = Process(target=run_trader, args=(
|
||||
param_dict,
|
||||
future_account.broker_id,
|
||||
future_account.server_dict['TDServer'],
|
||||
future_account.investor_id,
|
||||
future_account.password,
|
||||
future_account.app_id,
|
||||
future_account.auth_code,
|
||||
share_queue, # 队列
|
||||
future_account.td_flow_path
|
||||
))
|
||||
|
||||
md_process.start()
|
||||
trader_process.start()
|
||||
|
||||
md_process.join()
|
||||
trader_process.join()
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
taskkill /im python.exe /f
|
||||
taskkill /im cmd.exe /f
|
||||
exit
|
||||
@@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
set python_path=C:\veighna_studio\python.exe
|
||||
start python D:\real_test\on_time.py
|
||||
exit
|
||||
@@ -0,0 +1,8 @@
|
||||
echo oft
|
||||
w32tm /config /manualpeerlist:"time.nist.gov"/syncfromflags:manual /reliable:yes /update
|
||||
w32tm /resync
|
||||
w32tm /resync
|
||||
w32tm /config /manualpeerlist:"time.windows.com"/syncfromflags:manual /reliable:yes /update
|
||||
w32tm /resync
|
||||
w32tm /resync
|
||||
echo同步结束!
|
||||
@@ -0,0 +1,5 @@
|
||||
[tool.ruff]
|
||||
line-length = 120 # 设置行长度为120
|
||||
|
||||
[tool.ruff.select]
|
||||
E501 = "ignore" # 忽略行长度限制错误
|
||||
@@ -0,0 +1,588 @@
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from multiprocessing import Process, Queue
|
||||
import queue
|
||||
import threading
|
||||
from AlgoPlus.CTP.MdApi import run_tick_engine
|
||||
from AlgoPlus.CTP.FutureAccount import get_simulate_account
|
||||
from AlgoPlus.CTP.FutureAccount import FutureAccount
|
||||
from AlgoPlus.CTP.TraderApiBase import TraderApiBase
|
||||
from AlgoPlus.ta.time_bar import tick_to_bar
|
||||
import pandas as pd
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import time as s_time
|
||||
import operator
|
||||
import time
|
||||
import numpy as np
|
||||
import os
|
||||
import re
|
||||
tickdatadict = {}
|
||||
quotedict = {}
|
||||
ofdatadict = {}
|
||||
trade_dfs = {}
|
||||
previous_volume = {}
|
||||
tsymbollist={}
|
||||
clearing_time_dict = {'sc': s_time(2,30), 'bc': s_time(1,0)}
|
||||
|
||||
class ParamObj:
|
||||
symbol = None
|
||||
Lots = None
|
||||
py = None
|
||||
trailing_stop_percent = None
|
||||
fixed_stop_loss_percent = None
|
||||
dj_X = None
|
||||
delta = None
|
||||
sum_delta = None
|
||||
失衡=None
|
||||
堆积=None
|
||||
周期=None
|
||||
cont_df = 0
|
||||
pos = 0
|
||||
short_trailing_stop_price = 0
|
||||
long_trailing_stop_price = 0
|
||||
sl_long_price = 0
|
||||
sl_shor_price = 0
|
||||
out_long = 0
|
||||
out_short = 0
|
||||
clearing_executed = False
|
||||
kgdata = True
|
||||
|
||||
def __init__(self, symbol, Lots, py, trailing_stop_percent, fixed_stop_loss_percent, dj_X, delta, sum_delta,失衡,堆积,周期):
|
||||
self.symbol = symbol
|
||||
self.Lots = Lots
|
||||
self.py = py
|
||||
self.trailing_stop_percent = trailing_stop_percent
|
||||
self.fixed_stop_loss_percent = fixed_stop_loss_percent
|
||||
self.dj_X = dj_X
|
||||
self.delta = delta
|
||||
self.sum_delta = sum_delta
|
||||
self.失衡=失衡
|
||||
self.堆积=堆积
|
||||
self.周期=周期
|
||||
|
||||
class MyTrader(TraderApiBase):
|
||||
def __init__(self, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
self.param_dict = {}
|
||||
self.queue_dict = {}
|
||||
self.品种=' '
|
||||
|
||||
def tickcome(self,md_queue):
|
||||
global previous_volume
|
||||
data=md_queue
|
||||
instrument_id = data['InstrumentID'].decode()
|
||||
ActionDay = data['ActionDay'].decode()
|
||||
update_time = data['UpdateTime'].decode()
|
||||
update_millisec = str(data['UpdateMillisec'])
|
||||
created_at = ActionDay[:4] + '-' + ActionDay[4:6] + '-' + ActionDay[6:] + ' ' + update_time + '.' + update_millisec
|
||||
tick = {
|
||||
'symbol': instrument_id,
|
||||
'created_at':datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S.%f"),
|
||||
'price': float(data['LastPrice']),
|
||||
'last_volume': int(data['Volume']) - previous_volume.get(instrument_id, 0) if previous_volume.get(instrument_id, 0) != 0 else 0,
|
||||
'bid_p': float(data['BidPrice1']),
|
||||
'bid_v': int(data['BidVolume1']),
|
||||
'ask_p': float(data['AskPrice1']),
|
||||
'ask_v': int(data['AskVolume1']),
|
||||
'UpperLimitPrice': float(data['UpperLimitPrice']),
|
||||
'LowerLimitPrice': float(data['LowerLimitPrice']),
|
||||
'TradingDay': data['TradingDay'].decode(),
|
||||
'cum_volume': int(data['Volume']),
|
||||
'cum_amount': float(data['Turnover']),
|
||||
'cum_position': int(data['OpenInterest']),
|
||||
}
|
||||
previous_volume[instrument_id] = int(data['Volume'])
|
||||
if tick['last_volume']>0:
|
||||
self.on_tick(tick)
|
||||
|
||||
def can_time(self,hour, minute):
|
||||
hour = str(hour)
|
||||
minute = str(minute)
|
||||
if len(minute) == 1:
|
||||
minute = "0" + minute
|
||||
return int(hour + minute)
|
||||
|
||||
def on_tick(self,tick):
|
||||
tm=self.can_time(tick['created_at'].hour,tick['created_at'].minute)
|
||||
if tick['last_volume']==0:
|
||||
return
|
||||
quotes = tick
|
||||
timetick=str(tick['created_at']).replace('+08:00', '')
|
||||
tsymbol=tick['symbol']
|
||||
if tsymbol not in tsymbollist.keys():
|
||||
tsymbollist[tsymbol]=tick
|
||||
bid_p=quotes['bid_p']
|
||||
ask_p=quotes['ask_p']
|
||||
bid_v=quotes['bid_v']
|
||||
ask_v=quotes['ask_v']
|
||||
else:
|
||||
rquotes =tsymbollist[tsymbol]
|
||||
bid_p=rquotes['bid_p']
|
||||
ask_p=rquotes['ask_p']
|
||||
bid_v=rquotes['bid_v']
|
||||
ask_v=rquotes['ask_v']
|
||||
tsymbollist[tsymbol]=tick
|
||||
tick_dt=pd.DataFrame({'datetime':timetick,'symbol':tick['symbol'],'mainsym':tick['symbol'].rstrip('0123456789').upper(),'lastprice':tick['price'],
|
||||
'vol':tick['last_volume'],
|
||||
'bid_p':bid_p,'ask_p':ask_p,'bid_v':bid_v,'ask_v':ask_v},index=[0])
|
||||
sym = tick_dt['symbol'][0]
|
||||
self.tickdata(tick_dt,sym)
|
||||
|
||||
def data_of(self,symbol, df):
|
||||
global trade_dfs
|
||||
trade_dfs[symbol] = pd.concat([trade_dfs[symbol], df], ignore_index=True)
|
||||
|
||||
def process(self,bidDict, askDict, symbol):
|
||||
try:
|
||||
dic = quotedict[symbol]
|
||||
bidDictResult = dic['bidDictResult']
|
||||
askDictResult = dic['askDictResult']
|
||||
except:
|
||||
bidDictResult, askDictResult = {}, {}
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
if s in bidDictResult:
|
||||
bidDictResult[s] = int(bidDict[s]) + bidDictResult[s]
|
||||
else:
|
||||
bidDictResult[s] = int(bidDict[s])
|
||||
if s not in askDictResult:
|
||||
askDictResult[s] = 0
|
||||
else:
|
||||
if s in askDictResult:
|
||||
askDictResult[s] = int(askDict[s]) + askDictResult[s]
|
||||
else:
|
||||
askDictResult[s] = int(askDict[s])
|
||||
if s not in bidDictResult:
|
||||
bidDictResult[s] = 0
|
||||
df = {'bidDictResult': bidDictResult, 'askDictResult': askDictResult}
|
||||
quotedict[symbol] = df
|
||||
return bidDictResult, askDictResult
|
||||
|
||||
def tickdata(self,df,symbol):
|
||||
tickdata =pd.DataFrame({'datetime':df['datetime'],'symbol':df['symbol'],'lastprice':df['lastprice'],
|
||||
'volume':df['vol'],'bid_p':df['bid_p'],'bid_v':df['bid_v'],'ask_p':df['ask_p'],'ask_v':df['ask_v']})
|
||||
try:
|
||||
if symbol in tickdatadict.keys():
|
||||
rdf=tickdatadict[symbol]
|
||||
rdftm=pd.to_datetime(rdf['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
now=str(tickdata['datetime'][0])
|
||||
if now>rdftm:
|
||||
try:
|
||||
oo=ofdatadict[symbol]
|
||||
self.data_of(symbol, oo)
|
||||
if symbol in quotedict.keys():
|
||||
quotedict.pop(symbol)
|
||||
if symbol in tickdatadict.keys():
|
||||
tickdatadict.pop(symbol)
|
||||
if symbol in ofdatadict.keys():
|
||||
ofdatadict.pop(symbol)
|
||||
except IOError as e:
|
||||
print('rdftm捕获到异常',e)
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
else:
|
||||
tickdata['bartime'] = rdf['bartime']
|
||||
tickdata['open'] = rdf['open']
|
||||
tickdata['high'] = max(tickdata['lastprice'].values,rdf['high'].values)
|
||||
tickdata['low'] = min(tickdata['lastprice'].values,rdf['low'].values)
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['volume']=df['vol']+rdf['volume'].values
|
||||
tickdata['starttime'] = rdf['starttime']
|
||||
else :
|
||||
print('新bar的第一个tick进入')
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
except IOError as e:
|
||||
print('捕获到异常',e)
|
||||
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['bartime'])
|
||||
param = self.param_dict[self.品种]
|
||||
bardata = tickdata.resample(on = 'bartime',rule = param.周期,label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
bardata['bartime'] = pd.to_datetime(bardata['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
tickdatadict[symbol]=bardata
|
||||
tickdata['volume']=df['vol'].values
|
||||
self.orderflow_df_new(tickdata,bardata,symbol)
|
||||
|
||||
def orderflow_df_new(self,df_tick,df_min,symbol):
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
endArray = df_min['bartime'].values
|
||||
deltaArray = np.zeros((len(endArray),))
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
dt=endArray[index]
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
Bp = round(bp1TickArray[0],4)
|
||||
Ap = round(ap1TickArray[0],4)
|
||||
LastPrice = round(lastTickArray[0],4)
|
||||
Volume = volumeTickArray[0]
|
||||
if LastPrice >= Ap:
|
||||
if str(LastPrice) in askDict.keys():
|
||||
askDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
askDict[str(LastPrice)] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if str(LastPrice) in bidDict.keys():
|
||||
bidDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
bidDict[str(LastPrice)] = Volume
|
||||
bidDictResult,askDictResult = self.process(bidDict,askDict,symbol)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
df['dj'] = self.GetOrderFlow_dj(df)
|
||||
ofdatadict[symbol]=df
|
||||
|
||||
def GetOrderFlow_dj(self,kData):
|
||||
param = self.param_dict[self.品种]
|
||||
Config = {
|
||||
'Value1': param.失衡,
|
||||
'Value2': param.堆积,
|
||||
'Value4': True,
|
||||
}
|
||||
aryData = kData
|
||||
djcout = 0
|
||||
for index, row in aryData.iterrows():
|
||||
kItem = aryData.iloc[index]
|
||||
high = kItem['high']
|
||||
low = kItem['low']
|
||||
close = kItem['close']
|
||||
open = kItem['open']
|
||||
dtime = kItem['datetime']
|
||||
price_s = kItem['price']
|
||||
Ask_s = kItem['Ask']
|
||||
Bid_s = kItem['Bid']
|
||||
delta = kItem['delta']
|
||||
price_s = price_s
|
||||
Ask_s = Ask_s
|
||||
Bid_s = Bid_s
|
||||
gj = 0
|
||||
xq = 0
|
||||
gxx = 0
|
||||
xxx = 0
|
||||
for i in np.arange(0, len(price_s), 1):
|
||||
duiji = {
|
||||
'price': 0,
|
||||
'time': 0,
|
||||
'longshort': 0,
|
||||
}
|
||||
if i == 0:
|
||||
delta = delta
|
||||
order= {
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
if i >= 0 and i < len(price_s) - 1:
|
||||
if (order["Bid"]["Value"] > Ask_s[i + 1] * int(Config['Value1'])):
|
||||
gxx += 1
|
||||
gj += 1
|
||||
if gj >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = -1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += -1
|
||||
else:
|
||||
gj = 0
|
||||
if i >= 1 and i < len(price_s) - 1:
|
||||
if (order["Ask"]["Value"] > Bid_s[i - 1] * int(Config['Value1'])):
|
||||
xq += 1
|
||||
xxx += 1
|
||||
if xq >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = 1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += 1
|
||||
else:
|
||||
xq = 0
|
||||
return djcout
|
||||
|
||||
def read_to_csv(self,symbol):
|
||||
param = self.param_dict[symbol]
|
||||
folder_path = "traderdata"
|
||||
file_path = os.path.join(folder_path, f"{str(symbol)}_traderdata.csv")
|
||||
if not os.path.exists(folder_path):
|
||||
os.makedirs(folder_path)
|
||||
if os.path.exists(file_path):
|
||||
df = pd.read_csv(file_path)
|
||||
if not df.empty and param.kgdata==True:
|
||||
row = df.iloc[-1]
|
||||
param.pos = int(row['pos'])
|
||||
param.short_trailing_stop_price = float(row['short_trailing_stop_price'])
|
||||
param.long_trailing_stop_price = float(row['long_trailing_stop_price'])
|
||||
param.sl_long_price = float(row['sl_long_price'])
|
||||
param.sl_shor_price = float(row['sl_shor_price'])
|
||||
print("找到历史交易数据文件,已经更新持仓,止损止盈数据", df.iloc[-1])
|
||||
param.kgdata=False
|
||||
else:
|
||||
pass
|
||||
pass
|
||||
|
||||
def save_to_csv(self,symbol):
|
||||
param = self.param_dict[symbol]
|
||||
data = {
|
||||
'datetime': [trade_dfs[symbol]['datetime'].iloc[-1]],
|
||||
'pos': [param.pos],
|
||||
'short_trailing_stop_price': [param.short_trailing_stop_price],
|
||||
'long_trailing_stop_price': [param.long_trailing_stop_price],
|
||||
'sl_long_price': [param.sl_long_price],
|
||||
'sl_shor_price': [param.sl_shor_price],
|
||||
}
|
||||
df = pd.DataFrame(data)
|
||||
df.to_csv(f"traderdata/{str(symbol)}_traderdata.csv", index=False)
|
||||
|
||||
def day_data_reset(self, symbol):
|
||||
param = self.param_dict[symbol]
|
||||
sec = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
current_time = datetime.now().time()
|
||||
clearing_time1_start = s_time(15,00)
|
||||
clearing_time1_end = s_time(15,15)
|
||||
param.clearing_executed = False
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not param.clearing_executed :
|
||||
param.clearing_executed = True
|
||||
trade_dfs[symbol].drop(trade_dfs[symbol].index,inplace=True)
|
||||
elif sec in clearing_time_dict.keys():
|
||||
clearing_time2_start = clearing_time_dict[sec]
|
||||
clearing_time2_end = s_time(clearing_time2_start.hour, clearing_time2_start.minute+15)
|
||||
if clearing_time2_start <= current_time <= clearing_time2_end and not param.clearing_executed :
|
||||
param.clearing_executed = True
|
||||
trade_dfs[symbol].drop(trade_dfs[symbol].index,inplace=True)
|
||||
else:
|
||||
param.clearing_executed = False
|
||||
pass
|
||||
return param.clearing_executed
|
||||
|
||||
def OnRtnTrade(self, pTrade):
|
||||
print("||成交回报||", pTrade)
|
||||
|
||||
def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast):
|
||||
print("||OnRspOrderInsert||", pInputOrder, pRspInfo, nRequestID, bIsLast)
|
||||
|
||||
def OnRtnOrder(self, pOrder):
|
||||
print("||订单回报||", pOrder)
|
||||
|
||||
def cal_sig(self, symbol_queue):
|
||||
while True:
|
||||
try:
|
||||
data = symbol_queue.get(block=True, timeout=5)
|
||||
instrument_id = data['InstrumentID'].decode()
|
||||
size = symbol_queue.qsize()
|
||||
if size > 1:
|
||||
print(f'当前{instrument_id}共享队列长度为{size}, 有点阻塞!!!!!')
|
||||
self.read_to_csv(instrument_id)
|
||||
self.day_data_reset(instrument_id)
|
||||
param = self.param_dict[instrument_id]
|
||||
self.品种=instrument_id
|
||||
self.tickcome(data)
|
||||
trade_df = trade_dfs[instrument_id]
|
||||
self.read_to_csv(instrument_id)
|
||||
if len(trade_df)>param.cont_df:
|
||||
csv_file_path = f"traderdata/{instrument_id}_ofdata.csv"
|
||||
if os.path.exists(csv_file_path):
|
||||
trade_df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
else:
|
||||
trade_df.to_csv(csv_file_path, index=False)
|
||||
if param.long_trailing_stop_price >0 and param.pos>0:
|
||||
param.long_trailing_stop_price = trade_df['low'].iloc[-1] if param.long_trailing_stop_price<trade_df['low'].iloc[-1] else param.long_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
if param.short_trailing_stop_price >0 and param.pos<0:
|
||||
param.short_trailing_stop_price = trade_df['high'].iloc[-1] if trade_df['high'].iloc[-1] <param.short_trailing_stop_price else param.short_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
param.out_long=param.long_trailing_stop_price * (1 - param.trailing_stop_percent)
|
||||
param.out_short=param.short_trailing_stop_price*(1 + param.trailing_stop_percent)
|
||||
if param.out_long >0:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'预设——多头止盈——','TR',param.out_long,'low', trade_df['low'].iloc[-1])
|
||||
if trade_df['low'].iloc[-1] < param.out_long and param.pos>0 and param.sl_long_price>0 and trade_df['low'].iloc[-1]>param.sl_long_price:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'多头止盈','TR',param.out_long,'low', trade_df['low'].iloc[-1])
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.long_trailing_stop_price = 0
|
||||
param.out_long=0
|
||||
param.sl_long_price=0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
if param.out_short>0:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'预设——空头止盈——: ','TR',param.out_short,'high', trade_df['high'].iloc[-1])
|
||||
if trade_df['high'].iloc[-1] > param.out_short and param.pos<0 and param.sl_shor_price>0 and trade_df['high'].iloc[-1]<param.sl_shor_price:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'空头止盈: ','TR',param.out_short,'high', trade_df['high'].iloc[-1])
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.short_trailing_stop_price = 0
|
||||
param.sl_shor_price=0
|
||||
self.out_shor=0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
fixed_stop_loss_L = param.sl_long_price * (1 - param.fixed_stop_loss_percent)
|
||||
if param.pos>0:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '预设——多头止损', 'SL', fixed_stop_loss_L, 'close', trade_df['close'].iloc[-1])
|
||||
if param.sl_long_price>0 and fixed_stop_loss_L>0 and param.pos > 0 and trade_df['close'].iloc[-1] < fixed_stop_loss_L:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '多头止损', 'SL', fixed_stop_loss_L, 'close', trade_df['close'].iloc[-1])
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.long_trailing_stop_price = 0
|
||||
param.sl_long_price=0
|
||||
param.out_long = 0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
fixed_stop_loss_S = param.sl_shor_price * (1 + param.fixed_stop_loss_percent)
|
||||
if param.pos<0:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '预设——空头止损', 'SL', fixed_stop_loss_S, 'close', trade_df['close'].iloc[-1])
|
||||
if param.sl_shor_price>0 and fixed_stop_loss_S>0 and param.pos < 0 and trade_df['close'].iloc[-1] > fixed_stop_loss_S:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '空头止损', 'SL', fixed_stop_loss_S, 'close', trade_df['close'].iloc[-1])
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.short_trailing_stop_price = 0
|
||||
param.sl_shor_price=0
|
||||
param.out_short = 0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
trade_df['dayma']=trade_df['close'].mean()
|
||||
trade_df['delta'] = trade_df['delta'].astype(float)
|
||||
trade_df['delta累计'] = trade_df['delta'].cumsum()
|
||||
开多1=trade_df['dayma'].iloc[-1] > 0 and trade_df['close'].iloc[-1] > trade_df['dayma'].iloc[-1]
|
||||
开多4=trade_df['delta累计'].iloc[-1] > param.sum_delta and trade_df['delta'].iloc[-1] > param.delta
|
||||
开空1=trade_df['dayma'].iloc[-1]>0 and trade_df['close'].iloc[-1] < trade_df['dayma'].iloc[-1]
|
||||
开空4=trade_df['delta累计'].iloc[-1] < -param.sum_delta and trade_df['delta'].iloc[-1] < -param.delta
|
||||
开多组合= 开多1 and 开多4 and trade_df['dj'].iloc[-1]>param.dj_X
|
||||
开空条件= 开空1 and 开空4 and trade_df['dj'].iloc[-1]<-param.dj_X
|
||||
平多条件=trade_df['dj'].iloc[-1]<-param.dj_X
|
||||
平空条件=trade_df['dj'].iloc[-1]>param.dj_X
|
||||
if param.pos<0 and 平空条件 :
|
||||
print('平空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+param.py)
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
param.sl_shor_price=0
|
||||
param.short_trailing_stop_price=0
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '反手平空:', '平仓价格:', data['AskPrice1']+param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
if param.pos==0 and 开多组合:
|
||||
print('开多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+param.py)
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'0')
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '多头开仓', '开仓价格:', data['AskPrice1']+param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
param.pos=1
|
||||
param.long_trailing_stop_price=data['AskPrice1']
|
||||
param.sl_long_price=data['AskPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
if param.pos>0 and 平多条件 :
|
||||
print('平多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1']-param.py)
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
param.long_trailing_stop_price=0
|
||||
param.sl_long_price=0
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '反手平多', '平仓价格:', data['BidPrice1']-param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
if param.pos==0 and 开空条件 :
|
||||
print('开空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1'])
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'0')
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '空头开仓', '开仓价格:', data['BidPrice1']-param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
param.pos=-1
|
||||
param.short_trailing_stop_price=data['BidPrice1']
|
||||
param.sl_shor_price=data['BidPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
print(trade_df)
|
||||
param.cont_df=len(trade_df)
|
||||
except queue.Empty:
|
||||
pass
|
||||
|
||||
def distribute_tick(self):
|
||||
while True:
|
||||
if self.status == 0:
|
||||
data = None
|
||||
while not self.md_queue.empty():
|
||||
data = self.md_queue.get(block=False)
|
||||
instrument_id = data['InstrumentID'].decode()
|
||||
try:
|
||||
self.queue_dict[instrument_id].put(data, block=False)
|
||||
except queue.Full:
|
||||
print(f"{instrument_id}合约信号计算阻塞导致对应队列已满,请检查对应代码逻辑后重启。")
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
def start(self, param_dict):
|
||||
threads = []
|
||||
self.param_dict = param_dict
|
||||
for symbol in param_dict.keys():
|
||||
trade_dfs[symbol] = pd.DataFrame({})
|
||||
self.queue_dict[symbol] = queue.Queue(20)
|
||||
t = threading.Thread(target=self.cal_sig, args=(self.queue_dict[symbol],))
|
||||
threads.append(t)
|
||||
t.start()
|
||||
self.distribute_tick()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
def run_trader(param_dict, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
my_trader = MyTrader(broker_id, td_server, investor_id, password, app_id, auth_code, md_queue, page_dir, private_resume_type, public_resume_type)
|
||||
my_trader.start(param_dict)
|
||||
|
||||
if __name__ == '__main__':
|
||||
param_dict = {}
|
||||
param_dict['rb2410'] = ParamObj(symbol='rb2410', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
future_account = get_simulate_account(
|
||||
investor_id='***',
|
||||
password='***',
|
||||
server_name='***',
|
||||
subscribe_list=list(param_dict.keys())
|
||||
)
|
||||
print('开始',len(future_account.subscribe_list))
|
||||
share_queue = Queue(maxsize=200)
|
||||
md_process = Process(target=run_tick_engine, args=(future_account, [share_queue]))
|
||||
trader_process = Process(target=run_trader, args=(
|
||||
param_dict,
|
||||
future_account.broker_id,
|
||||
future_account.server_dict['TDServer'],
|
||||
future_account.investor_id,
|
||||
future_account.password,
|
||||
future_account.app_id,
|
||||
future_account.auth_code,
|
||||
share_queue,
|
||||
future_account.td_flow_path
|
||||
))
|
||||
md_process.start()
|
||||
trader_process.start()
|
||||
md_process.join()
|
||||
trader_process.join()
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
||||
import subprocess
|
||||
import schedule
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
# 定义要启动的文件
|
||||
files_to_run = ['实盘运行版本.py']
|
||||
|
||||
|
||||
def run_scripts():
|
||||
print("启动程序...")
|
||||
for file in files_to_run:
|
||||
time.sleep(1)
|
||||
# 使用subprocess模块运行命令
|
||||
subprocess.Popen(['start', 'cmd', '/k', 'python', file], shell=True)
|
||||
print(file)
|
||||
print(datetime.now(),'程序重新启动完成,等待明天关闭重启')
|
||||
|
||||
|
||||
def close_scripts():
|
||||
print("关闭程序...")
|
||||
# 通过创建一个包含关闭指定窗口命令的批处理文件来关闭CMD窗口
|
||||
def close_specific_cmd_window(cmd_window_title):
|
||||
with open("close_cmd_window.bat", "w") as batch_file:
|
||||
batch_file.write(f'@echo off\nfor /f "tokens=2 delims=," %%a in (\'tasklist /v /fo csv ^| findstr /i "{cmd_window_title}"\') do taskkill /pid %%~a')
|
||||
|
||||
# 运行批处理文件
|
||||
subprocess.run("close_cmd_window.bat", shell=True)
|
||||
|
||||
|
||||
# 循环关闭所有脚本对应的CMD窗口
|
||||
for title in files_to_run:
|
||||
close_specific_cmd_window(title)
|
||||
print(datetime.now(),'已关闭程序,等待重新运行程序')
|
||||
|
||||
|
||||
|
||||
# 设置定时任务,关闭程序
|
||||
schedule.every().day.at("15:30").do(close_scripts)
|
||||
schedule.every().day.at("03:00").do(close_scripts)
|
||||
|
||||
# 设置定时任务,启动程序
|
||||
schedule.every().day.at("08:55").do(run_scripts)
|
||||
schedule.every().day.at("20:55").do(run_scripts)
|
||||
|
||||
|
||||
|
||||
# 保持脚本运行,等待定时任务触发
|
||||
#240884432
|
||||
while True:
|
||||
schedule.run_pending()
|
||||
time.sleep(1)
|
||||
#240884432
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,840 @@
|
||||
'''
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
该代码的主要目的是处理Tick数据并生成交易信号。代码中定义了一个tickcome函数,它接收到Tick数据后会进行一系列的处理,包括构建Tick字典、更新上一个Tick的成交量、保存Tick数据、生成K线数据等。其中涉及到的一些函数有:
|
||||
|
||||
on_tick(tick): 处理单个Tick数据,根据Tick数据生成K线数据。
|
||||
tickdata(df, symbol): 处理Tick数据,生成K线数据。
|
||||
orderflow_df_new(df_tick, df_min, symbol): 处理Tick和K线数据,生成订单流数据。
|
||||
GetOrderFlow_dj(kData): 计算订单流的信号指标。
|
||||
除此之外,代码中还定义了一个MyTrader类,继承自TraderApiBase,用于实现交易相关的功能。
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
'''
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from multiprocessing import Process, Queue
|
||||
import queue
|
||||
import threading
|
||||
from AlgoPlus.CTP.MdApi import run_tick_engine
|
||||
from AlgoPlus.CTP.FutureAccount import get_simulate_account
|
||||
from AlgoPlus.CTP.FutureAccount import FutureAccount
|
||||
from AlgoPlus.CTP.TraderApiBase import TraderApiBase
|
||||
from AlgoPlus.ta.time_bar import tick_to_bar
|
||||
import pandas as pd
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import time as s_time
|
||||
import operator
|
||||
import time
|
||||
import numpy as np
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
tickdatadict = {} # 存储Tick数据的字典
|
||||
quotedict = {} # 存储行情数据的字典
|
||||
ofdatadict = {} # 存储K线数据的字典
|
||||
trade_dfs = {} #pd.DataFrame({}) # 存储交易数据的DataFrame对象
|
||||
previous_volume = {} # 上一个Tick的成交量
|
||||
tsymbollist={}
|
||||
|
||||
clearing_time_dict = {'sc': s_time(2,30), 'bc': s_time(1,0), 'lu': s_time(23,0), 'nr': s_time(23,0),'au': s_time(2,30), 'ag': s_time(2,30),
|
||||
'ss': s_time(1,0), 'sn': s_time(1,0), 'ni': s_time(1,0), 'pb': s_time(1,0),'zn': s_time(1,0), 'al': s_time(1,0), 'cu': s_time(1,0),
|
||||
'ru': s_time(23,0), 'rb': s_time(23,0), 'hc': s_time(23,0), 'fu': s_time(23,0), 'bu': s_time(23,0), 'sp': s_time(23,0),
|
||||
'PF': s_time(23,0), 'SR': s_time(23,0), 'CF': s_time(23,0), 'CY': s_time(23,0), 'RM': s_time(23,0), 'MA': s_time(23,0),
|
||||
'TA': s_time(23,0), 'ZC': s_time(23,0), 'FG': s_time(23,0), 'OI': s_time(23,0), 'SA': s_time(23,0),
|
||||
'p': s_time(23,0), 'j': s_time(23,0), 'jm': s_time(23,0), 'i': s_time(23,0), 'l': s_time(23,0), 'v': s_time(23,0),
|
||||
'pp': s_time(23,0), 'eg': s_time(23,0), 'c': s_time(23,0), 'cs': s_time(23,0), 'y': s_time(23,0), 'm': s_time(23,0),
|
||||
'a': s_time(23,0), 'b': s_time(23,0), 'rr': s_time(23,0), 'eb': s_time(23,0), 'pg': s_time(23,0)}
|
||||
|
||||
|
||||
#交易程序---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
class ParamObj:
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
symbol = None #合约名称
|
||||
Lots = None #下单手数
|
||||
py = None #设置委托价格的偏移,更加容易促成成交
|
||||
trailing_stop_percent = None #跟踪出场参数
|
||||
fixed_stop_loss_percent = None #固定出场参数
|
||||
dj_X = None #开仓的堆积参数
|
||||
delta = None #开仓的delta参数
|
||||
sum_delta = None #开仓的delta累积参数
|
||||
失衡=None
|
||||
堆积=None
|
||||
周期=None
|
||||
|
||||
# 策略需要用到的变量
|
||||
cont_df = 0
|
||||
pos = 0
|
||||
short_trailing_stop_price = 0
|
||||
long_trailing_stop_price = 0
|
||||
sl_long_price = 0
|
||||
sl_shor_price = 0
|
||||
out_long = 0
|
||||
out_short = 0
|
||||
clearing_executed = False
|
||||
kgdata = True
|
||||
|
||||
def __init__(self, symbol, Lots, py, trailing_stop_percent, fixed_stop_loss_percent, dj_X, delta, sum_delta,失衡,堆积,周期):
|
||||
self.symbol = symbol
|
||||
self.Lots = Lots
|
||||
self.py = py
|
||||
self.trailing_stop_percent = trailing_stop_percent
|
||||
self.fixed_stop_loss_percent = fixed_stop_loss_percent
|
||||
self.dj_X = dj_X
|
||||
self.delta = delta
|
||||
self.sum_delta = sum_delta
|
||||
self.失衡=失衡
|
||||
self.堆积=堆积
|
||||
self.周期=周期
|
||||
|
||||
|
||||
class MyTrader(TraderApiBase):
|
||||
def __init__(self, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
self.param_dict = {}
|
||||
self.queue_dict = {}
|
||||
self.品种=' '
|
||||
|
||||
|
||||
def tickcome(self,md_queue):
|
||||
global previous_volume
|
||||
data=md_queue
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
ActionDay = data['ActionDay'].decode() # 交易日日期
|
||||
update_time = data['UpdateTime'].decode() # 更新时间
|
||||
|
||||
update_millisec = str(data['UpdateMillisec']) # 更新毫秒数
|
||||
created_at = ActionDay[:4] + '-' + ActionDay[4:6] + '-' + ActionDay[6:] + ' ' + update_time + '.' + update_millisec #创建时间
|
||||
# 构建tick字典
|
||||
tick = {
|
||||
'symbol': instrument_id, # 品种代码和交易所ID
|
||||
'created_at':datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S.%f"),
|
||||
#'created_at': created_at, # 创建时间
|
||||
'price': float(data['LastPrice']), # 最新价
|
||||
'last_volume': int(data['Volume']) - previous_volume.get(instrument_id, 0) if previous_volume.get(instrument_id, 0) != 0 else 0, # 瞬时成交量
|
||||
'bid_p': float(data['BidPrice1']), # 买价
|
||||
'bid_v': int(data['BidVolume1']), # 买量
|
||||
'ask_p': float(data['AskPrice1']), # 卖价
|
||||
'ask_v': int(data['AskVolume1']), # 卖量
|
||||
'UpperLimitPrice': float(data['UpperLimitPrice']), # 涨停价
|
||||
'LowerLimitPrice': float(data['LowerLimitPrice']), # 跌停价
|
||||
'TradingDay': data['TradingDay'].decode(), # 交易日日期
|
||||
'cum_volume': int(data['Volume']), # 最新总成交量
|
||||
'cum_amount': float(data['Turnover']), # 最新总成交额
|
||||
'cum_position': int(data['OpenInterest']), # 合约持仓量
|
||||
}
|
||||
# print('&&&&&&&&',instrument_id, tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 更新上一个Tick的成交量
|
||||
previous_volume[instrument_id] = int(data['Volume'])
|
||||
if tick['last_volume']>0:
|
||||
#print(tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 处理Tick数据
|
||||
self.on_tick(tick)
|
||||
|
||||
def can_time(self,hour, minute):
|
||||
hour = str(hour)
|
||||
minute = str(minute)
|
||||
if len(minute) == 1:
|
||||
minute = "0" + minute
|
||||
return int(hour + minute)
|
||||
|
||||
def on_tick(self,tick):
|
||||
|
||||
tm=self.can_time(tick['created_at'].hour,tick['created_at'].minute)
|
||||
#print(tick['symbol'])
|
||||
#print(1)
|
||||
#if tm>1500 and tm<2100 :
|
||||
# return
|
||||
if tick['last_volume']==0:
|
||||
return
|
||||
quotes = tick
|
||||
timetick=str(tick['created_at']).replace('+08:00', '')
|
||||
tsymbol=tick['symbol']
|
||||
if tsymbol not in tsymbollist.keys():
|
||||
# 获取tick的买卖价和买卖量
|
||||
|
||||
tsymbollist[tsymbol]=tick
|
||||
bid_p=quotes['bid_p']
|
||||
ask_p=quotes['ask_p']
|
||||
bid_v=quotes['bid_v']
|
||||
ask_v=quotes['ask_v']
|
||||
else:
|
||||
# 获取上一个tick的买卖价和买卖量
|
||||
rquotes =tsymbollist[tsymbol]
|
||||
bid_p=rquotes['bid_p']
|
||||
ask_p=rquotes['ask_p']
|
||||
bid_v=rquotes['bid_v']
|
||||
ask_v=rquotes['ask_v']
|
||||
tsymbollist[tsymbol]=tick
|
||||
tick_dt=pd.DataFrame({'datetime':timetick,'symbol':tick['symbol'],'mainsym':tick['symbol'].rstrip('0123456789').upper(),'lastprice':tick['price'],
|
||||
'vol':tick['last_volume'],
|
||||
'bid_p':bid_p,'ask_p':ask_p,'bid_v':bid_v,'ask_v':ask_v},index=[0])
|
||||
sym = tick_dt['symbol'][0]
|
||||
#print(tick_dt)
|
||||
self.tickdata(tick_dt,sym)
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def data_of(self,symbol, df):
|
||||
global trade_dfs
|
||||
# 将df数据合并到trader_df中
|
||||
# if symbol not in trade_dfs.keys():
|
||||
# trade_df = pd.DataFrame({})
|
||||
# else:
|
||||
# trade_df = trade_dfs[symbol]
|
||||
trade_dfs[symbol] = pd.concat([trade_dfs[symbol], df], ignore_index=True)
|
||||
# print('!!!!!!!!!!!trader_df: ', symbol, df['datetime'].iloc[-1])
|
||||
#print(trader_df)
|
||||
|
||||
def process(self,bidDict, askDict, symbol):
|
||||
try:
|
||||
# 尝试从quotedict中获取对应品种的报价数据
|
||||
dic = quotedict[symbol]
|
||||
bidDictResult = dic['bidDictResult']
|
||||
askDictResult = dic['askDictResult']
|
||||
except:
|
||||
# 如果获取失败,则初始化bidDictResult和askDictResult为空字典
|
||||
bidDictResult, askDictResult = {}, {}
|
||||
|
||||
# 将所有买盘字典和卖盘字典的key合并,并按升序排序
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
|
||||
# 遍历所有的key,将相同key的值进行累加
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
if s in bidDictResult:
|
||||
bidDictResult[s] = int(bidDict[s]) + bidDictResult[s]
|
||||
else:
|
||||
bidDictResult[s] = int(bidDict[s])
|
||||
if s not in askDictResult:
|
||||
askDictResult[s] = 0
|
||||
else:
|
||||
if s in askDictResult:
|
||||
askDictResult[s] = int(askDict[s]) + askDictResult[s]
|
||||
else:
|
||||
askDictResult[s] = int(askDict[s])
|
||||
if s not in bidDictResult:
|
||||
bidDictResult[s] = 0
|
||||
|
||||
# 构建包含bidDictResult和askDictResult的字典,并存入quotedict中
|
||||
df = {'bidDictResult': bidDictResult, 'askDictResult': askDictResult}
|
||||
quotedict[symbol] = df
|
||||
|
||||
return bidDictResult, askDictResult
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
|
||||
def tickdata(self,df,symbol):
|
||||
tickdata =pd.DataFrame({'datetime':df['datetime'],'symbol':df['symbol'],'lastprice':df['lastprice'],
|
||||
'volume':df['vol'],'bid_p':df['bid_p'],'bid_v':df['bid_v'],'ask_p':df['ask_p'],'ask_v':df['ask_v']})
|
||||
try:
|
||||
if symbol in tickdatadict.keys():
|
||||
rdf=tickdatadict[symbol]
|
||||
rdftm=pd.to_datetime(rdf['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
now=str(tickdata['datetime'][0])
|
||||
if now>rdftm:
|
||||
try:
|
||||
oo=ofdatadict[symbol]
|
||||
self.data_of(symbol, oo)
|
||||
#print('oo',oo)
|
||||
if symbol in quotedict.keys():
|
||||
quotedict.pop(symbol)
|
||||
if symbol in tickdatadict.keys():
|
||||
tickdatadict.pop(symbol)
|
||||
if symbol in ofdatadict.keys():
|
||||
ofdatadict.pop(symbol)
|
||||
except IOError as e:
|
||||
print('rdftm捕获到异常',e)
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
else:
|
||||
tickdata['bartime'] = rdf['bartime']
|
||||
tickdata['open'] = rdf['open']
|
||||
tickdata['high'] = max(tickdata['lastprice'].values,rdf['high'].values)
|
||||
tickdata['low'] = min(tickdata['lastprice'].values,rdf['low'].values)
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['volume']=df['vol']+rdf['volume'].values
|
||||
tickdata['starttime'] = rdf['starttime']
|
||||
else :
|
||||
print('新bar的第一个tick进入')
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
except IOError as e:
|
||||
print('捕获到异常',e)
|
||||
|
||||
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['bartime'])
|
||||
param = self.param_dict[self.品种]
|
||||
bardata = tickdata.resample(on = 'bartime',rule = param.周期,label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
bardata['bartime'] = pd.to_datetime(bardata['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
tickdatadict[symbol]=bardata
|
||||
tickdata['volume']=df['vol'].values
|
||||
#print(bardata['symbol'].values,bardata['bartime'].values)
|
||||
self.orderflow_df_new(tickdata,bardata,symbol)
|
||||
# time.sleep(0.5)
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def orderflow_df_new(self,df_tick,df_min,symbol):
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
#endArray = pd.to_datetime(df_min['bartime']).values
|
||||
endArray = df_min['bartime'].values
|
||||
#print(endArray)
|
||||
deltaArray = np.zeros((len(endArray),))
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
dt=endArray[index]
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
# for indexTick in range(indexFinal,len(df_tick)):
|
||||
# if tTickArray[indexTick] >= tEnd:
|
||||
# break
|
||||
# elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] < tEnd):
|
||||
Bp = round(bp1TickArray[0],4)
|
||||
Ap = round(ap1TickArray[0],4)
|
||||
LastPrice = round(lastTickArray[0],4)
|
||||
Volume = volumeTickArray[0]
|
||||
if LastPrice >= Ap:
|
||||
if str(LastPrice) in askDict.keys():
|
||||
askDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
askDict[str(LastPrice)] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if str(LastPrice) in bidDict.keys():
|
||||
bidDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
bidDict[str(LastPrice)] = Volume
|
||||
# indexFinal = indexTick
|
||||
bidDictResult,askDictResult = self.process(bidDict,askDict,symbol)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
#print(prinslist,asklist,bidlist)
|
||||
#print(len(prinslist),len(bidDictResult),len(askDictResult))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
#df=pd.DataFrame({'price':pd.Series(bidDictResult.keys()),'Ask':pd.Series(askDictResult.values()),'Bid':pd.Series(bidDictResult.values())})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
#df['ticktime']=tTickArray[0]
|
||||
df['dj'] = self.GetOrderFlow_dj(df)
|
||||
ofdatadict[symbol]=df
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def GetOrderFlow_dj(self,kData):
|
||||
param = self.param_dict[self.品种]
|
||||
Config = {
|
||||
'Value1': param.失衡,
|
||||
'Value2': param.堆积,
|
||||
'Value4': True,
|
||||
}
|
||||
aryData = kData
|
||||
djcout = 0
|
||||
|
||||
# 遍历kData中的每一行,计算djcout指标
|
||||
for index, row in aryData.iterrows():
|
||||
kItem = aryData.iloc[index]
|
||||
high = kItem['high']
|
||||
low = kItem['low']
|
||||
close = kItem['close']
|
||||
open = kItem['open']
|
||||
dtime = kItem['datetime']
|
||||
price_s = kItem['price']
|
||||
Ask_s = kItem['Ask']
|
||||
Bid_s = kItem['Bid']
|
||||
delta = kItem['delta']
|
||||
|
||||
price_s = price_s
|
||||
Ask_s = Ask_s
|
||||
Bid_s = Bid_s
|
||||
|
||||
gj = 0
|
||||
xq = 0
|
||||
gxx = 0
|
||||
xxx = 0
|
||||
|
||||
# 遍历price_s中的每一个元素,计算相关指标
|
||||
for i in np.arange(0, len(price_s), 1):
|
||||
duiji = {
|
||||
'price': 0,
|
||||
'time': 0,
|
||||
'longshort': 0,
|
||||
}
|
||||
|
||||
if i == 0:
|
||||
delta = delta
|
||||
|
||||
order= {
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
#空头堆积
|
||||
if i >= 0 and i < len(price_s) - 1:
|
||||
if (order["Bid"]["Value"] > Ask_s[i + 1] * int(Config['Value1'])):
|
||||
gxx += 1
|
||||
gj += 1
|
||||
if gj >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = -1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += -1
|
||||
else:
|
||||
gj = 0
|
||||
#多头堆积
|
||||
if i >= 1 and i <= len(price_s) - 1:
|
||||
if (order["Ask"]["Value"] > Bid_s[i - 1] * int(Config['Value1'])):
|
||||
xq += 1
|
||||
xxx += 1
|
||||
if xq >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = 1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += 1
|
||||
else:
|
||||
xq = 0
|
||||
|
||||
# 返回计算得到的djcout值
|
||||
return djcout
|
||||
|
||||
#读取保存的数据
|
||||
def read_to_csv(self,symbol):
|
||||
# 文件夹路径和文件路径
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
param = self.param_dict[symbol]
|
||||
# symbol = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
folder_path = "traderdata"
|
||||
file_path = os.path.join(folder_path, f"{str(symbol)}_traderdata.csv")
|
||||
# 如果文件夹不存在则创建
|
||||
if not os.path.exists(folder_path):
|
||||
os.makedirs(folder_path)
|
||||
|
||||
# 读取保留的模型数据CSV文件
|
||||
if os.path.exists(file_path):
|
||||
df = pd.read_csv(file_path)
|
||||
if not df.empty and param.kgdata==True:
|
||||
# 选择最后一行数据
|
||||
row = df.iloc[-1]
|
||||
|
||||
# 根据CSV文件的列名将数据赋值给相应的属性
|
||||
param.pos = int(row['pos'])
|
||||
param.short_trailing_stop_price = float(row['short_trailing_stop_price'])
|
||||
param.long_trailing_stop_price = float(row['long_trailing_stop_price'])
|
||||
param.sl_long_price = float(row['sl_long_price'])
|
||||
param.sl_shor_price = float(row['sl_shor_price'])
|
||||
# param.out_long = int(row['out_long'])
|
||||
# param.out_short = int(row['out_short'])
|
||||
print("找到历史交易数据文件,已经更新持仓,止损止盈数据", df.iloc[-1])
|
||||
param.kgdata=False
|
||||
else:
|
||||
pass
|
||||
#print("没有找到历史交易数据文件", file_path)
|
||||
#如果没有找到CSV,则初始化变量
|
||||
|
||||
pass
|
||||
|
||||
#保存数据
|
||||
def save_to_csv(self,symbol):
|
||||
param = self.param_dict[symbol]
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
# symbol = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
# 创建DataFrame
|
||||
|
||||
data = {
|
||||
'datetime': [trade_dfs[symbol]['datetime'].iloc[-1]],
|
||||
'pos': [param.pos],
|
||||
'short_trailing_stop_price': [param.short_trailing_stop_price],
|
||||
'long_trailing_stop_price': [param.long_trailing_stop_price],
|
||||
'sl_long_price': [param.sl_long_price],
|
||||
'sl_shor_price': [param.sl_shor_price],
|
||||
# 'out_long': [param.out_long],
|
||||
# 'out_short': [param.out_short]
|
||||
}
|
||||
|
||||
df = pd.DataFrame(data)
|
||||
|
||||
# 将DataFrame保存到CSV文件
|
||||
df.to_csv(f"traderdata/{str(symbol)}_traderdata.csv", index=False)
|
||||
|
||||
#每日收盘重置数据
|
||||
def day_data_reset(self, symbol):
|
||||
param = self.param_dict[symbol]
|
||||
sec = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
# 获取当前时间
|
||||
current_time = datetime.now().time()
|
||||
|
||||
# 第一时间范围(日盘收盘)
|
||||
clearing_time1_start = s_time(15,00)
|
||||
clearing_time1_end = s_time(15,15)
|
||||
|
||||
# 创建一个标志变量,用于记录是否已经执行过
|
||||
param.clearing_executed = False
|
||||
# 检查当前时间第一个操作的时间范围内
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not param.clearing_executed :
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
trade_dfs[symbol].drop(trade_dfs[symbol].index,inplace=True)#清除当天的行情数据
|
||||
|
||||
# 检查当前时间是否在第二个操作的时间范围内(夜盘收盘)
|
||||
elif sec in clearing_time_dict.keys():
|
||||
clearing_time2_start = clearing_time_dict[sec]
|
||||
clearing_time2_end = s_time(clearing_time2_start.hour, clearing_time2_start.minute+15)
|
||||
if clearing_time2_start <= current_time <= clearing_time2_end and not param.clearing_executed :
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
trade_dfs[symbol].drop(trade_dfs[symbol].index,inplace=True) #清除当天的行情数据
|
||||
else:
|
||||
param.clearing_executed = False
|
||||
pass
|
||||
return param.clearing_executed
|
||||
|
||||
def OnRtnTrade(self, pTrade):
|
||||
print("||成交回报||", pTrade)
|
||||
|
||||
def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast):
|
||||
print("||OnRspOrderInsert||", pInputOrder, pRspInfo, nRequestID, bIsLast)
|
||||
|
||||
# 订单状态通知
|
||||
def OnRtnOrder(self, pOrder):
|
||||
print("||订单回报||", pOrder)
|
||||
|
||||
def cal_sig(self, symbol_queue):
|
||||
while True:
|
||||
try:
|
||||
data = symbol_queue.get(block=True, timeout=5) # 如果5秒没收到新的tick行情,则抛出异常
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
size = symbol_queue.qsize()
|
||||
if size > 1:
|
||||
print(f'当前{instrument_id}共享队列长度为{size}, 有点阻塞!!!!!')
|
||||
self.read_to_csv(instrument_id)
|
||||
self.day_data_reset(instrument_id)
|
||||
param = self.param_dict[instrument_id]
|
||||
self.品种=instrument_id
|
||||
self.tickcome(data)
|
||||
trade_df = trade_dfs[instrument_id]
|
||||
#新K线开始,启动交易程序 and 保存行情数据
|
||||
self.read_to_csv(instrument_id)
|
||||
# size = symbol_queue.qsize()
|
||||
# if size > 2:
|
||||
# print(f'!!!!!当前{instrument_id}共享队列长度为:',size)
|
||||
if len(trade_df)>param.cont_df:
|
||||
# 检查文件是否存在
|
||||
csv_file_path = f"traderdata/{instrument_id}_ofdata.csv"
|
||||
if os.path.exists(csv_file_path):
|
||||
# 仅保存最后一行数据
|
||||
trade_df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
else:
|
||||
# 创建新文件并保存整个DataFrame
|
||||
trade_df.to_csv(csv_file_path, index=False)
|
||||
|
||||
# 更新跟踪止损价格
|
||||
if param.long_trailing_stop_price >0 and param.pos>0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧多头出线',param.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
param.long_trailing_stop_price = trade_df['low'].iloc[-1] if param.long_trailing_stop_price<trade_df['low'].iloc[-1] else param.long_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#print('datetime+sig: ',dt,'多头出线',param.long_trailing_stop_price)
|
||||
if param.short_trailing_stop_price >0 and param.pos<0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧空头出线',param.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
param.short_trailing_stop_price = trade_df['high'].iloc[-1] if trade_df['high'].iloc[-1] <param.short_trailing_stop_price else param.short_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#print('datetime+sig: ',dt,'空头出线',param.short_trailing_stop_price)
|
||||
|
||||
param.out_long=param.long_trailing_stop_price * (1 - param.trailing_stop_percent)
|
||||
param.out_short=param.short_trailing_stop_price*(1 + param.trailing_stop_percent)
|
||||
#print('datetime+sig: ',dt,'空头出线',param.out_short)
|
||||
#print('datetime+sig: ',dt,'多头出线',param.out_long)
|
||||
# 跟踪出场
|
||||
if param.out_long >0:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'预设——多头止盈——','TR',param.out_long,'low', trade_df['low'].iloc[-1])
|
||||
if trade_df['low'].iloc[-1] < param.out_long and param.pos>0 and param.sl_long_price>0 and trade_df['low'].iloc[-1]>param.sl_long_price:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'多头止盈','TR',param.out_long,'low', trade_df['low'].iloc[-1])
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.long_trailing_stop_price = 0
|
||||
param.out_long=0
|
||||
param.sl_long_price=0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
if param.out_short>0:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'预设——空头止盈——: ','TR',param.out_short,'high', trade_df['high'].iloc[-1])
|
||||
if trade_df['high'].iloc[-1] > param.out_short and param.pos<0 and param.sl_shor_price>0 and trade_df['high'].iloc[-1]<param.sl_shor_price:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'空头止盈: ','TR',param.out_short,'high', trade_df['high'].iloc[-1])
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.short_trailing_stop_price = 0
|
||||
param.sl_shor_price=0
|
||||
self.out_shor=0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 固定止损
|
||||
fixed_stop_loss_L = param.sl_long_price * (1 - param.fixed_stop_loss_percent)
|
||||
if param.pos>0:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '预设——多头止损', 'SL', fixed_stop_loss_L, 'close', trade_df['close'].iloc[-1])
|
||||
if param.sl_long_price>0 and fixed_stop_loss_L>0 and param.pos > 0 and trade_df['close'].iloc[-1] < fixed_stop_loss_L:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '多头止损', 'SL', fixed_stop_loss_L, 'close', trade_df['close'].iloc[-1])
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.long_trailing_stop_price = 0
|
||||
param.sl_long_price=0
|
||||
param.out_long = 0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
fixed_stop_loss_S = param.sl_shor_price * (1 + param.fixed_stop_loss_percent)
|
||||
if param.pos<0:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '预设——空头止损', 'SL', fixed_stop_loss_S, 'close', trade_df['close'].iloc[-1])
|
||||
if param.sl_shor_price>0 and fixed_stop_loss_S>0 and param.pos < 0 and trade_df['close'].iloc[-1] > fixed_stop_loss_S:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '空头止损', 'SL', fixed_stop_loss_S, 'close', trade_df['close'].iloc[-1])
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.short_trailing_stop_price = 0
|
||||
param.sl_shor_price=0
|
||||
param.out_short = 0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#日均线
|
||||
trade_df['dayma']=trade_df['close'].mean()
|
||||
|
||||
# 计算累积的delta值
|
||||
trade_df['delta'] = trade_df['delta'].astype(float)
|
||||
trade_df['delta累计'] = trade_df['delta'].cumsum()
|
||||
|
||||
#大于日均线
|
||||
开多1=trade_df['dayma'].iloc[-1] > 0 and trade_df['close'].iloc[-1] > trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量大于X
|
||||
开多4=trade_df['delta累计'].iloc[-1] > param.sum_delta and trade_df['delta'].iloc[-1] > param.delta
|
||||
|
||||
#小于日均线
|
||||
开空1=trade_df['dayma'].iloc[-1]>0 and trade_df['close'].iloc[-1] < trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量小于X
|
||||
开空4=trade_df['delta累计'].iloc[-1] < -param.sum_delta and trade_df['delta'].iloc[-1] < -param.delta
|
||||
开多组合= 开多1 and 开多4 and trade_df['dj'].iloc[-1]>param.dj_X
|
||||
开空条件= 开空1 and 开空4 and trade_df['dj'].iloc[-1]<-param.dj_X
|
||||
|
||||
平多条件=trade_df['dj'].iloc[-1]<-param.dj_X
|
||||
平空条件=trade_df['dj'].iloc[-1]>param.dj_X
|
||||
#开仓
|
||||
#多头开仓条件
|
||||
if param.pos<0 and 平空条件 :
|
||||
print('平空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+param.py)
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
param.sl_shor_price=0
|
||||
param.short_trailing_stop_price=0
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '反手平空:', '平仓价格:', data['AskPrice1']+param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
if param.pos==0 and 开多组合:
|
||||
print('开多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+param.py)
|
||||
#开多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'0')
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '多头开仓', '开仓价格:', data['AskPrice1']+param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
param.pos=1
|
||||
param.long_trailing_stop_price=data['AskPrice1']
|
||||
param.sl_long_price=data['AskPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
if param.pos>0 and 平多条件 :
|
||||
print('平多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1']-param.py)
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
param.long_trailing_stop_price=0
|
||||
param.sl_long_price=0
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '反手平多', '平仓价格:', data['BidPrice1']-param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
if param.pos==0 and 开空条件 :
|
||||
print('开空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1'])
|
||||
#开空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'0')
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '空头开仓', '开仓价格:', data['BidPrice1']-param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
param.pos=-1
|
||||
param.short_trailing_stop_price=data['BidPrice1']
|
||||
param.sl_shor_price=data['BidPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
print(trade_df)
|
||||
param.cont_df=len(trade_df)
|
||||
except queue.Empty:
|
||||
# print(f"当前合约队列为空,等待新数据插入。")
|
||||
pass
|
||||
|
||||
# 将CTP推送的行情数据分发给对应线程队列去执行
|
||||
def distribute_tick(self):
|
||||
while True:
|
||||
if self.status == 0:
|
||||
data = None
|
||||
while not self.md_queue.empty():
|
||||
data = self.md_queue.get(block=False)
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
try:
|
||||
self.queue_dict[instrument_id].put(data, block=False) # 往对应合约队列中插入行情
|
||||
# print(f"{instrument_id}合约数据插入。")
|
||||
except queue.Full:
|
||||
# 当某个线程阻塞导致对应队列容量超限时抛出异常,不会影响其他合约的信号计算
|
||||
print(f"{instrument_id}合约信号计算阻塞导致对应队列已满,请检查对应代码逻辑后重启。")
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
def start(self, param_dict):
|
||||
threads = []
|
||||
self.param_dict = param_dict
|
||||
for symbol in param_dict.keys():
|
||||
trade_dfs[symbol] = pd.DataFrame({})
|
||||
self.queue_dict[symbol] = queue.Queue(10) #为每个合约创建一个限制数为10的队列,当计算发生阻塞导致队列达到限制数时会抛出异常
|
||||
t = threading.Thread(target=self.cal_sig, args=(self.queue_dict[symbol],)) # 为每个合约单独创建一个线程计算开仓逻辑
|
||||
threads.append(t)
|
||||
t.start()
|
||||
self.distribute_tick()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
def run_trader(param_dict, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
my_trader = MyTrader(broker_id, td_server, investor_id, password, app_id, auth_code, md_queue, page_dir, private_resume_type, public_resume_type)
|
||||
my_trader.start(param_dict)
|
||||
|
||||
if __name__ == '__main__':
|
||||
#global symbol
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
#注意:运行前请先安装好algoplus,
|
||||
# pip install AlgoPlus
|
||||
#http://www.algo.plus/ctp/python/0103001.html
|
||||
|
||||
# 实盘参数字典,需要实盘交易的合约,新建对应的参数对象即可,以下参数仅供测试使用,不作为实盘参考!!!!
|
||||
# 实盘参数字典,需要实盘交易的合约,新建对应的参数对象即可,以下参数仅供测试使用,不作为实盘参考!!!!
|
||||
# 实盘参数字典,需要实盘交易的合约,新建对应的参数对象即可,以下参数仅供测试使用,不作为实盘参考!!!!
|
||||
param_dict = {}
|
||||
param_dict['rb2405'] = ParamObj(symbol='rb2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict['ni2405'] = ParamObj(symbol='ni2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
param_dict['j2405'] = ParamObj(symbol='j2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
param_dict['TA405'] = ParamObj(symbol='TA405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
param_dict['au2406'] = ParamObj(symbol='au2406', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
param_dict['sc2405'] = ParamObj(symbol='sc2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
param_dict['bc2405'] = ParamObj(symbol='bc2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
param_dict['lu2405'] = ParamObj(symbol='lu2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
|
||||
#用simnow模拟,不要忘记屏蔽下方实盘的future_account字典
|
||||
future_account = get_simulate_account(
|
||||
investor_id='', # simnow账户,注意是登录账户的ID,SIMNOW个人首页查看
|
||||
password='', # simnow密码
|
||||
server_name='电信1', # 电信1、电信2、移动、TEST、N视界
|
||||
subscribe_list=list(param_dict.keys()), # 合约列表
|
||||
)
|
||||
|
||||
#实盘用这个,不要忘记屏蔽上方simnow的future_account字典
|
||||
# future_account = FutureAccount(
|
||||
# broker_id='', # 期货公司BrokerID
|
||||
# server_dict={'TDServer': "ip:port", 'MDServer': 'ip:port'}, # TDServer为交易服务器,MDServer为行情服务器。服务器地址格式为"ip:port。"
|
||||
# reserve_server_dict={}, # 备用服务器地址
|
||||
# investor_id='', # 账户
|
||||
# password='', # 密码
|
||||
# app_id='simnow_client_test', # 认证使用AppID
|
||||
# auth_code='0000000000000000', # 认证使用授权码
|
||||
# subscribe_list=list(param_dict.keys()), # 订阅合约列表
|
||||
# md_flow_path='./log', # MdApi流文件存储地址,默认MD_LOCATION
|
||||
# td_flow_path='./log', # TraderApi流文件存储地址,默认TD_LOCATION
|
||||
# )
|
||||
|
||||
|
||||
print('开始',len(future_account.subscribe_list))
|
||||
# 共享队列
|
||||
share_queue = Queue(maxsize=200)
|
||||
|
||||
# 行情进程
|
||||
md_process = Process(target=run_tick_engine, args=(future_account, [share_queue]))
|
||||
|
||||
|
||||
# 交易进程
|
||||
trader_process = Process(target=run_trader, args=(
|
||||
param_dict,
|
||||
future_account.broker_id,
|
||||
future_account.server_dict['TDServer'],
|
||||
future_account.investor_id,
|
||||
future_account.password,
|
||||
future_account.app_id,
|
||||
future_account.auth_code,
|
||||
share_queue, # 队列
|
||||
future_account.td_flow_path
|
||||
))
|
||||
|
||||
md_process.start()
|
||||
trader_process.start()
|
||||
|
||||
md_process.join()
|
||||
trader_process.join()
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
定时启动可以每日避开收盘时间,
|
||||
|
||||
只要设置好实盘运行版本.py里的账户,品种,以及程序参数,可以使用定时启动,每日无人监管。
|
||||
@@ -0,0 +1,928 @@
|
||||
"""
|
||||
该代码的主要目的是处理Tick数据并生成交易信号。代码中定义了一个tickcome函数,它接收到Tick数据后会进行一系列的处理,包括构建Tick字典、更新上一个Tick的成交量、保存Tick数据、生成K线数据等。其中涉及到的一些函数有:
|
||||
|
||||
on_tick(tick): 处理单个Tick数据,根据Tick数据生成K线数据。
|
||||
tickdata(df, symbol): 处理Tick数据,生成K线数据。
|
||||
orderflow_df_new(df_tick, df_min, symbol): 处理Tick和K线数据,生成订单流数据。
|
||||
GetOrderFlow_dj(kData): 计算订单流的信号指标。
|
||||
除此之外,代码中还定义了一个MyTrader类,继承自TraderApiBase,用于实现交易相关的功能。
|
||||
"""
|
||||
|
||||
# from multiprocessing import Process, Queue
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
import operator
|
||||
# import time
|
||||
import numpy as np
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
tickdatadict = {} # 存储Tick数据的字典
|
||||
quotedict = {} # 存储行情数据的字典
|
||||
ofdatadict = {} # 存储K线数据的字典
|
||||
trader_df = pd.DataFrame({}) # 存储交易数据的DataFrame对象
|
||||
previous_volume = {} # 上一个Tick的成交量
|
||||
tsymbollist = {}
|
||||
|
||||
|
||||
def tickcome(md_queue):
|
||||
global previous_volume
|
||||
|
||||
data = md_queue
|
||||
instrument_id = data["InstrumentID"] # 品种代码
|
||||
# 将 ActionDay 转换为日期字符串
|
||||
action_day = pd.to_datetime(data["ActionDay"]).strftime("%Y-%m-%d")
|
||||
# 从 UpdateTime 中提取时间部分
|
||||
update_time = pd.to_datetime(data["UpdateTime"]).strftime("%H:%M:%S")
|
||||
# 组合时间字符串
|
||||
created_at = f"{action_day} {update_time}.{data['UpdateMillisec']:03d}"
|
||||
# created_at = ActionDay[:4] + '-' + ActionDay[4:6] + '-' + ActionDay[6:] + ' ' + update_time + '.' + update_millisec #创建时间
|
||||
# 构建tick字典
|
||||
tick = {
|
||||
"symbol": instrument_id, # 品种代码和交易所ID
|
||||
"created_at": datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S.%f"),
|
||||
# 'created_at': created_at, # 创建时间
|
||||
"price": float(data["LastPrice"]), # 最新价
|
||||
"last_volume": int(data["Volume"]) - previous_volume.get(instrument_id, 0)
|
||||
if previous_volume.get(instrument_id, 0) != 0
|
||||
else 0, # 瞬时成交量
|
||||
"bid_p": float(data["BidPrice1"]), # 买价
|
||||
"bid_v": int(data["BidVolume1"]), # 买量
|
||||
"ask_p": float(data["AskPrice1"]), # 卖价
|
||||
"ask_v": int(data["AskVolume1"]), # 卖量
|
||||
"UpperLimitPrice": float(data["UpperLimitPrice"]), # 涨停价
|
||||
"LowerLimitPrice": float(data["LowerLimitPrice"]), # 跌停价
|
||||
"TradingDay": data["TradingDay"], # 交易日日期
|
||||
"cum_volume": int(data["Volume"]), # 最新总成交量
|
||||
"cum_amount": float(data["Turnover"]), # 最新总成交额
|
||||
"cum_position": int(data["OpenInterest"]), # 合约持仓量
|
||||
}
|
||||
# 更新上一个Tick的成交量
|
||||
previous_volume[instrument_id] = int(data["Volume"])
|
||||
if tick["last_volume"] > 0:
|
||||
# print(tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 处理Tick数据
|
||||
on_tick(tick)
|
||||
|
||||
|
||||
def can_time(hour, minute):
|
||||
hour = str(hour)
|
||||
minute = str(minute)
|
||||
if len(minute) == 1:
|
||||
minute = "0" + minute
|
||||
return int(hour + minute)
|
||||
|
||||
|
||||
def on_tick(tick):
|
||||
# tm = can_time(tick["created_at"].hour, tick["created_at"].minute)
|
||||
# print(tick['symbol'])
|
||||
# print(1)
|
||||
# if tm>1500 and tm<2100 :
|
||||
# return
|
||||
if tick["last_volume"] == 0:
|
||||
return
|
||||
quotes = tick
|
||||
timetick = str(tick["created_at"]).replace("+08:00", "")
|
||||
tsymbol = tick["symbol"]
|
||||
if tsymbol not in tsymbollist.keys():
|
||||
# 获取tick的买卖价和买卖量
|
||||
tsymbollist[tsymbol] = tick
|
||||
bid_p = quotes["bid_p"]
|
||||
ask_p = quotes["ask_p"]
|
||||
bid_v = quotes["bid_v"]
|
||||
ask_v = quotes["ask_v"]
|
||||
else:
|
||||
# 获取上一个tick的买卖价和买卖量
|
||||
rquotes = tsymbollist[tsymbol]
|
||||
bid_p = rquotes["bid_p"]
|
||||
ask_p = rquotes["ask_p"]
|
||||
bid_v = rquotes["bid_v"]
|
||||
ask_v = rquotes["ask_v"]
|
||||
tsymbollist[tsymbol] = tick
|
||||
tick_dt = pd.DataFrame(
|
||||
{
|
||||
"datetime": timetick,
|
||||
"symbol": tick["symbol"],
|
||||
"mainsym": tick["symbol"].rstrip("0123456789").upper(),
|
||||
"lastprice": tick["price"],
|
||||
"vol": tick["last_volume"],
|
||||
"bid_p": bid_p,
|
||||
"ask_p": ask_p,
|
||||
"bid_v": bid_v,
|
||||
"ask_v": ask_v,
|
||||
},
|
||||
index=[0],
|
||||
)
|
||||
sym = tick_dt["symbol"][0]
|
||||
# print(tick_dt)
|
||||
tickdata(tick_dt, sym)
|
||||
|
||||
|
||||
def data_of(df):
|
||||
global trader_df
|
||||
# 将df数据合并到trader_df中
|
||||
trader_df = pd.concat([trader_df, df], ignore_index=True)
|
||||
# print('trader_df: ', len(trader_df))
|
||||
# print(trader_df)
|
||||
|
||||
|
||||
def process(bidDict, askDict, symbol):
|
||||
try:
|
||||
# 尝试从quotedict中获取对应品种的报价数据
|
||||
dic = quotedict[symbol]
|
||||
bidDictResult = dic["bidDictResult"]
|
||||
askDictResult = dic["askDictResult"]
|
||||
except Exception:
|
||||
# 如果获取失败,则初始化bidDictResult和askDictResult为空字典
|
||||
bidDictResult, askDictResult = {}, {}
|
||||
|
||||
# 将所有买盘字典和卖盘字典的key合并,并按升序排序
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
|
||||
# 遍历所有的key,将相同key的值进行累加
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
if s in bidDictResult:
|
||||
bidDictResult[s] = int(bidDict[s]) + bidDictResult[s]
|
||||
else:
|
||||
bidDictResult[s] = int(bidDict[s])
|
||||
if s not in askDictResult:
|
||||
askDictResult[s] = 0
|
||||
else:
|
||||
if s in askDictResult:
|
||||
askDictResult[s] = int(askDict[s]) + askDictResult[s]
|
||||
else:
|
||||
askDictResult[s] = int(askDict[s])
|
||||
if s not in bidDictResult:
|
||||
bidDictResult[s] = 0
|
||||
|
||||
# 构建包含bidDictResult和askDictResult的字典,并存入quotedict中
|
||||
df = {"bidDictResult": bidDictResult, "askDictResult": askDictResult}
|
||||
quotedict[symbol] = df
|
||||
|
||||
return bidDictResult, askDictResult
|
||||
|
||||
|
||||
def tickdata(df, symbol):
|
||||
tickdata = pd.DataFrame(
|
||||
{
|
||||
"datetime": df["datetime"],
|
||||
"symbol": df["symbol"],
|
||||
"lastprice": df["lastprice"],
|
||||
"volume": df["vol"],
|
||||
"bid_p": df["bid_p"],
|
||||
"bid_v": df["bid_v"],
|
||||
"ask_p": df["ask_p"],
|
||||
"ask_v": df["ask_v"],
|
||||
}
|
||||
)
|
||||
try:
|
||||
if symbol in tickdatadict.keys():
|
||||
rdf = tickdatadict[symbol]
|
||||
rdftm = pd.to_datetime(rdf["bartime"][0]).strftime("%Y-%m-%d %H:%M:%S")
|
||||
now = str(tickdata["datetime"][0])
|
||||
if now > rdftm:
|
||||
try:
|
||||
oo = ofdatadict[symbol]
|
||||
data_of(oo)
|
||||
# print('oo',oo)
|
||||
if symbol in quotedict.keys():
|
||||
quotedict.pop(symbol)
|
||||
if symbol in tickdatadict.keys():
|
||||
tickdatadict.pop(symbol)
|
||||
if symbol in ofdatadict.keys():
|
||||
ofdatadict.pop(symbol)
|
||||
except IOError as e:
|
||||
print("rdftm捕获到异常", e)
|
||||
tickdata["bartime"] = pd.to_datetime(tickdata["datetime"])
|
||||
tickdata["open"] = tickdata["lastprice"]
|
||||
tickdata["high"] = tickdata["lastprice"]
|
||||
tickdata["low"] = tickdata["lastprice"]
|
||||
tickdata["close"] = tickdata["lastprice"]
|
||||
tickdata["starttime"] = tickdata["datetime"]
|
||||
else:
|
||||
tickdata["bartime"] = rdf["bartime"]
|
||||
tickdata["open"] = rdf["open"]
|
||||
tickdata["high"] = max(tickdata["lastprice"].values, rdf["high"].values)
|
||||
tickdata["low"] = min(tickdata["lastprice"].values, rdf["low"].values)
|
||||
tickdata["close"] = tickdata["lastprice"]
|
||||
tickdata["volume"] = df["vol"] + rdf["volume"].values
|
||||
tickdata["starttime"] = rdf["starttime"]
|
||||
else:
|
||||
print("新bar的第一个tick进入")
|
||||
tickdata["bartime"] = pd.to_datetime(tickdata["datetime"])
|
||||
tickdata["open"] = tickdata["lastprice"]
|
||||
tickdata["high"] = tickdata["lastprice"]
|
||||
tickdata["low"] = tickdata["lastprice"]
|
||||
tickdata["close"] = tickdata["lastprice"]
|
||||
tickdata["starttime"] = tickdata["datetime"]
|
||||
except IOError as e:
|
||||
print("捕获到异常", e)
|
||||
|
||||
tickdata["bartime"] = pd.to_datetime(tickdata["bartime"])
|
||||
bardata = (
|
||||
tickdata.resample(on="bartime", rule="1T", label="right", closed="right")
|
||||
.agg(
|
||||
{
|
||||
"starttime": "first",
|
||||
"symbol": "last",
|
||||
"open": "first",
|
||||
"high": "max",
|
||||
"low": "min",
|
||||
"close": "last",
|
||||
"volume": "sum",
|
||||
}
|
||||
)
|
||||
.reset_index(drop=False)
|
||||
)
|
||||
bardata = bardata.dropna().reset_index(drop=True)
|
||||
bardata["bartime"] = pd.to_datetime(bardata["bartime"][0]).strftime(
|
||||
"%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
tickdatadict[symbol] = bardata
|
||||
tickdata["volume"] = df["vol"].values
|
||||
# print(bardata['symbol'].values,bardata['bartime'].values)
|
||||
orderflow_df_new(tickdata, bardata, symbol)
|
||||
# time.sleep(0.5)
|
||||
|
||||
|
||||
def orderflow_df_new(df_tick, df_min, symbol):
|
||||
# startArray = pd.to_datetime(df_min["starttime"]).values
|
||||
voluememin = df_min["volume"].values
|
||||
highs = df_min["high"].values
|
||||
lows = df_min["low"].values
|
||||
opens = df_min["open"].values
|
||||
closes = df_min["close"].values
|
||||
# endArray = pd.to_datetime(df_min['bartime']).values
|
||||
endArray = df_min["bartime"].values
|
||||
# print(endArray)
|
||||
# deltaArray = np.zeros((len(endArray),))
|
||||
# tTickArray = pd.to_datetime(df_tick["datetime"]).values
|
||||
bp1TickArray = df_tick["bid_p"].values
|
||||
ap1TickArray = df_tick["ask_p"].values
|
||||
lastTickArray = df_tick["lastprice"].values
|
||||
volumeTickArray = df_tick["volume"].values
|
||||
symbolarray = df_tick["symbol"].values
|
||||
# indexFinal = 0
|
||||
for index, tEnd in enumerate(endArray):
|
||||
dt = endArray[index]
|
||||
# start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol = voluememin[index]
|
||||
bar_close = closes[index]
|
||||
bar_open = opens[index]
|
||||
bar_low = lows[index]
|
||||
bar_high = highs[index]
|
||||
bar_symbol = symbolarray[index]
|
||||
# for indexTick in range(indexFinal,len(df_tick)):
|
||||
# if tTickArray[indexTick] >= tEnd:
|
||||
# break
|
||||
# elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] < tEnd):
|
||||
Bp = round(bp1TickArray[0], 4)
|
||||
Ap = round(ap1TickArray[0], 4)
|
||||
LastPrice = round(lastTickArray[0], 4)
|
||||
Volume = volumeTickArray[0]
|
||||
if LastPrice >= Ap:
|
||||
if str(LastPrice) in askDict.keys():
|
||||
askDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
askDict[str(LastPrice)] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if str(LastPrice) in bidDict.keys():
|
||||
bidDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
bidDict[str(LastPrice)] = Volume
|
||||
# indexFinal = indexTick
|
||||
bidDictResult, askDictResult = process(bidDict, askDict, symbol)
|
||||
bidDictResult = dict(sorted(bidDictResult.items(), key=operator.itemgetter(0)))
|
||||
askDictResult = dict(sorted(askDictResult.items(), key=operator.itemgetter(0)))
|
||||
prinslist = list(bidDictResult.keys())
|
||||
asklist = list(askDictResult.values())
|
||||
bidlist = list(bidDictResult.values())
|
||||
delta = sum(askDictResult.values()) - sum(bidDictResult.values())
|
||||
# print(prinslist,asklist,bidlist)
|
||||
# print(len(prinslist),len(bidDictResult),len(askDictResult))
|
||||
df = pd.DataFrame(
|
||||
{
|
||||
"price": pd.Series([prinslist]),
|
||||
"Ask": pd.Series([asklist]),
|
||||
"Bid": pd.Series([bidlist]),
|
||||
}
|
||||
)
|
||||
# df=pd.DataFrame({'price':pd.Series(bidDictResult.keys()),'Ask':pd.Series(askDictResult.values()),'Bid':pd.Series(bidDictResult.values())})
|
||||
df["symbol"] = bar_symbol
|
||||
df["datetime"] = dt
|
||||
df["delta"] = str(delta)
|
||||
df["close"] = bar_close
|
||||
df["open"] = bar_open
|
||||
df["high"] = bar_high
|
||||
df["low"] = bar_low
|
||||
df["volume"] = bar_vol
|
||||
# df['ticktime']=tTickArray[0]
|
||||
df["dj"] = GetOrderFlow_dj(df)
|
||||
ofdatadict[symbol] = df
|
||||
|
||||
|
||||
def GetOrderFlow_dj(kData):
|
||||
Config = {
|
||||
"Value1": 3,
|
||||
"Value2": 3,
|
||||
"Value3": 3,
|
||||
"Value4": True,
|
||||
}
|
||||
aryData = kData
|
||||
djcout = 0
|
||||
|
||||
# 遍历kData中的每一行,计算djcout指标
|
||||
for index, row in aryData.iterrows():
|
||||
kItem = aryData.iloc[index]
|
||||
# high = kItem["high"]
|
||||
# low = kItem["low"]
|
||||
# close = kItem["close"]
|
||||
# open = kItem["open"]
|
||||
dtime = kItem["datetime"]
|
||||
price_s = kItem["price"]
|
||||
Ask_s = kItem["Ask"]
|
||||
Bid_s = kItem["Bid"]
|
||||
delta = kItem["delta"]
|
||||
|
||||
price_s = price_s
|
||||
Ask_s = Ask_s
|
||||
Bid_s = Bid_s
|
||||
|
||||
gj = 0
|
||||
xq = 0
|
||||
gxx = 0
|
||||
xxx = 0
|
||||
|
||||
# 遍历price_s中的每一个元素,计算相关指标
|
||||
for i in np.arange(0, len(price_s), 1):
|
||||
duiji = {
|
||||
"price": 0,
|
||||
"time": 0,
|
||||
"longshort": 0,
|
||||
}
|
||||
|
||||
if i == 0:
|
||||
delta = delta
|
||||
|
||||
order = {
|
||||
"Price": price_s[i],
|
||||
"Bid": {"Value": Bid_s[i]},
|
||||
"Ask": {"Value": Ask_s[i]},
|
||||
}
|
||||
# 空头堆积
|
||||
if i >= 0 and i < len(price_s) - 1:
|
||||
if order["Bid"]["Value"] > Ask_s[i + 1] * int(Config["Value1"]):
|
||||
gxx += 1
|
||||
gj += 1
|
||||
if gj >= int(Config["Value2"]) and Config["Value4"] is True:
|
||||
duiji["price"] = price_s[i]
|
||||
duiji["time"] = dtime
|
||||
duiji["longshort"] = -1
|
||||
if float(duiji["price"]) > 0:
|
||||
djcout += -1
|
||||
else:
|
||||
gj = 0
|
||||
# 多头堆积
|
||||
if i >= 1 and i <= len(price_s) - 1:
|
||||
if order["Ask"]["Value"] > Bid_s[i - 1] * int(Config["Value1"]):
|
||||
xq += 1
|
||||
xxx += 1
|
||||
if xq >= int(Config["Value2"]) and Config["Value4"] is True:
|
||||
duiji["price"] = price_s[i]
|
||||
duiji["time"] = dtime
|
||||
duiji["longshort"] = 1
|
||||
if float(duiji["price"]) > 0:
|
||||
djcout += 1
|
||||
else:
|
||||
xq = 0
|
||||
|
||||
# 返回计算得到的djcout值
|
||||
return djcout
|
||||
|
||||
|
||||
# 交易程序---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class 专享08of:
|
||||
def __init__(self):
|
||||
self.py = 5 # 设置委托价格的偏移,更加容易促成成交。仅螺纹,其他品种根据最小点波动,自己设置
|
||||
self.cont_df = 0
|
||||
self.trailing_stop_percent = 0.02 # 跟踪出场参数
|
||||
self.fixed_stop_loss_percent = 0.01 # 固定出场参数
|
||||
self.dj_X = 1 # 开仓的堆积参数
|
||||
|
||||
self.pos = 0
|
||||
self.Lots = 1 # 下单手数
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_long = 0
|
||||
self.out_short = 0
|
||||
self.clearing_executed = False
|
||||
self.kgdata = True
|
||||
|
||||
# 读取保存的数据
|
||||
def read_to_csv(self, symbol):
|
||||
# 文件夹路径和文件路径
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
symbol = "".join(re.findall("[a-zA-Z]", str(symbol)))
|
||||
folder_path = "traderdata"
|
||||
file_path = os.path.join(folder_path, f"{str(symbol)}traderdata.csv")
|
||||
# 如果文件夹不存在则创建
|
||||
if not os.path.exists(folder_path):
|
||||
os.makedirs(folder_path)
|
||||
|
||||
# 读取保留的模型数据CSV文件
|
||||
if os.path.exists(file_path):
|
||||
df = pd.read_csv(file_path)
|
||||
if not df.empty and self.kgdata is True:
|
||||
# 选择最后一行数据
|
||||
row = df.iloc[-1]
|
||||
# 根据CSV文件的列名将数据赋值给相应的属性
|
||||
self.pos = int(row["pos"])
|
||||
self.short_trailing_stop_price = float(row["short_trailing_stop_price"])
|
||||
self.long_trailing_stop_price = float(row["long_trailing_stop_price"])
|
||||
self.sl_long_price = float(row["sl_long_price"])
|
||||
self.sl_shor_price = float(row["sl_shor_price"])
|
||||
# self.out_long = int(row['out_long'])
|
||||
# self.out_short = int(row['out_short'])
|
||||
print("找到历史交易数据文件,已经更新持仓,止损止盈数据", df.iloc[-1])
|
||||
self.kgdata = False
|
||||
else:
|
||||
pass
|
||||
# print("没有找到历史交易数据文件", file_path)
|
||||
# 如果没有找到CSV,则初始化变量
|
||||
|
||||
pass
|
||||
|
||||
# 保存数据
|
||||
def save_to_csv(self, symbol):
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
symbol = "".join(re.findall("[a-zA-Z]", str(symbol)))
|
||||
# 创建DataFrame
|
||||
data = {
|
||||
"datetime": [trader_df["datetime"].iloc[-1]],
|
||||
"pos": [self.pos],
|
||||
"short_trailing_stop_price": [self.short_trailing_stop_price],
|
||||
"long_trailing_stop_price": [self.long_trailing_stop_price],
|
||||
"sl_long_price": [self.sl_long_price],
|
||||
"sl_shor_price": [self.sl_shor_price],
|
||||
# 'out_long': [self.out_long],
|
||||
# 'out_short': [self.out_short]
|
||||
}
|
||||
|
||||
df = pd.DataFrame(data)
|
||||
|
||||
# 将DataFrame保存到CSV文件
|
||||
df.to_csv(f"traderdata/{str(symbol)}traderdata.csv", index=False)
|
||||
|
||||
# 每日收盘重置数据
|
||||
def day_data_reset(self):
|
||||
# 获取当前时间
|
||||
current_time = datetime.now().time()
|
||||
|
||||
# 第一时间范围
|
||||
clearing_time1_start = s_time(15, 00)
|
||||
clearing_time1_end = s_time(15, 15)
|
||||
|
||||
# 第二时间范围
|
||||
clearing_time2_start = s_time(23, 0)
|
||||
clearing_time2_end = s_time(23, 15)
|
||||
|
||||
# 创建一个标志变量,用于记录是否已经执行过
|
||||
self.clearing_executed = False
|
||||
# 检查当前时间第一个操作的时间范围内
|
||||
if (
|
||||
clearing_time1_start <= current_time <= clearing_time1_end
|
||||
and not self.clearing_executed
|
||||
):
|
||||
self.clearing_executed = True # 设置标志变量为已执行
|
||||
trader_df.drop(trader_df.index, inplace=True) # 清除当天的行情数据
|
||||
|
||||
# 检查当前时间是否在第二个操作的时间范围内
|
||||
elif (
|
||||
clearing_time2_start <= current_time <= clearing_time2_end
|
||||
and not self.clearing_executed
|
||||
):
|
||||
self.clearing_executed = True # 设置标志变量为已执行
|
||||
trader_df.drop(trader_df.index, inplace=True) # 清除当天的行情数据
|
||||
else:
|
||||
self.clearing_executed = False
|
||||
pass
|
||||
return self.clearing_executed
|
||||
|
||||
def OnRtnTrade(self, pTrade):
|
||||
print("||成交回报||", pTrade)
|
||||
|
||||
def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast):
|
||||
print("||OnRspOrderInsert||", pInputOrder, pRspInfo, nRequestID, bIsLast)
|
||||
|
||||
# 订单状态通知
|
||||
def OnRtnOrder(self, pOrder):
|
||||
print("||订单回报||", pOrder)
|
||||
|
||||
def Join(self, tickdata):
|
||||
data = tickdata
|
||||
# print(tickdata)
|
||||
instrument_id = data["InstrumentID"] # 品种代码
|
||||
self.read_to_csv(instrument_id)
|
||||
self.day_data_reset()
|
||||
tickcome(data)
|
||||
# 新K线开始,启动交易程序 and 保存行情数据
|
||||
if len(trader_df) > self.cont_df:
|
||||
# 检查文件是否存在
|
||||
csv_file_path = f"traderdata/{instrument_id}_ofdata.csv"
|
||||
if os.path.exists(csv_file_path):
|
||||
# 仅保存最后一行数据
|
||||
trader_df.tail(1).to_csv(
|
||||
csv_file_path, mode="a", header=False, index=False
|
||||
)
|
||||
else:
|
||||
# 创建新文件并保存整个DataFrame
|
||||
trader_df.to_csv(csv_file_path, index=False)
|
||||
|
||||
# 更新跟踪止损价格
|
||||
if self.long_trailing_stop_price > 0 and self.pos > 0:
|
||||
# print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = (
|
||||
trader_df["low"].iloc[-1]
|
||||
if self.long_trailing_stop_price < trader_df["low"].iloc[-1]
|
||||
else self.long_trailing_stop_price
|
||||
)
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price > 0 and self.pos < 0:
|
||||
# print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = (
|
||||
trader_df["high"].iloc[-1]
|
||||
if trader_df["high"].iloc[-1] < self.short_trailing_stop_price
|
||||
else self.short_trailing_stop_price
|
||||
)
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
self.out_long = self.long_trailing_stop_price * (
|
||||
1 - self.trailing_stop_percent
|
||||
)
|
||||
self.out_short = self.short_trailing_stop_price * (
|
||||
1 + self.trailing_stop_percent
|
||||
)
|
||||
# print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
# print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long > 0:
|
||||
if (
|
||||
trader_df["low"].iloc[-1] < self.out_long
|
||||
and self.pos > 0
|
||||
and self.sl_long_price > 0
|
||||
and trader_df["low"].iloc[-1] > self.sl_long_price
|
||||
):
|
||||
print(
|
||||
"datetime+sig: ",
|
||||
trader_df["datetime"].iloc[-1],
|
||||
"多头止盈",
|
||||
"TR",
|
||||
self.out_long,
|
||||
"low",
|
||||
trader_df["low"].iloc[-1],
|
||||
)
|
||||
# 平多
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["BidPrice1"] - self.py,
|
||||
self.Lots,
|
||||
b"1",
|
||||
b"1",
|
||||
)
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["BidPrice1"] - self.py,
|
||||
self.Lots,
|
||||
b"1",
|
||||
b"3",
|
||||
)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.out_long = 0
|
||||
self.sl_long_price = 0
|
||||
self.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
if self.out_short > 0:
|
||||
if (
|
||||
trader_df["high"].iloc[-1] > self.out_short
|
||||
and self.pos < 0
|
||||
and self.sl_shor_price > 0
|
||||
and trader_df["high"].iloc[-1] < self.sl_shor_price
|
||||
):
|
||||
print(
|
||||
"datetime+sig: ",
|
||||
trader_df["datetime"].iloc[-1],
|
||||
"空头止盈: ",
|
||||
"TR",
|
||||
self.out_short,
|
||||
"high",
|
||||
trader_df["high"].iloc[-1],
|
||||
)
|
||||
# 平空
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["AskPrice1"] + self.py,
|
||||
self.Lots,
|
||||
b"0",
|
||||
b"1",
|
||||
)
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["AskPrice1"] + self.py,
|
||||
self.Lots,
|
||||
b"0",
|
||||
b"3",
|
||||
)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_shor = 0
|
||||
self.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (
|
||||
1 - self.fixed_stop_loss_percent
|
||||
)
|
||||
if (
|
||||
self.sl_long_price > 0
|
||||
and self.fixed_stop_loss_L > 0
|
||||
and self.pos > 0
|
||||
and trader_df["close"].iloc[-1] < self.fixed_stop_loss_L
|
||||
):
|
||||
print(
|
||||
"datetime+sig: ",
|
||||
trader_df["datetime"].iloc[-1],
|
||||
"多头止损",
|
||||
"SL",
|
||||
self.fixed_stop_loss_L,
|
||||
"close",
|
||||
trader_df["close"].iloc[-1],
|
||||
)
|
||||
# 平多
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["BidPrice1"] - self.py,
|
||||
self.Lots,
|
||||
b"1",
|
||||
b"1",
|
||||
)
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["BidPrice1"] - self.py,
|
||||
self.Lots,
|
||||
b"1",
|
||||
b"3",
|
||||
)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (
|
||||
1 + self.fixed_stop_loss_percent
|
||||
)
|
||||
if (
|
||||
self.sl_shor_price > 0
|
||||
and self.fixed_stop_loss_S > 0
|
||||
and self.pos < 0
|
||||
and trader_df["close"].iloc[-1] > self.fixed_stop_loss_S
|
||||
):
|
||||
print(
|
||||
"datetime+sig: ",
|
||||
trader_df["datetime"].iloc[-1],
|
||||
"空头止损",
|
||||
"SL",
|
||||
self.fixed_stop_loss_S,
|
||||
"close",
|
||||
trader_df["close"].iloc[-1],
|
||||
)
|
||||
# 平空
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["AskPrice1"] + self.py,
|
||||
self.Lots,
|
||||
b"0",
|
||||
b"1",
|
||||
)
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["AskPrice1"] + self.py,
|
||||
self.Lots,
|
||||
b"0",
|
||||
b"3",
|
||||
)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price = 0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 日均线
|
||||
trader_df["dayma"] = trader_df["close"].mean()
|
||||
|
||||
# 计算累积的delta值
|
||||
trader_df["delta"] = trader_df["delta"].astype(float)
|
||||
trader_df["delta累计"] = trader_df["delta"].cumsum()
|
||||
|
||||
# 大于日均线
|
||||
开多1 = (
|
||||
trader_df["dayma"].iloc[-1] > 0
|
||||
and trader_df["close"].iloc[-1] > trader_df["dayma"].iloc[-1]
|
||||
)
|
||||
|
||||
# 累计多空净量大于X
|
||||
开多4 = (
|
||||
trader_df["delta累计"].iloc[-1] > 2000
|
||||
and trader_df["delta"].iloc[-1] > 1500
|
||||
)
|
||||
|
||||
# 小于日均线
|
||||
开空1 = (
|
||||
trader_df["dayma"].iloc[-1] > 0
|
||||
and trader_df["close"].iloc[-1] < trader_df["dayma"].iloc[-1]
|
||||
)
|
||||
|
||||
# 累计多空净量小于X
|
||||
开空4 = (
|
||||
trader_df["delta累计"].iloc[-1] < -2000
|
||||
and trader_df["delta"].iloc[-1] < -1500
|
||||
)
|
||||
|
||||
开多组合 = 开多1 and 开多4 and trader_df["dj"].iloc[-1] > self.dj_X
|
||||
开空条件 = 开空1 and 开空4 and trader_df["dj"].iloc[-1] < -self.dj_X
|
||||
|
||||
平多条件 = trader_df["dj"].iloc[-1] < -self.dj_X
|
||||
平空条件 = trader_df["dj"].iloc[-1] > self.dj_X
|
||||
# 开仓
|
||||
# 多头开仓条件
|
||||
if self.pos < 0 and 平空条件:
|
||||
print(
|
||||
"平空: ",
|
||||
"ExchangeID: ",
|
||||
data["ExchangeID"],
|
||||
"InstrumentID",
|
||||
data["InstrumentID"],
|
||||
"AskPrice1",
|
||||
data["AskPrice1"] + self.py,
|
||||
)
|
||||
# 平空
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["AskPrice1"] + self.py,
|
||||
self.Lots,
|
||||
b"0",
|
||||
b"1",
|
||||
)
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["AskPrice1"] + self.py,
|
||||
self.Lots,
|
||||
b"0",
|
||||
b"3",
|
||||
)
|
||||
self.pos = 0
|
||||
self.sl_shor_price = 0
|
||||
self.short_trailing_stop_price = 0
|
||||
print(
|
||||
"datetime+sig: ",
|
||||
trader_df["datetime"].iloc[-1],
|
||||
"反手平空:",
|
||||
"平仓价格:",
|
||||
data["AskPrice1"] + self.py,
|
||||
"堆积数:",
|
||||
trader_df["dj"].iloc[-1],
|
||||
)
|
||||
self.save_to_csv(instrument_id)
|
||||
if self.pos == 0 and 开多组合:
|
||||
print(
|
||||
"开多: ",
|
||||
"ExchangeID: ",
|
||||
data["ExchangeID"],
|
||||
"InstrumentID",
|
||||
data["InstrumentID"],
|
||||
"AskPrice1",
|
||||
data["AskPrice1"] + self.py,
|
||||
)
|
||||
# 开多
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["AskPrice1"] + self.py,
|
||||
self.Lots,
|
||||
b"0",
|
||||
b"0",
|
||||
)
|
||||
print(
|
||||
"datetime+sig: ",
|
||||
trader_df["datetime"].iloc[-1],
|
||||
"多头开仓",
|
||||
"开仓价格:",
|
||||
data["AskPrice1"] + self.py,
|
||||
"堆积数:",
|
||||
trader_df["dj"].iloc[-1],
|
||||
)
|
||||
self.pos = 1
|
||||
self.long_trailing_stop_price = data["AskPrice1"]
|
||||
self.sl_long_price = data["AskPrice1"]
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
if self.pos > 0 and 平多条件:
|
||||
print(
|
||||
"平多: ",
|
||||
"ExchangeID: ",
|
||||
data["ExchangeID"],
|
||||
"InstrumentID",
|
||||
data["InstrumentID"],
|
||||
"BidPrice1",
|
||||
data["BidPrice1"] - self.py,
|
||||
)
|
||||
# 平多
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["BidPrice1"] - self.py,
|
||||
self.Lots,
|
||||
b"1",
|
||||
b"1",
|
||||
)
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["BidPrice1"] - self.py,
|
||||
self.Lots,
|
||||
b"1",
|
||||
b"3",
|
||||
)
|
||||
self.pos = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price = 0
|
||||
print(
|
||||
"datetime+sig: ",
|
||||
trader_df["datetime"].iloc[-1],
|
||||
"反手平多",
|
||||
"平仓价格:",
|
||||
data["BidPrice1"] - self.py,
|
||||
"堆积数:",
|
||||
trader_df["dj"].iloc[-1],
|
||||
)
|
||||
self.save_to_csv(instrument_id)
|
||||
if self.pos == 0 and 开空条件:
|
||||
print(
|
||||
"开空: ",
|
||||
"ExchangeID: ",
|
||||
data["ExchangeID"],
|
||||
"InstrumentID",
|
||||
data["InstrumentID"],
|
||||
"BidPrice1",
|
||||
data["BidPrice1"],
|
||||
)
|
||||
# 开空
|
||||
self.insert_order(
|
||||
data["ExchangeID"],
|
||||
data["InstrumentID"],
|
||||
data["BidPrice1"] - self.py,
|
||||
self.Lots,
|
||||
b"1",
|
||||
b"0",
|
||||
)
|
||||
print(
|
||||
"datetime+sig: ",
|
||||
trader_df["datetime"].iloc[-1],
|
||||
"空头开仓",
|
||||
"开仓价格:",
|
||||
data["BidPrice1"] - self.py,
|
||||
"堆积数:",
|
||||
trader_df["dj"].iloc[-1],
|
||||
)
|
||||
self.pos = -1
|
||||
self.short_trailing_stop_price = data["BidPrice1"]
|
||||
self.sl_shor_price = data["BidPrice1"]
|
||||
self.save_to_csv(instrument_id)
|
||||
# print(trader_df)
|
||||
self.cont_df = len(trader_df)
|
||||
@@ -0,0 +1,279 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
|
||||
# from datetime import datetime
|
||||
import gzip
|
||||
import numpy as np
|
||||
import os
|
||||
import io
|
||||
from 专享08策略 import 专享08of # 导入您的 MyTrader 类
|
||||
|
||||
|
||||
class BacktestEngine:
|
||||
def __init__(self, trader_class, initial_capital=1000000):
|
||||
self.trader = trader_class()
|
||||
self.initial_capital = initial_capital
|
||||
self.equity_curve = []
|
||||
self.positions = {} # {instrument_id: {'long': {'today': 0, 'yesterday': 0}, 'short': {'today': 0, 'yesterday': 0}}}
|
||||
self.cash = initial_capital
|
||||
self.current_date = None
|
||||
|
||||
def run(self, data, start=0, end=None, start_date=None, end_date=None):
|
||||
for i, (_, row) in enumerate(data.iloc[start:end].iterrows()):
|
||||
tick = row.to_dict()
|
||||
|
||||
action_day = pd.to_datetime(tick["ActionDay"]).strftime("%Y-%m-%d")
|
||||
update_time = pd.to_datetime(tick["UpdateTime"]).strftime("%H:%M:%S")
|
||||
created_at = f"{action_day} {update_time}.{tick['UpdateMillisec']:03d}"
|
||||
|
||||
current_date = pd.to_datetime(created_at)
|
||||
|
||||
if start_date is not None and current_date < start_date:
|
||||
continue
|
||||
if end_date is not None and current_date > end_date:
|
||||
break
|
||||
|
||||
tick_date = pd.to_datetime(created_at).date()
|
||||
if self.current_date is None or tick_date != self.current_date:
|
||||
self.update_positions_day()
|
||||
self.current_date = tick_date
|
||||
|
||||
self.trader.Join(tickdata=tick)
|
||||
self.update_account(created_at, tick["LastPrice"], tick["InstrumentID"])
|
||||
|
||||
def update_positions_day(self):
|
||||
for position in self.positions.values():
|
||||
position["long"]["yesterday"] += position["long"]["today"]
|
||||
position["long"]["today"] = 0
|
||||
position["short"]["yesterday"] += position["short"]["today"]
|
||||
position["short"]["today"] = 0
|
||||
|
||||
def update_account(self, datetime, last_price, instrument_id):
|
||||
position_value = 0
|
||||
for inst, pos in self.positions.items():
|
||||
price = (
|
||||
last_price
|
||||
if inst == instrument_id
|
||||
else self.positions[inst]["last_price"]
|
||||
)
|
||||
long_value = (pos["long"]["today"] + pos["long"]["yesterday"]) * price
|
||||
short_value = (pos["short"]["today"] + pos["short"]["yesterday"]) * price
|
||||
position_value += long_value - short_value
|
||||
current_equity = self.cash + position_value
|
||||
self.equity_curve.append((datetime, current_equity))
|
||||
|
||||
def mock_insert_order(
|
||||
self, exchange_id, instrument_id, price, volume, direction, offset
|
||||
):
|
||||
is_buy = direction == b"0"
|
||||
is_open = offset == b"0"
|
||||
is_close_today = offset == b"3"
|
||||
|
||||
if instrument_id not in self.positions:
|
||||
self.positions[instrument_id] = {
|
||||
"long": {"today": 0, "yesterday": 0},
|
||||
"short": {"today": 0, "yesterday": 0},
|
||||
"last_price": price,
|
||||
}
|
||||
|
||||
position = self.positions[instrument_id]
|
||||
|
||||
if is_open:
|
||||
if is_buy:
|
||||
position["long"]["today"] += volume
|
||||
self.cash -= price * volume
|
||||
else:
|
||||
position["short"]["today"] += volume
|
||||
self.cash += price * volume
|
||||
else: # close
|
||||
if is_buy: # buy to close short
|
||||
if is_close_today:
|
||||
position["short"]["today"] -= volume
|
||||
else:
|
||||
if position["short"]["yesterday"] >= volume:
|
||||
position["short"]["yesterday"] -= volume
|
||||
else:
|
||||
remaining = volume - position["short"]["yesterday"]
|
||||
position["short"]["yesterday"] = 0
|
||||
position["short"]["today"] -= remaining
|
||||
self.cash -= price * volume
|
||||
else: # sell to close long
|
||||
if is_close_today:
|
||||
position["long"]["today"] -= volume
|
||||
else:
|
||||
if position["long"]["yesterday"] >= volume:
|
||||
position["long"]["yesterday"] -= volume
|
||||
else:
|
||||
remaining = volume - position["long"]["yesterday"]
|
||||
position["long"]["yesterday"] = 0
|
||||
position["long"]["today"] -= remaining
|
||||
self.cash += price * volume
|
||||
|
||||
position["last_price"] = price
|
||||
|
||||
def calculate_performance(self):
|
||||
df = pd.DataFrame(self.equity_curve, columns=["time", "equity"])
|
||||
df["time"] = pd.to_datetime(df["time"])
|
||||
df.set_index("time", inplace=True)
|
||||
|
||||
if len(df) < 2:
|
||||
print("警告:回测数据点不足,无法计算性能指标。")
|
||||
return {
|
||||
"total_return": 0,
|
||||
"sharpe_ratio": 0,
|
||||
"max_drawdown": 0,
|
||||
"equity_curve": df,
|
||||
}
|
||||
|
||||
df["returns"] = df["equity"].pct_change()
|
||||
|
||||
total_return = (df["equity"].iloc[-1] - df["equity"].iloc[0]) / df[
|
||||
"equity"
|
||||
].iloc[0]
|
||||
sharpe_ratio = np.sqrt(len(df)) * df["returns"].mean() / df["returns"].std()
|
||||
|
||||
drawdown = df["equity"] / df["equity"].cummax() - 1
|
||||
max_drawdown = drawdown.min()
|
||||
|
||||
return {
|
||||
"total_return": total_return,
|
||||
"sharpe_ratio": sharpe_ratio,
|
||||
"max_drawdown": max_drawdown,
|
||||
"equity_curve": df,
|
||||
}
|
||||
|
||||
def plot_performance(self):
|
||||
performance = self.calculate_performance()
|
||||
equity_curve = performance["equity_curve"]
|
||||
|
||||
plt.figure(figsize=(12, 8))
|
||||
plt.plot(equity_curve.index, equity_curve["equity"])
|
||||
plt.title("Equity Curve")
|
||||
plt.xlabel("Time")
|
||||
plt.ylabel("Equity")
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
|
||||
print(f"Total Return: {performance['total_return']:.6%}")
|
||||
print(f"Sharpe Ratio: {performance['sharpe_ratio']:.6f}")
|
||||
print(f"Max Drawdown: {performance['max_drawdown']:.6%}")
|
||||
|
||||
|
||||
# 定义中文表头到英文表头的映射
|
||||
header_mapping = {
|
||||
"交易日": "TradingDay",
|
||||
"合约代码": "InstrumentID",
|
||||
"交易所代码": "ExchangeID",
|
||||
"合约在交易所的代码": "ExchangeInstID",
|
||||
"最新价": "LastPrice",
|
||||
"上次结算价": "PreSettlementPrice",
|
||||
"昨收盘": "PreClosePrice",
|
||||
"昨持仓量": "PreOpenInterest",
|
||||
"今开盘": "OpenPrice",
|
||||
"最高价": "HighestPrice",
|
||||
"最低价": "LowestPrice",
|
||||
"数量": "Volume",
|
||||
"成交金额": "Turnover",
|
||||
"持仓量": "OpenInterest",
|
||||
"今收盘": "ClosePrice",
|
||||
"本次结算价": "SettlementPrice",
|
||||
"涨停板价": "UpperLimitPrice",
|
||||
"跌停板价": "LowerLimitPrice",
|
||||
"昨虚实度": "PreDelta",
|
||||
"今虚实度": "CurrDelta",
|
||||
"最后修改时间": "UpdateTime",
|
||||
"最后修改毫秒": "UpdateMillisec",
|
||||
"申买价一": "BidPrice1",
|
||||
"申买量一": "BidVolume1",
|
||||
"申卖价一": "AskPrice1",
|
||||
"申卖量一": "AskVolume1",
|
||||
"申买价二": "BidPrice2",
|
||||
"申买量二": "BidVolume2",
|
||||
"申卖价二": "AskPrice2",
|
||||
"申卖量二": "AskVolume2",
|
||||
"申买价三": "BidPrice3",
|
||||
"申买量三": "BidVolume3",
|
||||
"申卖价三": "AskPrice3",
|
||||
"申卖量三": "AskVolume3",
|
||||
"申买价四": "BidPrice4",
|
||||
"申买量四": "BidVolume4",
|
||||
"申卖价四": "AskPrice4",
|
||||
"申卖量四": "AskVolume4",
|
||||
"申买价五": "BidPrice5",
|
||||
"申买量五": "BidVolume5",
|
||||
"申卖价五": "AskPrice5",
|
||||
"申卖量五": "AskVolume5",
|
||||
"当日均价": "AveragePrice",
|
||||
"业务日期": "ActionDay",
|
||||
}
|
||||
|
||||
|
||||
def load_and_process_data(folder_path):
|
||||
dfs = []
|
||||
for filename in os.listdir(folder_path):
|
||||
file_path = os.path.join(folder_path, filename)
|
||||
|
||||
try:
|
||||
if filename.endswith(".gz"):
|
||||
# 处理 GZ 文件
|
||||
with gzip.open(file_path, "rt", encoding="gbk") as gz_file:
|
||||
csv_data = io.StringIO(gz_file.read())
|
||||
df = pd.read_csv(csv_data, parse_dates=["业务日期", "最后修改时间"])
|
||||
elif filename.endswith(".csv"):
|
||||
# 处理 CSV 文件
|
||||
df = pd.read_csv(
|
||||
file_path,
|
||||
encoding="utf-8",
|
||||
parse_dates=["业务日期", "最后修改时间"],
|
||||
)
|
||||
else:
|
||||
# 跳过非 GZ 和非 CSV 文件
|
||||
print(f"Skipping {filename}: not a GZ or CSV file")
|
||||
continue
|
||||
|
||||
# 重命名列
|
||||
df.rename(columns=header_mapping, inplace=True)
|
||||
|
||||
dfs.append(df)
|
||||
print(f"Successfully read {filename}")
|
||||
except Exception as e:
|
||||
print(f"Error reading {filename}: {str(e)}")
|
||||
print("Skipping this file.")
|
||||
continue
|
||||
|
||||
if dfs:
|
||||
data = pd.concat(dfs, ignore_index=True)
|
||||
data.sort_values(["ActionDay", "UpdateTime", "UpdateMillisec"], inplace=True)
|
||||
data = data.reset_index(drop=True) # 重置索引
|
||||
return data
|
||||
else:
|
||||
print("没有找到可读取的GZ或CSV文件")
|
||||
return None
|
||||
|
||||
|
||||
# 使用示例
|
||||
if __name__ == "__main__":
|
||||
# 使用示例
|
||||
folder_path = "./回测数据" # 替换为您的数据文件夹路径
|
||||
# 读取,排序,合并tick数据
|
||||
data = load_and_process_data(folder_path)
|
||||
print(data)
|
||||
if data is not None:
|
||||
# 初始化回测引擎,设置策略和初始资金
|
||||
backtest = BacktestEngine(专享08of, initial_capital=10000)
|
||||
|
||||
# 替换MyTrader中的insert_order方法
|
||||
backtest.trader.insert_order = backtest.mock_insert_order
|
||||
|
||||
# # 运行回测
|
||||
# backtest.run(data)
|
||||
|
||||
backtest.run(
|
||||
data,
|
||||
# start=1000,
|
||||
# end=3000,
|
||||
# start_date=pd.to_datetime('2023-01-01'),
|
||||
# end_date=pd.to_datetime('2023-01-31')
|
||||
)
|
||||
# 显示回测结果
|
||||
backtest.plot_performance()
|
||||
@@ -0,0 +1,279 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
|
||||
# from datetime import datetime
|
||||
import gzip
|
||||
import numpy as np
|
||||
import os
|
||||
import io
|
||||
from 专享08策略 import 专享08of # 导入您的 MyTrader 类
|
||||
|
||||
|
||||
class BacktestEngine:
|
||||
def __init__(self, trader_class, initial_capital=1000000):
|
||||
self.trader = trader_class()
|
||||
self.initial_capital = initial_capital
|
||||
self.equity_curve = []
|
||||
self.positions = {} # {instrument_id: {'long': {'today': 0, 'yesterday': 0}, 'short': {'today': 0, 'yesterday': 0}}}
|
||||
self.cash = initial_capital
|
||||
self.current_date = None
|
||||
|
||||
def run(self, data, start=0, end=None, start_date=None, end_date=None):
|
||||
for i, (_, row) in enumerate(data.iloc[start:end].iterrows()):
|
||||
tick = row.to_dict()
|
||||
|
||||
action_day = pd.to_datetime(tick["ActionDay"]).strftime("%Y-%m-%d")
|
||||
update_time = pd.to_datetime(tick["UpdateTime"]).strftime("%H:%M:%S")
|
||||
created_at = f"{action_day} {update_time}.{tick['UpdateMillisec']:03d}"
|
||||
|
||||
current_date = pd.to_datetime(created_at)
|
||||
|
||||
if start_date is not None and current_date < start_date:
|
||||
continue
|
||||
if end_date is not None and current_date > end_date:
|
||||
break
|
||||
|
||||
tick_date = pd.to_datetime(created_at).date()
|
||||
if self.current_date is None or tick_date != self.current_date:
|
||||
self.update_positions_day()
|
||||
self.current_date = tick_date
|
||||
|
||||
self.trader.Join(tickdata=tick)
|
||||
self.update_account(created_at, tick["LastPrice"], tick["InstrumentID"])
|
||||
|
||||
def update_positions_day(self):
|
||||
for position in self.positions.values():
|
||||
position["long"]["yesterday"] += position["long"]["today"]
|
||||
position["long"]["today"] = 0
|
||||
position["short"]["yesterday"] += position["short"]["today"]
|
||||
position["short"]["today"] = 0
|
||||
|
||||
def update_account(self, datetime, last_price, instrument_id):
|
||||
position_value = 0
|
||||
for inst, pos in self.positions.items():
|
||||
price = (
|
||||
last_price
|
||||
if inst == instrument_id
|
||||
else self.positions[inst]["last_price"]
|
||||
)
|
||||
long_value = (pos["long"]["today"] + pos["long"]["yesterday"]) * price
|
||||
short_value = (pos["short"]["today"] + pos["short"]["yesterday"]) * price
|
||||
position_value += long_value - short_value
|
||||
current_equity = self.cash + position_value
|
||||
self.equity_curve.append((datetime, current_equity))
|
||||
|
||||
def mock_insert_order(
|
||||
self, exchange_id, instrument_id, price, volume, direction, offset
|
||||
):
|
||||
is_buy = direction == b"0"
|
||||
is_open = offset == b"0"
|
||||
is_close_today = offset == b"3"
|
||||
|
||||
if instrument_id not in self.positions:
|
||||
self.positions[instrument_id] = {
|
||||
"long": {"today": 0, "yesterday": 0},
|
||||
"short": {"today": 0, "yesterday": 0},
|
||||
"last_price": price,
|
||||
}
|
||||
|
||||
position = self.positions[instrument_id]
|
||||
|
||||
if is_open:
|
||||
if is_buy:
|
||||
position["long"]["today"] += volume
|
||||
self.cash -= price * volume
|
||||
else:
|
||||
position["short"]["today"] += volume
|
||||
self.cash += price * volume
|
||||
else: # close
|
||||
if is_buy: # buy to close short
|
||||
if is_close_today:
|
||||
position["short"]["today"] -= volume
|
||||
else:
|
||||
if position["short"]["yesterday"] >= volume:
|
||||
position["short"]["yesterday"] -= volume
|
||||
else:
|
||||
remaining = volume - position["short"]["yesterday"]
|
||||
position["short"]["yesterday"] = 0
|
||||
position["short"]["today"] -= remaining
|
||||
self.cash -= price * volume
|
||||
else: # sell to close long
|
||||
if is_close_today:
|
||||
position["long"]["today"] -= volume
|
||||
else:
|
||||
if position["long"]["yesterday"] >= volume:
|
||||
position["long"]["yesterday"] -= volume
|
||||
else:
|
||||
remaining = volume - position["long"]["yesterday"]
|
||||
position["long"]["yesterday"] = 0
|
||||
position["long"]["today"] -= remaining
|
||||
self.cash += price * volume
|
||||
|
||||
position["last_price"] = price
|
||||
|
||||
def calculate_performance(self):
|
||||
df = pd.DataFrame(self.equity_curve, columns=["time", "equity"])
|
||||
df["time"] = pd.to_datetime(df["time"])
|
||||
df.set_index("time", inplace=True)
|
||||
|
||||
if len(df) < 2:
|
||||
print("警告:回测数据点不足,无法计算性能指标。")
|
||||
return {
|
||||
"total_return": 0,
|
||||
"sharpe_ratio": 0,
|
||||
"max_drawdown": 0,
|
||||
"equity_curve": df,
|
||||
}
|
||||
|
||||
df["returns"] = df["equity"].pct_change()
|
||||
|
||||
total_return = (df["equity"].iloc[-1] - df["equity"].iloc[0]) / df[
|
||||
"equity"
|
||||
].iloc[0]
|
||||
sharpe_ratio = np.sqrt(len(df)) * df["returns"].mean() / df["returns"].std()
|
||||
|
||||
drawdown = df["equity"] / df["equity"].cummax() - 1
|
||||
max_drawdown = drawdown.min()
|
||||
|
||||
return {
|
||||
"total_return": total_return,
|
||||
"sharpe_ratio": sharpe_ratio,
|
||||
"max_drawdown": max_drawdown,
|
||||
"equity_curve": df,
|
||||
}
|
||||
|
||||
def plot_performance(self):
|
||||
performance = self.calculate_performance()
|
||||
equity_curve = performance["equity_curve"]
|
||||
|
||||
plt.figure(figsize=(12, 8))
|
||||
plt.plot(equity_curve.index, equity_curve["equity"])
|
||||
plt.title("Equity Curve")
|
||||
plt.xlabel("Time")
|
||||
plt.ylabel("Equity")
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
|
||||
print(f"Total Return: {performance['total_return']:.6%}")
|
||||
print(f"Sharpe Ratio: {performance['sharpe_ratio']:.6f}")
|
||||
print(f"Max Drawdown: {performance['max_drawdown']:.6%}")
|
||||
|
||||
|
||||
# 定义中文表头到英文表头的映射
|
||||
header_mapping = {
|
||||
"交易日": "TradingDay",
|
||||
"合约代码": "InstrumentID",
|
||||
"交易所代码": "ExchangeID",
|
||||
"合约在交易所的代码": "ExchangeInstID",
|
||||
"最新价": "LastPrice",
|
||||
"上次结算价": "PreSettlementPrice",
|
||||
"昨收盘": "PreClosePrice",
|
||||
"昨持仓量": "PreOpenInterest",
|
||||
"今开盘": "OpenPrice",
|
||||
"最高价": "HighestPrice",
|
||||
"最低价": "LowestPrice",
|
||||
"数量": "Volume",
|
||||
"成交金额": "Turnover",
|
||||
"持仓量": "OpenInterest",
|
||||
"今收盘": "ClosePrice",
|
||||
"本次结算价": "SettlementPrice",
|
||||
"涨停板价": "UpperLimitPrice",
|
||||
"跌停板价": "LowerLimitPrice",
|
||||
"昨虚实度": "PreDelta",
|
||||
"今虚实度": "CurrDelta",
|
||||
"最后修改时间": "UpdateTime",
|
||||
"最后修改毫秒": "UpdateMillisec",
|
||||
"申买价一": "BidPrice1",
|
||||
"申买量一": "BidVolume1",
|
||||
"申卖价一": "AskPrice1",
|
||||
"申卖量一": "AskVolume1",
|
||||
"申买价二": "BidPrice2",
|
||||
"申买量二": "BidVolume2",
|
||||
"申卖价二": "AskPrice2",
|
||||
"申卖量二": "AskVolume2",
|
||||
"申买价三": "BidPrice3",
|
||||
"申买量三": "BidVolume3",
|
||||
"申卖价三": "AskPrice3",
|
||||
"申卖量三": "AskVolume3",
|
||||
"申买价四": "BidPrice4",
|
||||
"申买量四": "BidVolume4",
|
||||
"申卖价四": "AskPrice4",
|
||||
"申卖量四": "AskVolume4",
|
||||
"申买价五": "BidPrice5",
|
||||
"申买量五": "BidVolume5",
|
||||
"申卖价五": "AskPrice5",
|
||||
"申卖量五": "AskVolume5",
|
||||
"当日均价": "AveragePrice",
|
||||
"业务日期": "ActionDay",
|
||||
}
|
||||
|
||||
|
||||
def load_and_process_data(folder_path):
|
||||
dfs = []
|
||||
for filename in os.listdir(folder_path):
|
||||
file_path = os.path.join(folder_path, filename)
|
||||
|
||||
try:
|
||||
if filename.endswith(".gz"):
|
||||
# 处理 GZ 文件
|
||||
with gzip.open(file_path, "rt", encoding="gbk") as gz_file:
|
||||
csv_data = io.StringIO(gz_file.read())
|
||||
df = pd.read_csv(csv_data, parse_dates=["业务日期", "最后修改时间"])
|
||||
elif filename.endswith(".csv"):
|
||||
# 处理 CSV 文件
|
||||
df = pd.read_csv(
|
||||
file_path,
|
||||
encoding="utf-8",
|
||||
parse_dates=["业务日期", "最后修改时间"],
|
||||
)
|
||||
else:
|
||||
# 跳过非 GZ 和非 CSV 文件
|
||||
print(f"Skipping {filename}: not a GZ or CSV file")
|
||||
continue
|
||||
|
||||
# 重命名列
|
||||
df.rename(columns=header_mapping, inplace=True)
|
||||
|
||||
dfs.append(df)
|
||||
print(f"Successfully read {filename}")
|
||||
except Exception as e:
|
||||
print(f"Error reading {filename}: {str(e)}")
|
||||
print("Skipping this file.")
|
||||
continue
|
||||
|
||||
if dfs:
|
||||
data = pd.concat(dfs, ignore_index=True)
|
||||
data.sort_values(["ActionDay", "UpdateTime", "UpdateMillisec"], inplace=True)
|
||||
data = data.reset_index(drop=True) # 重置索引
|
||||
return data
|
||||
else:
|
||||
print("没有找到可读取的GZ或CSV文件")
|
||||
return None
|
||||
|
||||
|
||||
# 使用示例
|
||||
if __name__ == "__main__":
|
||||
# 使用示例
|
||||
folder_path = "./回测数据" # 替换为您的数据文件夹路径
|
||||
# 读取,排序,合并tick数据
|
||||
data = load_and_process_data(folder_path)
|
||||
print(data)
|
||||
if data is not None:
|
||||
# 初始化回测引擎,设置策略和初始资金
|
||||
backtest = BacktestEngine(专享08of, initial_capital=10000)
|
||||
|
||||
# 替换MyTrader中的insert_order方法
|
||||
backtest.trader.insert_order = backtest.mock_insert_order
|
||||
|
||||
# # 运行回测
|
||||
# backtest.run(data)
|
||||
|
||||
backtest.run(
|
||||
data,
|
||||
# start=1000,
|
||||
# end=3000,
|
||||
# start_date=pd.to_datetime('2023-01-01'),
|
||||
# end_date=pd.to_datetime('2023-01-31')
|
||||
)
|
||||
# 显示回测结果
|
||||
backtest.plot_performance()
|
||||
@@ -0,0 +1,95 @@
|
||||
import os
|
||||
from chardet.universaldetector import UniversalDetector
|
||||
import chardet
|
||||
|
||||
|
||||
def get_filelist(path):
|
||||
"""
|
||||
获取路径下所有csv文件的路径列表
|
||||
"""
|
||||
Filelist = []
|
||||
for home, dirs, files in os.walk(path):
|
||||
for filename in files:
|
||||
if ".csv" in filename:
|
||||
Filelist.append(os.path.join(home, filename))
|
||||
return Filelist
|
||||
|
||||
|
||||
def read_file(file):
|
||||
"""
|
||||
逐个读取文件的内容
|
||||
"""
|
||||
with open(file, 'rb') as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def get_encode_info(file):
|
||||
"""
|
||||
逐个读取文件的编码方式
|
||||
"""
|
||||
with open(file, 'rb') as f:
|
||||
# data = f.read()
|
||||
# detected_encoding = chardet.detect(data)['encoding']
|
||||
detector = UniversalDetector()
|
||||
for line in f.readlines():
|
||||
detector.feed(line)
|
||||
if detector.done:
|
||||
break
|
||||
detector.close()
|
||||
# return detected_encoding
|
||||
return detector.result['encoding']
|
||||
# return detected_encoding
|
||||
|
||||
|
||||
def convert_encode2gbk(file, original_encode, des_encode):
|
||||
"""
|
||||
将文件的编码方式转换为gbk,并写入原先的文件中。
|
||||
"""
|
||||
file_content = read_file(file)
|
||||
file_decode = file_content.decode(original_encode, 'ignore')
|
||||
file_encode = file_decode.encode(des_encode)
|
||||
with open(file, 'wb') as f:
|
||||
f.write(file_encode)
|
||||
|
||||
|
||||
def read_and_convert(path):
|
||||
"""
|
||||
读取文件并转换
|
||||
"""
|
||||
Filelist = get_filelist(path=path)
|
||||
fileNum= 0
|
||||
for filename in Filelist:
|
||||
try:
|
||||
file_content = read_file(filename)
|
||||
print("filename:", filename)
|
||||
encode_info = get_encode_info(filename)
|
||||
print("encode_info", encode_info)
|
||||
if encode_info != 'gbk':
|
||||
fileNum +=1
|
||||
convert_encode2gbk(filename, encode_info, 'gbk')
|
||||
print('成功转换 %s 个文件 %s '%(fileNum,filename))
|
||||
except BaseException:
|
||||
print(filename,'存在问题,请检查!')
|
||||
|
||||
|
||||
def recheck_again(path):
|
||||
"""
|
||||
再次判断文件是否为gbk
|
||||
"""
|
||||
print('---------------------以下文件仍存在问题---------------------')
|
||||
Filelist = get_filelist(path)
|
||||
for filename in Filelist:
|
||||
encode_info_ch = get_encode_info(filename)
|
||||
if encode_info_ch != 'gbk':
|
||||
print(filename,'的编码方式是:',encode_info_ch)
|
||||
|
||||
|
||||
print('--------------------------检查结束--------------------------')
|
||||
# if __name__ == "__main__":
|
||||
# """
|
||||
# 输入文件路径
|
||||
# """
|
||||
# path = r"D:\data"
|
||||
# read_and_convert(path)
|
||||
# recheck_again(path)
|
||||
# print('转换结束!')
|
||||
@@ -0,0 +1,515 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2d85dda4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import pandas as pd\n",
|
||||
"from file_format_conversion import file_format_conversion\n",
|
||||
"from ffc import read_and_convert, recheck_again"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "fe51b707",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_directory = \"D:/data_all/doing\" # \"E:/data/大商所/test\"\n",
|
||||
"os.chdir(new_directory) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d2694b45",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"read_and_convert(new_directory)\n",
|
||||
"recheck_again(new_directory)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f6ba7f98",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 文件格式检查并转换替换\n",
|
||||
"for root, dirs, files in os.walk('.'):\n",
|
||||
" if len(dirs) > 0:\n",
|
||||
" for dir in dirs:\n",
|
||||
" # 获取二级子文件夹中的所有 CSV 文件\n",
|
||||
" all_csv_files = [os.path.join(dir, file) for file in os.listdir(dir) if file.endswith('.csv')]\n",
|
||||
"\n",
|
||||
" sp_old_chars = ['_2019', '_2020', '_2021']\n",
|
||||
" for sp_old_char in sp_old_chars:\n",
|
||||
" csv_old_files = [sp_file for sp_file in all_csv_files if sp_old_char in sp_file]\n",
|
||||
" if len(csv_old_files) > 0:\n",
|
||||
" old_df, old_code_value = file_format_conversion(csv_old_files, sp_old_char)\n",
|
||||
"\n",
|
||||
" # sp_new_chars = ['_2022', '_2023']\n",
|
||||
" # for sp_new_char in sp_new_chars:\n",
|
||||
" # csv_new_files = [sp_file for sp_file in all_csv_files if sp_new_char in sp_file]\n",
|
||||
" # if len(csv_new_files) > 0:\n",
|
||||
" # new_df, new_code_value = file_format_conversion(csv_new_files, sp_new_char)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d9c211c7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import chardet\n",
|
||||
"csv_file = \"D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv\"\n",
|
||||
"with open(csv_file, 'rb') as f:\n",
|
||||
" data = f.read()\n",
|
||||
"\n",
|
||||
"detected_encoding = chardet.detect(data)['encoding']\n",
|
||||
"print(\"当前文件编码格式:\", detected_encoding)\n",
|
||||
"\n",
|
||||
"if detected_encoding and detected_encoding != 'gbk':\n",
|
||||
" print(\"当前文件不为gbk格式:\", csv_file)\n",
|
||||
" print(\"当前文件编码格式:\", detected_encoding)\n",
|
||||
" # convert_csv_to_gbk(csv_file,detected_encoding)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e5cf73aa",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# 读取 ISO-8859-1 编码的 CSV 文件\n",
|
||||
"df = pd.read_csv('D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv', encoding='iso-8859-1', error_bad_lines= False)\n",
|
||||
"\n",
|
||||
"# # 将数据框转换为 GBK 编码\n",
|
||||
"# df = df.to_csv('D:/data_all/doing/bu主力连续/bu主力连续_20190530_bak.csv', index=False, encoding='gbk')\n",
|
||||
"\n",
|
||||
"# # 替换原始 CSV 文件\n",
|
||||
"# os.replace('D:/data_all/doing/bu主力连续/bu主力连续_20190530_bak.csv', 'D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv')\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3d81f4d0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "714d5286",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = df.to_csv('D:/data_all/doing/bu主力连续/bu主力连续_20190530_bak.csv', index=False, encoding='gbk')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3d4ff2c6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"f.close"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ebc8f7ab",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"csv_file = \"D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv\"\n",
|
||||
"csv_df = pd.read_csv(csv_file,encoding=\"ISO-8859-1\")#detected_encoding"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1beee390",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import codecs\n",
|
||||
" \n",
|
||||
"def convert_encoding(input_str, input_encoding='iso-8859-1', output_encoding='gbk'):\n",
|
||||
" return codecs.encode(input_str, output_encoding, input_encoding)\n",
|
||||
" \n",
|
||||
"input_str = csv_df\n",
|
||||
"converted_str = convert_encoding(input_str, 'iso-8859-1', 'gbk')\n",
|
||||
"print(converted_str)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d8d36cfc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import csv\n",
|
||||
"import codecs\n",
|
||||
"from csv import reader\n",
|
||||
"from csv import writer\n",
|
||||
" \n",
|
||||
"# 指定原始文件和目标文件路径\n",
|
||||
"input_file_path = 'D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv'\n",
|
||||
"output_file_path = 'D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv'\n",
|
||||
" \n",
|
||||
"# 打开原始文件和目标文件\n",
|
||||
"with open(input_file_path, 'r', encoding='iso-8859-1') as input_file, \\\n",
|
||||
" codecs.open(output_file_path, 'w', 'gbk') as output_file:\n",
|
||||
" # 创建读取器和写入器\n",
|
||||
" input_reader = reader(input_file)\n",
|
||||
" output_writer = writer(output_file)\n",
|
||||
" \n",
|
||||
" # 读取并写入数据\n",
|
||||
" for row in input_reader:\n",
|
||||
" output_writer.writerow(row)\n",
|
||||
" \n",
|
||||
"print(f'文件编码从ISO-8859-1转换为GBK,已保存为 {output_file_path}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7c814155",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import csv\n",
|
||||
"import codecs\n",
|
||||
"import os\n",
|
||||
" \n",
|
||||
"input_file_name = 'D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv'\n",
|
||||
"output_file_name = 'D:/data_all/doing/bu主力连续/bu主力连续_20190530_bak.csv'\n",
|
||||
" \n",
|
||||
"# 打开原始ISO-8859-1编码的CSV文件\n",
|
||||
"with codecs.open(input_file_name, 'r', 'iso-8859-1') as input_file:\n",
|
||||
" reader = csv.reader(input_file)\n",
|
||||
" # 打开目标GBK编码的CSV文件进行写入\n",
|
||||
" with open(output_file_name, 'w', newline='', encoding='utf-8') as output_file:\n",
|
||||
" writer = csv.writer(output_file)\n",
|
||||
" for row in reader:\n",
|
||||
" writer.writerow(row)\n",
|
||||
" \n",
|
||||
"# 删除原始文件\n",
|
||||
"os.remove(input_file_name)\n",
|
||||
"# 重命名新文件为原始文件名\n",
|
||||
"os.rename(output_file_name, input_file_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "fb75d9a0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.read_csv(\"D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv\",encoding=\"gbk\")\n",
|
||||
"\n",
|
||||
"# df.to_csv(\"D:/data_all/doing/bu主力连续/bu主力连续_20190530_bak.csv\", encoding=\"gbk\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b9687682",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4e300950",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(csv_file)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ddf98c52",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"os.remove(csv_file)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "364add14",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import csv\n",
|
||||
"import codecs\n",
|
||||
" \n",
|
||||
"# # 输入输出文件路径\n",
|
||||
"# input_file_path = 'utf8_file.csv'\n",
|
||||
"# output_file_path = 'gbk_file.csv'\n",
|
||||
" \n",
|
||||
"# 打开UTF-8编码的CSV文件进行读取\n",
|
||||
"with open(csv_file, 'r', encoding= detected_encoding) as input_file:\n",
|
||||
" reader = csv.reader(csv_file)\n",
|
||||
" os.remove(csv_file)\n",
|
||||
" # 使用codecs打开GBK编码的CSV文件进行写入\n",
|
||||
" with codecs.open(csv_file, 'w', encoding='gbk') as output_file:\n",
|
||||
" writer = csv.writer(csv_file)\n",
|
||||
" for row in reader:\n",
|
||||
" writer.writerow(row)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f6f546c6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"csv_df.to_csv(csv_file, index=False, encoding='gbk')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a028b88e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 列错读取错误文件\n",
|
||||
"当前读取文件读取错误: bu主力连续\\bu主力连续_20190530.csv\n",
|
||||
"当前读取文件读取错误: bu主力连续\\bu主力连续_20190701.csv"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "200715a8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"df = pd.read_csv(\n",
|
||||
" \"D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv\", \n",
|
||||
" header=0,\n",
|
||||
" # usecols=[ 1, 2, 3, 7, 12, 13, 14, 15],\n",
|
||||
" # names=[\n",
|
||||
" # \"合约代码\",\n",
|
||||
" # \"时间\",\n",
|
||||
" # \"最新\",\n",
|
||||
" # \"成交量\",\n",
|
||||
" # \"买一价\",\n",
|
||||
" # \"卖一价\",\n",
|
||||
" # \"买一量\",\n",
|
||||
" # \"卖一量\",\n",
|
||||
" # ],\n",
|
||||
" encoding='ISO-8859-1',#ISO-8859-1\n",
|
||||
" # skiprows=0,\n",
|
||||
" # parse_dates=['时间']\n",
|
||||
" )\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a8de54b6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from chardet.universaldetector import UniversalDetector\n",
|
||||
"import chardet\n",
|
||||
"with open(\"D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv\", 'rb') as f:\n",
|
||||
" data = f.read()\n",
|
||||
" detected_encoding = chardet.detect(data)['encoding']\n",
|
||||
"print(detected_encoding)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 45,
|
||||
"id": "d874e66b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd \n",
|
||||
"import chardet \n",
|
||||
"# 读取CSV文件 \n",
|
||||
"df = pd.read_csv('D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv',encoding=\"ISO-8859-1\", error_bad_lines=False, warn_bad_lines=True) \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 46,
|
||||
"id": "55c69d0a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"CSV文件字符编码为: ISO-8859-1\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 检测CSV文件字符编码 \n",
|
||||
"with open('D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv', 'rb') as f: \n",
|
||||
" result = chardet.detect(f.read()) \n",
|
||||
" encoding = result['encoding'] \n",
|
||||
" print('CSV文件字符编码为:', encoding) \n",
|
||||
" # 转换CSV文件编码格式 \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 50,
|
||||
"id": "bee6800a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"CSV文件已转换为GBK编码格式\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"if encoding != 'GBK': \n",
|
||||
" df.to_csv('D:/data_all/doing/bu主力连续/bu主力连续_20190530_gbk.csv', encoding='utf-8', index=False) \n",
|
||||
" print('CSV文件已转换为GBK编码格式') \n",
|
||||
"else: print('CSV文件无需转换')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3c61930c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#'gbk' codec can't decode byte 0xc3 in position 189076: illegal multibyte sequence\n",
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1b22d988",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = df.sort_values(by = ['datetime'], ascending=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cc14352a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['datetime'] = sorted(df['datetime'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2dc49f0c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "befec0c4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import chardet"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6397fffb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 假设file_path是你要读取的文件路径\n",
|
||||
"with open(\"D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv\", 'rb') as file:\n",
|
||||
" data = file.read()\n",
|
||||
" \n",
|
||||
"# 使用chardet检测编码\n",
|
||||
"detected_encoding = chardet.detect(data)['encoding']\n",
|
||||
" \n",
|
||||
"# # 如果检测到的编码不是gbk,可以尝试转换编码后再读取\n",
|
||||
"# if detected_encoding and detected_encoding != 'gbk':\n",
|
||||
"# with open(file_path, 'rb') as file:\n",
|
||||
"# data = file.read().decode(detected_encoding)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c2433c60",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(detected_encoding)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.7.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import pandas as pd
|
||||
import os
|
||||
# from datetime import time as s_time
|
||||
# from datetime import datetime
|
||||
import chardet
|
||||
import csv
|
||||
|
||||
# has_common_keys(commodity_day_dict, commodity_night_dict,financial_time_dict)
|
||||
|
||||
# import chardet
|
||||
|
||||
# # 假设file_path是你要读取的文件路径
|
||||
# with open(file_path, 'rb') as file:
|
||||
# data = file.read()
|
||||
|
||||
# # 使用chardet检测编码
|
||||
# detected_encoding = chardet.detect(data)['encoding']
|
||||
|
||||
# # 如果检测到的编码不是gbk,可以尝试转换编码后再读取
|
||||
# if detected_encoding and detected_encoding != 'gbk':
|
||||
# with open(file_path, 'rb') as file:
|
||||
# data = file.read().decode(detected_encoding)
|
||||
|
||||
|
||||
def file_format_conversion(all_csv_files, sp_char):
|
||||
# 获取当前目录下的所有文件名包含sp_char的csv文件
|
||||
csv_files = [sp_file for sp_file in all_csv_files if sp_char in sp_file]
|
||||
print("csv_files:", csv_files)
|
||||
merged_df = pd.DataFrame()
|
||||
dir = os.getcwd()
|
||||
|
||||
# 循环遍历每个csv文件
|
||||
for csv_file in csv_files:
|
||||
|
||||
# file_path = os.path.join(dir, file)
|
||||
# 读取csv文件,并使用第一行为列标题,编译不通过可以改为gbk
|
||||
with open(csv_file, 'rb') as f:
|
||||
data = f.read()
|
||||
|
||||
detected_encoding = chardet.detect(data)['encoding']
|
||||
|
||||
if detected_encoding and detected_encoding != 'gbk':
|
||||
print("当前文件不为gbk格式:", csv_file)
|
||||
convert_csv_to_gbk(csv_file,detected_encoding)
|
||||
|
||||
# with open(file_path, 'rb') as file:
|
||||
# data = file.read().decode(detected_encoding)
|
||||
|
||||
# 定义一个函数来处理单个CSV文件
|
||||
def convert_csv_to_gbk(csv_file,encoding_type):
|
||||
# 读取CSV文件,以UTF-8格式
|
||||
with open(csv_file, 'r', encoding=encoding_type) as f:
|
||||
reader = csv.reader(f)
|
||||
rows = list(reader)
|
||||
|
||||
# 将读取的内容写入新的CSV文件,以GBK格式
|
||||
with open(csv_file, 'w', newline='', encoding='gbk') as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows(rows)
|
||||
|
||||
# 删除原始CSV文件
|
||||
os.remove(csv_file)
|
||||
# 将转换后的文件重命名为原始文件名
|
||||
new_file = csv_file.replace('.csv', '_gbk.csv')
|
||||
os.rename(new_file, csv_file)
|
||||
print("当前文件已经转换为gbk格式:", csv_file)
|
||||
@@ -0,0 +1,351 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "2d85dda4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"'''\n",
|
||||
"Author: zhoujie2104231 zhoujie@me.com\n",
|
||||
"Date: 2024-04-07 19:26:52\n",
|
||||
"LastEditors: zhoujie2104231 zhoujie@me.com\n",
|
||||
"LastEditTime: 2024-04-07 20:56:21\n",
|
||||
"FilePath: \"/Gitee_Code/trading_strategy/SS_Code\\SF08\\使用文档\\数据转换最终版/merged_by_year.ipynb\"\n",
|
||||
"Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\n",
|
||||
"'''\n",
|
||||
"import os\n",
|
||||
"import pandas as pd\n",
|
||||
"from merged_tickdata import merged_old_tickdata, merged_new_tickdata, all_dict\n",
|
||||
"# from merged_tickdata_tmp import merged_old_tickdata, merged_new_tickdata, all_dict"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "fe51b707",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_directory = \"D:/data_all/doing\" # \"E:/data/大商所/test\"\n",
|
||||
"os.chdir(new_directory) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "3356d8ff",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"csv_files: ['bu主力连续\\\\bu主力连续_20190703.csv', 'bu主力连续\\\\bu主力连续_20190528.csv', 'bu主力连续\\\\bu主力连续_20190529.csv', 'bu主力连续\\\\bu主力连续_20190530.csv', 'bu主力连续\\\\bu主力连续_20190531.csv', 'bu主力连续\\\\bu主力连续_20190603.csv', 'bu主力连续\\\\bu主力连续_20190604.csv', 'bu主力连续\\\\bu主力连续_20190605.csv', 'bu主力连续\\\\bu主力连续_20190606.csv', 'bu主力连续\\\\bu主力连续_20190610.csv', 'bu主力连续\\\\bu主力连续_20190611.csv', 'bu主力连续\\\\bu主力连续_20190612.csv', 'bu主力连续\\\\bu主力连续_20190613.csv', 'bu主力连续\\\\bu主力连续_20190614.csv', 'bu主力连续\\\\bu主力连续_20190617.csv', 'bu主力连续\\\\bu主力连续_20190618.csv', 'bu主力连续\\\\bu主力连续_20190619.csv', 'bu主力连续\\\\bu主力连续_20190620.csv', 'bu主力连续\\\\bu主力连续_20190621.csv', 'bu主力连续\\\\bu主力连续_20190624.csv', 'bu主力连续\\\\bu主力连续_20190625.csv', 'bu主力连续\\\\bu主力连续_20190626.csv', 'bu主力连续\\\\bu主力连续_20190627.csv', 'bu主力连续\\\\bu主力连续_20190628.csv', 'bu主力连续\\\\bu主力连续_20190701.csv', 'bu主力连续\\\\bu主力连续_20190702.csv']\n",
|
||||
"当前读取文件读取错误: <_io.BufferedReader name='D:\\\\data_all\\\\doing\\\\bu主力连续\\\\bu主力连续_20190530.csv'>\n",
|
||||
"当前读取文件正确解码格式 ISO-8859-1\n",
|
||||
"当前读取文件读取错误: <_io.BufferedReader name='D:\\\\data_all\\\\doing\\\\bu主力连续\\\\bu主力连续_20190701.csv'>\n",
|
||||
"当前读取文件正确解码格式 ISO-8859-1\n",
|
||||
"code_value characters: bu888\n",
|
||||
"按照夜盘截止交易时间为23:00筛选商品期货品种\n",
|
||||
"bu888_2019数据生成成功!\n",
|
||||
"bu888_2019.CSV文件合并成功!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for root, dirs, files in os.walk('.'):\n",
|
||||
" if len(dirs) > 0:\n",
|
||||
" for dir in dirs:\n",
|
||||
" # 获取二级子文件夹中的所有 CSV 文件\n",
|
||||
" all_csv_files = [os.path.join(dir, file) for file in os.listdir(dir) if file.endswith('.csv')]\n",
|
||||
"\n",
|
||||
" sp_old_chars = ['_2019', '_2020', '_2021']\n",
|
||||
" for sp_old_char in sp_old_chars:\n",
|
||||
" csv_old_files = [sp_file for sp_file in all_csv_files if sp_old_char in sp_file]\n",
|
||||
" if len(csv_old_files) > 0:\n",
|
||||
" old_df, old_code_value = merged_old_tickdata(csv_old_files, sp_old_char)\n",
|
||||
" folder_path = str('D:/data_merged/上期所/%s'%(old_code_value))\n",
|
||||
"\n",
|
||||
" if not os.path.exists(folder_path):\n",
|
||||
" os.makedirs(folder_path)\n",
|
||||
" \n",
|
||||
" old_df.to_csv('%s/%s%s.csv'%(folder_path,old_code_value,sp_old_char), index=False)\n",
|
||||
" print(\"%s%s.CSV文件合并成功!\"%(old_code_value,sp_old_char))\n",
|
||||
"\n",
|
||||
" sp_new_chars = ['_2022', '_2023']\n",
|
||||
" for sp_new_char in sp_new_chars:\n",
|
||||
" csv_new_files = [sp_file for sp_file in all_csv_files if sp_new_char in sp_file]\n",
|
||||
" if len(csv_new_files) > 0:\n",
|
||||
" new_df, new_code_value = merged_new_tickdata(csv_new_files, sp_new_char)\n",
|
||||
" new_df.head()\n",
|
||||
" folder_path = str('D:/data_merged/上期所/%s'%(new_code_value))\n",
|
||||
"\n",
|
||||
" if not os.path.exists(folder_path):\n",
|
||||
" os.makedirs(folder_path)\n",
|
||||
" \n",
|
||||
" new_df.to_csv('%s/%s%s.csv'%(folder_path,new_code_value,sp_new_char), index=False)\n",
|
||||
" print(\"%s%s.CSV文件合并成功!\"%(new_code_value,sp_new_char))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a028b88e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 列错读取错误文件\n",
|
||||
"当前读取文件读取错误: bu主力连续\\bu主力连续_20190530.csv\n",
|
||||
"当前读取文件读取错误: bu主力连续\\bu主力连续_20190701.csv"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "200715a8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"df = pd.read_csv(\n",
|
||||
" \"D:/data_merged/上期所/bu888/bu888_2019.csv\", \n",
|
||||
" header=0,\n",
|
||||
" # usecols=[ 1, 2, 3, 7, 12, 13, 14, 15],\n",
|
||||
" # names=[\n",
|
||||
" # \"合约代码\",\n",
|
||||
" # \"时间\",\n",
|
||||
" # \"最新\",\n",
|
||||
" # \"成交量\",\n",
|
||||
" # \"买一价\",\n",
|
||||
" # \"卖一价\",\n",
|
||||
" # \"买一量\",\n",
|
||||
" # \"卖一量\",\n",
|
||||
" # ],\n",
|
||||
" encoding='gbk',#ISO-8859-1\n",
|
||||
" # skiprows=0,\n",
|
||||
" # parse_dates=['时间']\n",
|
||||
" )\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "3c61930c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>main_contract</th>\n",
|
||||
" <th>symbol</th>\n",
|
||||
" <th>datetime</th>\n",
|
||||
" <th>lastprice</th>\n",
|
||||
" <th>volume</th>\n",
|
||||
" <th>bid_p</th>\n",
|
||||
" <th>ask_p</th>\n",
|
||||
" <th>bid_v</th>\n",
|
||||
" <th>ask_v</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>bu888</td>\n",
|
||||
" <td>bu1912</td>\n",
|
||||
" <td>2019-05-27 21:00:00.500</td>\n",
|
||||
" <td>3252.0</td>\n",
|
||||
" <td>734</td>\n",
|
||||
" <td>3252.0</td>\n",
|
||||
" <td>3256.0</td>\n",
|
||||
" <td>288</td>\n",
|
||||
" <td>15</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>bu888</td>\n",
|
||||
" <td>bu1912</td>\n",
|
||||
" <td>2019-05-27 21:00:01.000</td>\n",
|
||||
" <td>3250.0</td>\n",
|
||||
" <td>3240</td>\n",
|
||||
" <td>3250.0</td>\n",
|
||||
" <td>3252.0</td>\n",
|
||||
" <td>43</td>\n",
|
||||
" <td>38</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>bu888</td>\n",
|
||||
" <td>bu1912</td>\n",
|
||||
" <td>2019-05-27 21:00:01.500</td>\n",
|
||||
" <td>3250.0</td>\n",
|
||||
" <td>2226</td>\n",
|
||||
" <td>3250.0</td>\n",
|
||||
" <td>3252.0</td>\n",
|
||||
" <td>15</td>\n",
|
||||
" <td>19</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>bu888</td>\n",
|
||||
" <td>bu1912</td>\n",
|
||||
" <td>2019-05-27 21:00:02.000</td>\n",
|
||||
" <td>3248.0</td>\n",
|
||||
" <td>962</td>\n",
|
||||
" <td>3246.0</td>\n",
|
||||
" <td>3248.0</td>\n",
|
||||
" <td>110</td>\n",
|
||||
" <td>8</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>bu888</td>\n",
|
||||
" <td>bu1912</td>\n",
|
||||
" <td>2019-05-27 21:00:02.500</td>\n",
|
||||
" <td>3248.0</td>\n",
|
||||
" <td>1178</td>\n",
|
||||
" <td>3248.0</td>\n",
|
||||
" <td>3250.0</td>\n",
|
||||
" <td>10</td>\n",
|
||||
" <td>110</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" main_contract symbol datetime lastprice volume bid_p \\\n",
|
||||
"0 bu888 bu1912 2019-05-27 21:00:00.500 3252.0 734 3252.0 \n",
|
||||
"1 bu888 bu1912 2019-05-27 21:00:01.000 3250.0 3240 3250.0 \n",
|
||||
"2 bu888 bu1912 2019-05-27 21:00:01.500 3250.0 2226 3250.0 \n",
|
||||
"3 bu888 bu1912 2019-05-27 21:00:02.000 3248.0 962 3246.0 \n",
|
||||
"4 bu888 bu1912 2019-05-27 21:00:02.500 3248.0 1178 3248.0 \n",
|
||||
"\n",
|
||||
" ask_p bid_v ask_v \n",
|
||||
"0 3256.0 288 15 \n",
|
||||
"1 3252.0 43 38 \n",
|
||||
"2 3252.0 15 19 \n",
|
||||
"3 3248.0 110 8 \n",
|
||||
"4 3250.0 10 110 "
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"#'gbk' codec can't decode byte 0xc3 in position 189076: illegal multibyte sequence\n",
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1b22d988",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = df.sort_values(by = ['datetime'], ascending=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cc14352a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['datetime'] = sorted(df['datetime'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2dc49f0c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "befec0c4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import chardet"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6397fffb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 假设file_path是你要读取的文件路径\n",
|
||||
"with open(\"D:/data_all/doing/bu主力连续/bu主力连续_20190530.csv\", 'rb') as file:\n",
|
||||
" data = file.read()\n",
|
||||
" \n",
|
||||
"# 使用chardet检测编码\n",
|
||||
"detected_encoding = chardet.detect(data)['encoding']\n",
|
||||
" \n",
|
||||
"# # 如果检测到的编码不是gbk,可以尝试转换编码后再读取\n",
|
||||
"# if detected_encoding and detected_encoding != 'gbk':\n",
|
||||
"# with open(file_path, 'rb') as file:\n",
|
||||
"# data = file.read().decode(detected_encoding)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c2433c60",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(detected_encoding)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.7.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
import pandas as pd
|
||||
import os
|
||||
from datetime import time as s_time
|
||||
from datetime import datetime
|
||||
import chardet
|
||||
|
||||
# 日盘商品期货交易品种
|
||||
commodity_day_dict = {'bb': s_time(15,00), 'jd': s_time(15,00), 'lh': s_time(15,00), 'l': s_time(15,00), 'fb': s_time(15,00), 'ec': s_time(15,00),
|
||||
'AP': s_time(15,00), 'CJ': s_time(15,00), 'JR': s_time(15,00), 'LR': s_time(15,00), 'RS': s_time(15,00), 'PK': s_time(15,00),
|
||||
'PM': s_time(15,00), 'PX': s_time(15,00), 'RI': s_time(15,00), 'ao': s_time(15,00), 'br': s_time(15,00), 'wr': s_time(15,00),}
|
||||
|
||||
# 夜盘商品期货交易品种
|
||||
commodity_night_dict = {'sc': s_time(2,30), 'bc': s_time(1,0), 'lu': s_time(23,0), 'nr': s_time(23,0),'au': s_time(2,30), 'ag': s_time(2,30),
|
||||
'ss': s_time(1,0), 'sn': s_time(1,0), 'ni': s_time(1,0), 'pb': s_time(1,0),'zn': s_time(1,0), 'al': s_time(1,0), 'cu': s_time(1,0),
|
||||
'ru': s_time(23,0), 'rb': s_time(23,0), 'hc': s_time(23,0), 'fu': s_time(23,0), 'bu': s_time(23,0), 'sp': s_time(23,0),
|
||||
'PF': s_time(23,0), 'SR': s_time(23,0), 'CF': s_time(23,0), 'CY': s_time(23,0), 'RM': s_time(23,0), 'MA': s_time(23,0),
|
||||
'TA': s_time(23,0), 'ZC': s_time(23,0), 'FG': s_time(23,0), 'OI': s_time(23,0), 'SA': s_time(23,0),
|
||||
'p': s_time(23,0), 'j': s_time(23,0), 'jm': s_time(23,0), 'i': s_time(23,0), 'l': s_time(23,0), 'v': s_time(23,0),
|
||||
'pp': s_time(23,0), 'eg': s_time(23,0), 'c': s_time(23,0), 'cs': s_time(23,0), 'y': s_time(23,0), 'm': s_time(23,0),
|
||||
'a': s_time(23,0), 'b': s_time(23,0), 'rr': s_time(23,0), 'eb': s_time(23,0), 'pg': s_time(23,0)}
|
||||
|
||||
# 金融期货交易品种
|
||||
financial_time_dict = {'IH': s_time(15,00), 'IF': s_time(15,00), 'IC': s_time(15,00), 'IM': s_time(15,00),'T': s_time(15,00), 'TS': s_time(15,00),
|
||||
'TF': s_time(15,00), 'TL': s_time(15,00)}
|
||||
|
||||
# 所有已列入的筛选品种
|
||||
all_dict = {k: v for d in [commodity_day_dict, commodity_night_dict, financial_time_dict] for k, v in d.items()}
|
||||
|
||||
# def has_common_keys(*dicts):
|
||||
# keys_union = set().union(*dicts) # 计算所有字典键的并集
|
||||
# keys_intersection = set().intersection(*dicts) # 计算所有字典键的交集
|
||||
# return len(keys_intersection) > 0
|
||||
|
||||
# has_common_keys(commodity_day_dict, commodity_night_dict,financial_time_dict)
|
||||
|
||||
# import chardet
|
||||
|
||||
# # 假设file_path是你要读取的文件路径
|
||||
# with open(file_path, 'rb') as file:
|
||||
# data = file.read()
|
||||
|
||||
# # 使用chardet检测编码
|
||||
# detected_encoding = chardet.detect(data)['encoding']
|
||||
|
||||
# # 如果检测到的编码不是gbk,可以尝试转换编码后再读取
|
||||
# if detected_encoding and detected_encoding != 'gbk':
|
||||
# with open(file_path, 'rb') as file:
|
||||
# data = file.read().decode(detected_encoding)
|
||||
|
||||
def split_alpha_numeric(string):
|
||||
alpha_chars = ""
|
||||
numeric_chars = ""
|
||||
for char in string:
|
||||
if char.isalpha():
|
||||
alpha_chars += char
|
||||
elif char.isdigit():
|
||||
numeric_chars += char
|
||||
return alpha_chars, numeric_chars
|
||||
|
||||
def find_files(all_csv_files):
|
||||
all_csv_files = sorted(all_csv_files)
|
||||
sp_old_chars = ['_2019','_2020','_2021']
|
||||
sp_old_chars = sorted(sp_old_chars)
|
||||
sp_new_chars = ['_2022','_2023']
|
||||
sp_new_chars = sorted(sp_new_chars)
|
||||
csv_old_files = [file for file in all_csv_files if any(sp_char in file for sp_char in sp_old_chars)]
|
||||
csv_new_files = [file for file in all_csv_files if any(sp_char in file for sp_char in sp_new_chars)]
|
||||
|
||||
return csv_old_files, csv_new_files
|
||||
|
||||
def merged_old_tickdata(all_csv_files, sp_char):
|
||||
merged_up_df = pd.DataFrame()
|
||||
merged_up_df = merged_old_unprocessed_tickdata(all_csv_files, sp_char)
|
||||
# 获取当前目录下的所有文件名包含sp_char的csv文件
|
||||
|
||||
# 添加主力连续的合约代码,主力连续为888,指数连续可以用999,次主力连续可以使用889,表头用“统一代码”
|
||||
alpha_chars, numeric_chars = split_alpha_numeric(merged_up_df.loc[0,'合约代码'])
|
||||
code_value = alpha_chars + "888"
|
||||
print("code_value characters:", code_value)
|
||||
merged_up_df.insert(loc=0,column="统一代码", value=code_value)
|
||||
|
||||
while alpha_chars not in all_dict.keys():
|
||||
print("%s期货品种未列入所有筛选条件中!!!"%(code_value))
|
||||
continue
|
||||
|
||||
# merged_df['时间'] = pd.to_datetime(merged_df['时间'])
|
||||
merged_df =pd.DataFrame({'main_contract':merged_df['统一代码'],'symbol':merged_df['合约代码'],'datetime':merged_df['时间'],'lastprice':merged_df['最新'],'volume':merged_df['成交量'],
|
||||
'bid_p':merged_df['买一价'],'ask_p':merged_df['卖一价'],'bid_v':merged_df['买一量'],'ask_v':merged_df['卖一量']})
|
||||
|
||||
merged_df['tmp_time'] = merged_df['datetime'].dt.strftime('%H:%M:%S.%f')
|
||||
merged_df['time'] = merged_df['tmp_time'].apply(lambda x: datetime.strptime(x, '%H:%M:%S.%f')).dt.time
|
||||
del merged_df['tmp_time']
|
||||
|
||||
|
||||
if alpha_chars in financial_time_dict.keys():
|
||||
drop_index1 = pd.DataFrame().index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 0, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 30, 0, 000000))].index
|
||||
drop_index4 = pd.DataFrame().index
|
||||
print("按照中金所交易时间筛选金融期货品种")
|
||||
# else:
|
||||
elif alpha_chars in commodity_night_dict.keys():
|
||||
if commodity_night_dict[alpha_chars] == s_time(23,00):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(23, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为23:00筛选商品期货品种")
|
||||
elif commodity_night_dict[alpha_chars] == s_time(1,00):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(1, 0, 0, 000000)) & (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为1:00筛选商品期货品种")
|
||||
elif commodity_night_dict[alpha_chars] == s_time(2,30):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(2, 30, 0, 000000)) & (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为2:30筛选商品期货品种")
|
||||
else:
|
||||
print("夜盘截止交易时间未设置或者设置错误!!!")
|
||||
elif alpha_chars in commodity_day_dict.keys():
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
drop_index4 = pd.DataFrame().index
|
||||
print("按照无夜盘筛选商品期货品种")
|
||||
else:
|
||||
print("%s期货品种未列入筛选条件中!!!"%(code_value))
|
||||
# 清理不在交易时间段的数据
|
||||
merged_df.drop(labels=drop_index1, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index2, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index3, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index4, axis=0, inplace=True)
|
||||
|
||||
del merged_df['time']
|
||||
# sorted_merged_df = merged_df.sort_values(by = ['datetime'], ascending=True)
|
||||
# merged_df['datetime'] = pd.to_datetime(merged_df['datetime'])
|
||||
merged_df['datetime'] = sorted(merged_df['datetime'])
|
||||
print("%s%s数据生成成功!"%(code_value,sp_char))
|
||||
|
||||
return merged_df, code_value
|
||||
|
||||
def merged_new_tickdata(all_csv_files, sp_char):
|
||||
# 获取当前目录下的所有文件名包含sp_char的csv文件
|
||||
csv_files = [sp_file for sp_file in all_csv_files if sp_char in sp_file]
|
||||
print("csv_files:", csv_files)
|
||||
merged_df = pd.DataFrame()
|
||||
|
||||
dir = os.getcwd()
|
||||
|
||||
# 循环遍历每个csv文件
|
||||
for file in csv_files:
|
||||
# 读取csv文件,并使用第一行为列标题,编译不通过可以改为gbk
|
||||
try:
|
||||
df = pd.read_csv(
|
||||
file,
|
||||
header=0,
|
||||
usecols=[0, 1, 4, 11, 20, 21, 22, 23, 24, 25, 43],
|
||||
names=[
|
||||
"交易日",
|
||||
"合约代码",
|
||||
"最新价",
|
||||
"数量",
|
||||
"最后修改时间",
|
||||
"最后修改毫秒",
|
||||
"申买价一",
|
||||
"申买量一",
|
||||
"申卖价一",
|
||||
"申卖量一",
|
||||
"业务日期",
|
||||
],
|
||||
encoding='gbk',
|
||||
# skiprows=0,
|
||||
parse_dates=['业务日期','最后修改时间','最后修改毫秒'])#注意此处增加的排序,为了后面按时间排序
|
||||
except:
|
||||
# 假设file_path是你要读取的文件路径
|
||||
file_path = os.path.join(dir, file)
|
||||
with open(file_path, 'rb') as file:
|
||||
data = file.read()
|
||||
|
||||
# 使用chardet检测编码
|
||||
detected_encoding = chardet.detect(data)['encoding']
|
||||
print("当前读取文件读取错误:", file)
|
||||
print("当前读取文件正确解码格式", detected_encoding)
|
||||
# 删除重复行
|
||||
df.drop_duplicates(inplace=True)
|
||||
# 将数据合并到新的DataFrame中
|
||||
merged_df = pd.concat([merged_df, df], ignore_index=True)
|
||||
|
||||
# 删除重复列
|
||||
merged_df.drop_duplicates(subset = merged_df.columns.tolist(), inplace=True)
|
||||
# 重置行索引
|
||||
merged_df.reset_index(inplace=True, drop=True)
|
||||
#print("合约代码:", merged_df["合约代码"])
|
||||
|
||||
# 插入新的数据
|
||||
alpha_chars, numeric_chars = split_alpha_numeric(merged_df.loc[0,'合约代码'])
|
||||
# print("Alphabetical characters:", alpha_chars)
|
||||
# 添加主力连续的合约代码,主力连续为888,指数连续可以用999,次主力连续可以使用889,表头用“统一代码”
|
||||
code_value = alpha_chars + "888"
|
||||
print("code_value characters:", code_value)
|
||||
merged_df.insert(loc=1, column="统一代码", value=code_value)
|
||||
|
||||
while alpha_chars not in all_dict.keys():
|
||||
print("%s期货品种未列入所有筛选条件中!!!"%(code_value))
|
||||
continue
|
||||
|
||||
#日期修正
|
||||
#merged_df['业务日期'] = pd.to_datetime(merged_df['业务日期'])
|
||||
merged_df['业务日期'] = merged_df['业务日期'].dt.strftime('%Y-%m-%d')
|
||||
merged_df['datetime'] = merged_df['业务日期'] + ' '+merged_df['最后修改时间'].dt.time.astype(str) + '.' + merged_df['最后修改毫秒'].astype(str)
|
||||
# 将'datetime' 列的数据类型更改为 datetime 格式,如果数据转换少8个小时,可以用timedelta处理
|
||||
merged_df['datetime'] = pd.to_datetime(merged_df['datetime'], errors='coerce', format='%Y-%m-%d %H:%M:%S.%f')
|
||||
#计算瞬时成交量
|
||||
merged_df['volume'] = merged_df['数量'] - merged_df['数量'].shift(1)
|
||||
merged_df['volume'] = merged_df['volume'].fillna(0)
|
||||
|
||||
merged_df =pd.DataFrame({'main_contract':merged_df['统一代码'],'symbol':merged_df['合约代码'],'datetime':merged_df['datetime'],'lastprice':merged_df['最新价'],'volume':merged_df['volume'],
|
||||
'bid_p':merged_df['申买价一'],'ask_p':merged_df['申卖价一'],'bid_v':merged_df['申买量一'],'ask_v':merged_df['申卖量一']})
|
||||
|
||||
merged_df['tmp_time'] = merged_df['datetime'].dt.strftime('%H:%M:%S.%f')
|
||||
merged_df['time'] = merged_df['tmp_time'].apply(lambda x: datetime.strptime(x, '%H:%M:%S.%f')).dt.time
|
||||
del merged_df['tmp_time']
|
||||
|
||||
if alpha_chars in financial_time_dict.keys():
|
||||
drop_index1 = pd.DataFrame().index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 0, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 30, 0, 000000))].index
|
||||
drop_index4 = pd.DataFrame().index
|
||||
print("按照中金所交易时间筛选金融期货品种")
|
||||
# else:
|
||||
elif alpha_chars in commodity_night_dict.keys():
|
||||
if commodity_night_dict[alpha_chars] == s_time(23,00):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(23, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为23:00筛选商品期货品种")
|
||||
elif commodity_night_dict[alpha_chars] == s_time(1,00):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(1, 0, 0, 000000)) & (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为1:00筛选商品期货品种")
|
||||
elif commodity_night_dict[alpha_chars] == s_time(2,30):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(2, 30, 0, 000000)) & (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为2:30筛选商品期货品种")
|
||||
else:
|
||||
print("夜盘截止交易时间未设置或者设置错误!!!")
|
||||
elif alpha_chars in commodity_day_dict.keys():
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
drop_index4 = pd.DataFrame().index
|
||||
print("按照无夜盘筛选商品期货品种")
|
||||
else:
|
||||
print("%s期货品种未列入筛选条件中!!!"%(code_value))
|
||||
|
||||
# 清理不在交易时间段的数据
|
||||
merged_df.drop(labels=drop_index1, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index2, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index3, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index4, axis=0, inplace=True)
|
||||
|
||||
del merged_df['time']
|
||||
# sorted_merged_df = merged_df.sort_values(by = ['datetime'], inplace=True)
|
||||
merged_df['datetime'] = sorted(merged_df['datetime'])
|
||||
print("%s%s数据生成成功!"%(code_value,sp_char))
|
||||
|
||||
|
||||
return merged_df, code_value
|
||||
|
||||
def merged_old_unprocessed_tickdata(all_csv_files, sp_char):
|
||||
csv_files = [sp_file for sp_file in all_csv_files if sp_char in sp_file]
|
||||
print("csv_files:", csv_files)
|
||||
merged_df = pd.DataFrame()
|
||||
|
||||
dir = os.getcwd()
|
||||
|
||||
# 循环遍历每个csv文件
|
||||
for file in csv_files:
|
||||
try:
|
||||
# 读取csv文件,并使用第一行为列标题,编译不通过可以改为gbk
|
||||
df = pd.read_csv(file, header=0, encoding='gbk')
|
||||
except:
|
||||
file_path = os.path.join(dir, file)
|
||||
with open(file_path, 'rb') as file:
|
||||
data = file.read()
|
||||
|
||||
# 使用chardet检测编码
|
||||
detected_encoding = chardet.detect(data)['encoding']
|
||||
print("当前读取文件读取错误:", file)
|
||||
print("当前读取文件正确解码格式", detected_encoding)
|
||||
|
||||
# 删除重复行
|
||||
df.drop_duplicates(inplace=True)
|
||||
# 将数据合并到新的DataFrame中
|
||||
merged_df = pd.concat([merged_df, df], ignore_index=True)
|
||||
|
||||
# 删除重复列
|
||||
merged_df.drop_duplicates(subset=merged_df.columns.tolist(), inplace=True)
|
||||
# 重置行索引
|
||||
merged_df.reset_index(inplace=True, drop=True)
|
||||
|
||||
# 插入新的数据
|
||||
alpha_chars, numeric_chars = split_alpha_numeric(merged_df.loc[0,'合约代码'])
|
||||
|
||||
# 添加主力连续的合约代码,主力连续为888,指数连续可以用999,次主力连续可以使用889,表头用“统一代码”
|
||||
code_value = alpha_chars + "888"
|
||||
print("code_value characters:", code_value)
|
||||
merged_df.insert(loc=1,column="统一代码", value=code_value)
|
||||
|
||||
|
||||
# 将合并后的数据保存到csv文件中
|
||||
folder_path = "合成tick数据2019-2021"
|
||||
if not os.path.exists(folder_path):
|
||||
os.mkdir('合成tick数据2019-2021')
|
||||
|
||||
# sorted_merged_df = merged_df.sort_values(by= ['业务日期','最后修改时间','最后修改毫秒'], ascending=[True, True, True])
|
||||
# sorted_merged_df.to_csv('./合成tick数据/%s.csv'%(code_value), index=False)
|
||||
|
||||
merged_df['时间'] = pd.to_datetime(merged_df['时间'])
|
||||
sorted_merged_df = merged_df.sort_values(by = ['时间'], ascending=True)
|
||||
sorted_merged_df.to_csv('./合成tick数据2019-2021/%s%s.csv'%(code_value,sp_char), index=False)
|
||||
del merged_df
|
||||
del sorted_merged_df
|
||||
#merged_df.to_csv('./合成tick数据/%s.csv'%(code_value), index=False) #数据按照时间排序,前面文件夹按照时间修改好了可以直接用这里
|
||||
|
||||
# 打印提示信息
|
||||
print("CSV文件合并成功!")
|
||||
@@ -0,0 +1,281 @@
|
||||
import pandas as pd
|
||||
import os
|
||||
from datetime import time as s_time
|
||||
from datetime import datetime
|
||||
|
||||
# 日盘商品期货交易品种
|
||||
commodity_day_dict = {'bb': s_time(15,00), 'jd': s_time(15,00), 'lh': s_time(15,00), 'l': s_time(15,00), 'fb': s_time(15,00),}
|
||||
|
||||
# 夜盘商品期货交易品种
|
||||
commodity_night_dict = {'sc': s_time(2,30), 'bc': s_time(1,0), 'lu': s_time(23,0), 'nr': s_time(23,0),'au': s_time(2,30), 'ag': s_time(2,30),
|
||||
'ss': s_time(1,0), 'sn': s_time(1,0), 'ni': s_time(1,0), 'pb': s_time(1,0),'zn': s_time(1,0), 'al': s_time(1,0), 'cu': s_time(1,0),
|
||||
'ru': s_time(23,0), 'rb': s_time(23,0), 'hc': s_time(23,0), 'fu': s_time(23,0), 'bu': s_time(23,0), 'sp': s_time(23,0),
|
||||
'PF': s_time(23,0), 'SR': s_time(23,0), 'CF': s_time(23,0), 'CY': s_time(23,0), 'RM': s_time(23,0), 'MA': s_time(23,0),
|
||||
'TA': s_time(23,0), 'ZC': s_time(23,0), 'FG': s_time(23,0), 'OI': s_time(23,0), 'SA': s_time(23,0),
|
||||
'p': s_time(23,0), 'j': s_time(23,0), 'jm': s_time(23,0), 'i': s_time(23,0), 'l': s_time(23,0), 'v': s_time(23,0),
|
||||
'pp': s_time(23,0), 'eg': s_time(23,0), 'c': s_time(23,0), 'cs': s_time(23,0), 'y': s_time(23,0), 'm': s_time(23,0),
|
||||
'a': s_time(23,0), 'b': s_time(23,0), 'rr': s_time(23,0), 'eb': s_time(23,0), 'pg': s_time(23,0)}
|
||||
|
||||
# 金融期货交易品种
|
||||
financial_time_dict = {'IH': s_time(15,00), 'IF': s_time(15,00), 'IC': s_time(15,00), 'IM': s_time(15,00),'T': s_time(15,00), 'TS': s_time(15,00),
|
||||
'TF': s_time(15,00), 'TL': s_time(15,00)}
|
||||
|
||||
# 所有已列入的筛选品种
|
||||
all_dict = {k: v for d in [commodity_day_dict, commodity_night_dict, financial_time_dict] for k, v in d.items()}
|
||||
|
||||
# def has_common_keys(*dicts):
|
||||
# keys_union = set().union(*dicts) # 计算所有字典键的并集
|
||||
# keys_intersection = set().intersection(*dicts) # 计算所有字典键的交集
|
||||
# return len(keys_intersection) > 0
|
||||
|
||||
# has_common_keys(commodity_day_dict, commodity_night_dict,financial_time_dict)
|
||||
|
||||
def split_alpha_numeric(string):
|
||||
alpha_chars = ""
|
||||
numeric_chars = ""
|
||||
for char in string:
|
||||
if char.isalpha():
|
||||
alpha_chars += char
|
||||
elif char.isdigit():
|
||||
numeric_chars += char
|
||||
return alpha_chars, numeric_chars
|
||||
|
||||
def find_files(all_csv_files):
|
||||
all_csv_files = sorted(all_csv_files)
|
||||
sp_old_chars = ['_2019','_2020','_2021']
|
||||
sp_old_chars = sorted(sp_old_chars)
|
||||
sp_new_chars = ['_2022','_2023']
|
||||
sp_new_chars = sorted(sp_new_chars)
|
||||
csv_old_files = [file for file in all_csv_files if any(sp_char in file for sp_char in sp_old_chars)]
|
||||
csv_new_files = [file for file in all_csv_files if any(sp_char in file for sp_char in sp_new_chars)]
|
||||
|
||||
return csv_old_files, csv_new_files
|
||||
|
||||
def merged_old_tickdata(all_csv_files, sp_char):
|
||||
# 获取当前目录下的所有文件名包含sp_char的csv文件
|
||||
csv_files = [sp_file for sp_file in all_csv_files if sp_char in sp_file]
|
||||
print("csv_files:", csv_files)
|
||||
merged_df = pd.DataFrame()
|
||||
|
||||
# 循环遍历每个csv文件
|
||||
for file in csv_files:
|
||||
# 读取csv文件,并使用第一行为列标题,编译不通过可以改为gbk
|
||||
df = pd.read_csv(
|
||||
file,
|
||||
header=0,
|
||||
usecols=[ 1, 2, 3, 4, 8, 13, 14, 15, 16],
|
||||
names=[
|
||||
"统一代码",
|
||||
"合约代码",
|
||||
"时间",
|
||||
"最新",
|
||||
"成交量",
|
||||
"买一价",
|
||||
"卖一价",
|
||||
"买一量",
|
||||
"卖一量",
|
||||
],
|
||||
encoding='utf-8',
|
||||
# skiprows=0,
|
||||
parse_dates=['时间'])#注意此处增加的排序,为了后面按时间排序
|
||||
# 删除重复行
|
||||
df.drop_duplicates(inplace=True)
|
||||
# 将数据合并到新的DataFrame中
|
||||
merged_df = pd.concat([merged_df, df], ignore_index=True)
|
||||
|
||||
# 删除重复列
|
||||
merged_df.drop_duplicates(subset = merged_df.columns.tolist(), inplace=True)
|
||||
# 重置行索引
|
||||
merged_df.reset_index(inplace=True, drop=True)
|
||||
# print("合约代码:", merged_df["合约代码"])
|
||||
|
||||
# # 插入新的数据
|
||||
alpha_chars, numeric_chars = split_alpha_numeric(merged_df.loc[0,'合约代码'])
|
||||
# print("Alphabetical characters:", alpha_chars)
|
||||
# 添加主力连续的合约代码,主力连续为888,指数连续可以用999,次主力连续可以使用889,表头用“统一代码”
|
||||
code_value = alpha_chars + "888"
|
||||
print("code_value characters:", code_value)
|
||||
# merged_df.insert(loc=0,column="统一代码", value=code_value)
|
||||
|
||||
while alpha_chars not in all_dict.keys():
|
||||
print("%s期货品种未列入所有筛选条件中!!!"%(code_value))
|
||||
continue
|
||||
|
||||
# merged_df['时间'] = pd.to_datetime(merged_df['时间'])
|
||||
merged_df =pd.DataFrame({'main_contract':merged_df['统一代码'],'symbol':merged_df['合约代码'],'datetime':merged_df['时间'],'lastprice':merged_df['最新'],'volume':merged_df['成交量'],
|
||||
'bid_p':merged_df['买一价'],'ask_p':merged_df['卖一价'],'bid_v':merged_df['买一量'],'ask_v':merged_df['卖一量']})
|
||||
|
||||
merged_df['tmp_time'] = merged_df['datetime'].dt.strftime('%H:%M:%S.%f')
|
||||
merged_df['time'] = merged_df['tmp_time'].apply(lambda x: datetime.strptime(x, '%H:%M:%S.%f')).dt.time
|
||||
del merged_df['tmp_time']
|
||||
|
||||
|
||||
if alpha_chars in financial_time_dict.keys():
|
||||
drop_index1 = pd.DataFrame().index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 0, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 30, 0, 000000))].index
|
||||
drop_index4 = pd.DataFrame().index
|
||||
print("按照中金所交易时间筛选金融期货品种")
|
||||
# else:
|
||||
elif alpha_chars in commodity_night_dict.keys():
|
||||
if commodity_night_dict[alpha_chars] == s_time(23,00):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(23, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为23:00筛选商品期货品种")
|
||||
elif commodity_night_dict[alpha_chars] == s_time(1,00):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(1, 0, 0, 000000)) & (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为1:00筛选商品期货品种")
|
||||
elif commodity_night_dict[alpha_chars] == s_time(2,30):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(2, 30, 0, 000000)) & (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为2:30筛选商品期货品种")
|
||||
else:
|
||||
print("夜盘截止交易时间未设置或者设置错误!!!")
|
||||
elif alpha_chars in commodity_day_dict.keys():
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
drop_index4 = pd.DataFrame().index
|
||||
print("按照无夜盘筛选商品期货品种")
|
||||
else:
|
||||
print("%s期货品种未列入筛选条件中!!!"%(code_value))
|
||||
# 清理不在交易时间段的数据
|
||||
merged_df.drop(labels=drop_index1, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index2, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index3, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index4, axis=0, inplace=True)
|
||||
|
||||
del merged_df['time']
|
||||
# sorted_merged_df = merged_df.sort_values(by = ['datetime'], ascending=True)
|
||||
sorted(merged_df['datetime'])
|
||||
print("%s%s数据生成成功!"%(code_value,sp_char))
|
||||
|
||||
return merged_df, code_value
|
||||
|
||||
def merged_new_tickdata(all_csv_files, sp_char):
|
||||
# 获取当前目录下的所有文件名包含sp_char的csv文件
|
||||
csv_files = [sp_file for sp_file in all_csv_files if sp_char in sp_file]
|
||||
print("csv_files:", csv_files)
|
||||
merged_df = pd.DataFrame()
|
||||
|
||||
# 循环遍历每个csv文件
|
||||
for file in csv_files:
|
||||
# 读取csv文件,并使用第一行为列标题,编译不通过可以改为gbk
|
||||
df = pd.read_csv(
|
||||
file,
|
||||
header=0,
|
||||
usecols=[0, 1, 2, 5, 12, 21, 22, 23, 24, 25, 26, 44],
|
||||
names=[
|
||||
"交易日",
|
||||
"统一代码",
|
||||
"合约代码",
|
||||
"最新价",
|
||||
"数量",
|
||||
"最后修改时间",
|
||||
"最后修改毫秒",
|
||||
"申买价一",
|
||||
"申买量一",
|
||||
"申卖价一",
|
||||
"申卖量一",
|
||||
"业务日期",
|
||||
],
|
||||
encoding='utf-8',
|
||||
# skiprows=0,
|
||||
parse_dates=['业务日期','最后修改时间','最后修改毫秒'])#注意此处增加的排序,为了后面按时间排序
|
||||
# 删除重复行
|
||||
df.drop_duplicates(inplace=True)
|
||||
# 将数据合并到新的DataFrame中
|
||||
merged_df = pd.concat([merged_df, df], ignore_index=True)
|
||||
|
||||
# 删除重复列
|
||||
merged_df.drop_duplicates(subset = merged_df.columns.tolist(), inplace=True)
|
||||
# 重置行索引
|
||||
merged_df.reset_index(inplace=True, drop=True)
|
||||
#print("合约代码:", merged_df["合约代码"])
|
||||
|
||||
# 插入新的数据
|
||||
alpha_chars, numeric_chars = split_alpha_numeric(merged_df.loc[0,'合约代码'])
|
||||
# print("Alphabetical characters:", alpha_chars)
|
||||
# 添加主力连续的合约代码,主力连续为888,指数连续可以用999,次主力连续可以使用889,表头用“统一代码”
|
||||
code_value = alpha_chars + "888"
|
||||
print("code_value characters:", code_value)
|
||||
# merged_df.insert(loc=1, column="统一代码", value=code_value)
|
||||
|
||||
while alpha_chars not in all_dict.keys():
|
||||
print("%s期货品种未列入所有筛选条件中!!!"%(code_value))
|
||||
continue
|
||||
|
||||
#日期修正
|
||||
#merged_df['业务日期'] = pd.to_datetime(merged_df['业务日期'])
|
||||
merged_df['业务日期'] = merged_df['业务日期'].dt.strftime('%Y-%m-%d')
|
||||
merged_df['datetime'] = merged_df['业务日期'] + ' '+merged_df['最后修改时间'].dt.time.astype(str) + '.' + merged_df['最后修改毫秒'].astype(str)
|
||||
# 将'datetime' 列的数据类型更改为 datetime 格式,如果数据转换少8个小时,可以用timedelta处理
|
||||
merged_df['datetime'] = pd.to_datetime(merged_df['datetime'], errors='coerce', format='%Y-%m-%d %H:%M:%S.%f')
|
||||
#计算瞬时成交量
|
||||
merged_df['volume'] = merged_df['数量'] - merged_df['数量'].shift(1)
|
||||
merged_df['volume'] = merged_df['volume'].fillna(0)
|
||||
|
||||
merged_df =pd.DataFrame({'main_contract':merged_df['统一代码'],'symbol':merged_df['合约代码'],'datetime':merged_df['datetime'],'lastprice':merged_df['最新价'],'volume':merged_df['volume'],
|
||||
'bid_p':merged_df['申买价一'],'ask_p':merged_df['申卖价一'],'bid_v':merged_df['申买量一'],'ask_v':merged_df['申卖量一']})
|
||||
|
||||
merged_df['tmp_time'] = merged_df['datetime'].dt.strftime('%H:%M:%S.%f')
|
||||
merged_df['time'] = merged_df['tmp_time'].apply(lambda x: datetime.strptime(x, '%H:%M:%S.%f')).dt.time
|
||||
del merged_df['tmp_time']
|
||||
|
||||
if alpha_chars in financial_time_dict.keys():
|
||||
drop_index1 = pd.DataFrame().index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 0, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 30, 0, 000000))].index
|
||||
drop_index4 = pd.DataFrame().index
|
||||
print("按照中金所交易时间筛选金融期货品种")
|
||||
# else:
|
||||
elif alpha_chars in commodity_night_dict.keys():
|
||||
if commodity_night_dict[alpha_chars] == s_time(23,00):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(23, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为23:00筛选商品期货品种")
|
||||
elif commodity_night_dict[alpha_chars] == s_time(1,00):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(1, 0, 0, 000000)) & (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为1:00筛选商品期货品种")
|
||||
elif commodity_night_dict[alpha_chars] == s_time(2,30):
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) & (merged_df['time'] < s_time(21, 0, 0, 000000))].index
|
||||
drop_index4 = merged_df.loc[(merged_df['time'] > s_time(2, 30, 0, 000000)) & (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
print("按照夜盘截止交易时间为2:30筛选商品期货品种")
|
||||
else:
|
||||
print("夜盘截止交易时间未设置或者设置错误!!!")
|
||||
elif alpha_chars in commodity_day_dict.keys():
|
||||
drop_index1 = merged_df.loc[(merged_df['time'] > s_time(10, 15, 0, 000000)) & (merged_df['time'] < s_time(10, 30, 0, 000000))].index
|
||||
drop_index2 = merged_df.loc[(merged_df['time'] > s_time(11, 30, 0, 000000)) & (merged_df['time'] < s_time(13, 30, 0, 000000))].index
|
||||
drop_index3 = merged_df.loc[(merged_df['time'] > s_time(15, 0, 0, 000000)) | (merged_df['time'] < s_time(9, 0, 0, 000000))].index
|
||||
drop_index4 = pd.DataFrame().index
|
||||
print("按照无夜盘筛选商品期货品种")
|
||||
else:
|
||||
print("%s期货品种未列入筛选条件中!!!"%(code_value))
|
||||
|
||||
# 清理不在交易时间段的数据
|
||||
merged_df.drop(labels=drop_index1, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index2, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index3, axis=0, inplace=True)
|
||||
merged_df.drop(drop_index4, axis=0, inplace=True)
|
||||
|
||||
del merged_df['time']
|
||||
# sorted_merged_df = merged_df.sort_values(by = ['datetime'], inplace=True)
|
||||
sorted(merged_df['datetime'])
|
||||
print("%s%s数据生成成功!"%(code_value,sp_char))
|
||||
|
||||
|
||||
return merged_df, code_value
|
||||
@@ -0,0 +1,454 @@
|
||||
'''
|
||||
以下是代码的详细说明:
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
1.
|
||||
导入必要的模块和库:
|
||||
backtrader 用于回测功能
|
||||
datetime 用于处理日期和时间
|
||||
GenericCSVData 用于从CSV文件加载数据
|
||||
numpy 用于数值操作
|
||||
time 用于时间相关操作
|
||||
matplotlib.pyplot 用于绘图
|
||||
|
||||
2. 定义自定义手续费模板MyCommission
|
||||
继承自bt.CommInfoBase
|
||||
|
||||
3.
|
||||
定义自定义数据源类 GenericCSV_SIG:
|
||||
继承自 GenericCSVData,并添加了两个额外的行:'sig'和'delta'
|
||||
定义了参数 'sig'和'delta'
|
||||
|
||||
4.
|
||||
定义 MyStrategy_固定止损_跟踪止盈 类:
|
||||
继承自 bt.Strategy(backtrader的基础策略类)
|
||||
定义了两个参数:trailing_stop_percent 和 fixed_stop_loss_percent
|
||||
初始化策略并设置各种变量和指标
|
||||
实现了 next 方法,该方法在数据源的每个新的K线出现时被调用
|
||||
根据当前K线数据更新跟踪止盈价格
|
||||
实现了跟踪止盈出场和固定止损出场
|
||||
根据信号处理多头和空头仓位
|
||||
在策略执行过程中打印调试信息
|
||||
|
||||
5.
|
||||
if __name__ == "__main__": 代码块:
|
||||
使用 Cerebro 实例设置回测环境
|
||||
使用 GenericCSV_SIG 数据源从CSV文件加载数据
|
||||
将数据源和策略添加到 Cerebro 实例中
|
||||
添加观察者和分析器以评估性能
|
||||
设置初始资金和经纪人参数
|
||||
运行回测并获取结果
|
||||
打印回测报告,包括收益率、回撤、胜率和交易统计数据
|
||||
使用 matplotlib 绘制回测结果
|
||||
使用说明:使用前需要调整的相关参数如下
|
||||
1.确定python到csv文件夹下运行,修改csv文件为需要运行的csv
|
||||
2.MyStrategy_固定止损_跟踪止盈:可以修改跟踪百分比和移动周期均线。
|
||||
3.__init__函数中:可以修改lost手数,,
|
||||
4.next函数:一、修改清仓时间参数,每个品种不一致;二、window_size和window_size_delta的周期暂为10;三、修改“开多组合”和“开空组合”
|
||||
5.__main__函数:一、修改回测时间段fromdate和todate;二、根据交易平中设置初始资金、手续费,单手保证金,合约倍数;
|
||||
'''
|
||||
|
||||
# 需要进一步了解windows_size的计算规则,日线?
|
||||
|
||||
import backtrader as bt
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
from backtrader.feeds import GenericCSVData
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import os
|
||||
|
||||
# 导入表头解决图标中中文显示问题
|
||||
from pylab import mpl
|
||||
|
||||
手续费汇总=0
|
||||
|
||||
|
||||
class GenericCSV_SIG(GenericCSVData):
|
||||
# 从基类继承,添加一个 'sig',‘delta’行
|
||||
lines = ('sig','delta')
|
||||
# 添加参数为从基类继承的参数
|
||||
params = (('sig',6),('delta', 8))
|
||||
|
||||
class MyStrategy_固定止损_跟踪止盈(bt.Strategy):
|
||||
params = (
|
||||
('trailing_stop_percent', 0.02), # 跟踪止盈百分比
|
||||
('fixed_stop_loss_percent', 0.01), # 固定止损百分比
|
||||
|
||||
# ('sma1_period', 60), # 移动平均线周期
|
||||
# ('sma2_period',120),
|
||||
|
||||
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.Lots=1 #下单手数
|
||||
|
||||
self.signal = self.datas[0].sig # 使用sig字段作为策略的信号字段
|
||||
self.delta= self.datas[0].delta
|
||||
# 获取数据序列别名列表
|
||||
line_aliases = self.datas[0].getlinealiases()
|
||||
self.pos=0
|
||||
print(line_aliases)
|
||||
self.high=self.datas[0].high
|
||||
self.low=self.datas[0].low
|
||||
self.closes=self.datas[0].close
|
||||
self.open=self.datas[0].open
|
||||
self.trailing_stop_percent = self.params.trailing_stop_percent
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.fixed_stop_loss_percent = self.params.fixed_stop_loss_percent
|
||||
self.sl_long_price=0
|
||||
self.sl_shor_price=0
|
||||
#240884432
|
||||
self.out_long=0
|
||||
self.out_short=0
|
||||
self.rinei_ma=[]
|
||||
self.rinei_mean=0
|
||||
|
||||
self.datetime_list= []
|
||||
self.high_list = []
|
||||
self.low_list = []
|
||||
self.close_list = []
|
||||
self.opens_list = []
|
||||
self.deltas_list = []
|
||||
self.delta_cumsum=[]
|
||||
|
||||
self.barN = 0
|
||||
|
||||
# self.sma1 = bt.indicators.SimpleMovingAverage(
|
||||
# self.data, period=self.params.sma1_period
|
||||
# )
|
||||
# self.sma2 = bt.indicators.SimpleMovingAverage(
|
||||
# self.data, period=self.params.sma2_period
|
||||
# )
|
||||
|
||||
self.df = pd.DataFrame(columns=['datetime', 'high', 'low', 'close', 'open', 'delta', 'delta_cumsum'])
|
||||
|
||||
self.trader_df=pd.DataFrame(columns=['open', 'high', 'low', 'close', 'volume', 'openInterest','delta'])
|
||||
|
||||
def log(self, txt, dt=None):
|
||||
'''可选,构建策略打印日志的函数:可用于打印订单记录或交易记录等'''
|
||||
dt = dt or self.datas[0].datetime.date(0)
|
||||
print('%s, %s' % (dt.isoformat(), txt))
|
||||
|
||||
def notify_order(self, order):
|
||||
# 未被处理的订单
|
||||
if order.status in [order.Submitted, order.Accepted]:
|
||||
return
|
||||
# 已经处理的订单
|
||||
if order.status in [order.Completed, order.Canceled, order.Margin]:
|
||||
global 手续费汇总
|
||||
if order.isbuy():
|
||||
手续费汇总 +=order.executed.comm
|
||||
self.log(
|
||||
'BUY EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f' %
|
||||
(order.ref, # 订单编号
|
||||
order.executed.price, # 成交价
|
||||
order.executed.comm, # 佣金
|
||||
order.executed.size, # 成交量
|
||||
order.data._name,# 品种名称
|
||||
手续费汇总))
|
||||
|
||||
else: # Sell
|
||||
手续费汇总 +=order.executed.comm
|
||||
self.log('SELL EXECUTED, 订单编号:%.0f,成交价格: %.2f, 手续费滑点:%.2f, 成交量: %.2f, 品种: %s,手续费汇总:%.2f' %
|
||||
(order.ref,
|
||||
order.executed.price,
|
||||
order.executed.comm,
|
||||
order.executed.size,
|
||||
order.data._name,
|
||||
手续费汇总))
|
||||
|
||||
def next(self):
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
#bar线计数初始化
|
||||
self.barN += 1
|
||||
position = self.getposition(self.datas[0]).size
|
||||
#时间轴
|
||||
dt = bt.num2date(self.data.datetime[0])
|
||||
|
||||
#更新跟踪止损价格
|
||||
def 每日重置数据():
|
||||
# 获取当前时间
|
||||
current_time = dt.time()
|
||||
#print(current_time)
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(22, 55)
|
||||
clearing_time2_end = s_time(23, 0)
|
||||
|
||||
# 创建一个标志变量
|
||||
clearing_executed = False
|
||||
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not clearing_executed :
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma=[]
|
||||
self.delta_cumsum=[]
|
||||
self.deltas_list=[]
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not clearing_executed :
|
||||
clearing_executed = True # 设置标志变量为已执行
|
||||
self.rinei_ma=[]
|
||||
self.delta_cumsum=[]
|
||||
self.deltas_list=[]
|
||||
# 如果不在任何时间范围内,可以执行其他操作
|
||||
else:
|
||||
self.rinei_ma.append(self.closes[0])
|
||||
self.rinei_mean = np.mean(self.rinei_ma)
|
||||
#self.delta_cumsum=[]
|
||||
#self.deltas_list=[]
|
||||
#print('rinei_ma',self.rinei_ma)
|
||||
clearing_executed = False
|
||||
pass
|
||||
|
||||
return clearing_executed
|
||||
|
||||
run_kg=每日重置数据()
|
||||
|
||||
#过滤成交量为0或小于0
|
||||
if self.data.volume[0] <= 0 :
|
||||
return
|
||||
#print(f'volume,{self.data.volume[0]}')
|
||||
if self.long_trailing_stop_price >0 and self.pos>0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = self.low[0] if self.long_trailing_stop_price<self.low[0] else self.long_trailing_stop_price
|
||||
|
||||
#print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price >0 and self.pos<0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = self.high[0] if self.high[0] <self.short_trailing_stop_price else self.short_trailing_stop_price
|
||||
|
||||
#print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
self.out_long=self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short=self.short_trailing_stop_price*(1 + self.trailing_stop_percent)
|
||||
#print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
#print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long >0:
|
||||
if self.low[0] < self.out_long and self.pos>0 and self.sl_long_price>0 and self.low[0]>self.sl_long_price:
|
||||
print('--多头止盈出场datetime+sig: ',dt,'Trailing stop triggered: Closing position','TR',self.out_long,'low', self.low[0])
|
||||
self.close(data=self.data, price=self.data.close[0],size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long=0
|
||||
self.pos = 0
|
||||
|
||||
if self.out_short>0:
|
||||
if self.high[0] > self.out_short and self.pos<0 and self.sl_shor_price>0 and self.high[0]<self.sl_shor_price:
|
||||
print('--空头止盈出场datetime+sig: ',dt,'Trailing stop triggered: Closing position: ','TR',self.out_short,'high', self.high[0])
|
||||
self.close(data=self.data, price=self.data.close[0],size=self.Lots, exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_shor=0
|
||||
self.pos = 0
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if self.sl_long_price>0 and self.fixed_stop_loss_L>0 and self.pos > 0 and self.closes[0] < self.fixed_stop_loss_L:
|
||||
print('--多头止损datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0],size=self.Lots, exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if self.sl_shor_price>0 and self.fixed_stop_loss_S>0 and self.pos < 0 and self.closes[0] > self.fixed_stop_loss_S:
|
||||
print('--空头止损datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], size=self.Lots,exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
|
||||
|
||||
# 更新最高价和最低价的列表
|
||||
self.datetime_list.append(dt)
|
||||
self.high_list.append(self.data.high[0])
|
||||
self.low_list.append(self.data.low[0])
|
||||
self.close_list.append(self.data.close[0])
|
||||
self.opens_list.append(self.data.open[0])
|
||||
self.deltas_list.append(self.data.delta[0])
|
||||
# 计算delta累计
|
||||
self.delta_cumsum.append(sum(self.deltas_list))
|
||||
|
||||
|
||||
# 将当前行数据添加到 DataFrame
|
||||
# new_row = {
|
||||
# 'datetime': dt,
|
||||
# 'high': self.data.high[0],
|
||||
# 'low': self.data.low[0],
|
||||
# 'close': self.data.close[0],
|
||||
# 'open': self.data.open[0],
|
||||
# 'delta': self.data.delta[0],
|
||||
# 'delta_cumsum': sum(self.deltas_list)
|
||||
# }
|
||||
# # 使用pandas.concat代替append
|
||||
# self.df = pd.concat([self.df, pd.DataFrame([new_row])], ignore_index=True)
|
||||
|
||||
# # 检查文件是否存在
|
||||
# csv_file_path = f"output.csv"
|
||||
# if os.path.exists(csv_file_path):
|
||||
# # 仅保存最后一行数据
|
||||
# self.df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
# else:
|
||||
# # 创建新文件并保存整个DataFrame
|
||||
# self.df.to_csv(csv_file_path, index=False)
|
||||
|
||||
|
||||
#
|
||||
if run_kg==False : #
|
||||
# # 构建delta的正数和负数
|
||||
# positive_nums = [x for x in self.data.delta if x > 0]
|
||||
# negative_nums = [x for x in self.data.delta if x < 0]
|
||||
|
||||
# positive_sums = [x for x in self.delta_cumsum if x > 0]
|
||||
# negative_sums = [x for x in self.delta_cumsum if x < 0]
|
||||
# #
|
||||
# # 开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] >1 and self.data.delta[0]>1000 and self.delta_cumsum[-1]>1500
|
||||
# # 开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-1 and self.data.delta[0]<-1000 and self.delta_cumsum[-1]<-1500
|
||||
# 开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] > 1 and self.data.delta[0]>max(self.data.delta[-60:-1]) #and self.delta_cumsum[-1] > np.max(self.delta_cumsum[-61:-2]) #np.mean(self.data.delta_cumsum[-61:-2])
|
||||
# 开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-1 and self.data.delta[0]<min(self.data.delta[-60:-1]) #and self.delta_cumsum[-1] < np.min(self.delta_cumsum[-61:-2]) #np.mean(self.data.delta_cumsum[-61:-2])
|
||||
#print(self.delta_cumsum)
|
||||
开多组合= self.rinei_mean>0 and self.closes[0]>self.rinei_mean and self.signal[0] >1 and self.data.delta[0]>1500 and self.delta_cumsum[-1]>2000
|
||||
开空组合= self.rinei_mean>0 and self.closes[0]<self.rinei_mean and self.signal[0] <-1 and self.data.delta[0]<-1500 and self.delta_cumsum[-1]<-2000
|
||||
平多条件=self.pos<0 and self.signal[0] >1
|
||||
平空条件=self.pos>0 and self.signal[0] <-1
|
||||
if self.pos !=1 : #
|
||||
if 平多条件:
|
||||
#print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_S, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
if 开多组合 : #
|
||||
self.buy(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos=1
|
||||
self.long_trailing_stop_price=self.low[0]
|
||||
self.sl_long_price=self.data.open[0]
|
||||
#print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存多头价格: ',self.long_trailing_stop_price)
|
||||
|
||||
if self.pos !=-1 : #
|
||||
if 平空条件:
|
||||
#print('datetime+sig: ', dt, 'Fixed stop loss triggered: Closing position', 'SL', self.fixed_stop_loss_L, 'close', self.closes[0])
|
||||
self.close(data=self.data, price=self.data.close[0], exectype=bt.Order.Market)
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
if 开空组合: #
|
||||
self.sell(data=self.data, price=self.data.close[0], size=1, exectype=bt.Order.Market)
|
||||
self.pos=-1
|
||||
self.short_trailing_stop_price=self.high[0]
|
||||
self.sl_shor_price=self.data.open[0]
|
||||
#print('datetime+sig: ',dt,' sig: ',self.signal[0],'保存空头价格: ',self.short_trailing_stop_price)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
# 创建Cerebro实例
|
||||
|
||||
cerebro = bt.Cerebro()
|
||||
#数据
|
||||
csv_file='./tick生成的OF数据-own/back_ofdata_dj.csv' #
|
||||
# 从CSV文件加载数据
|
||||
data = GenericCSV_SIG(
|
||||
dataname=csv_file,
|
||||
fromdate=datetime(2023,1,1),
|
||||
todate=datetime(2023,12,29),
|
||||
timeframe=bt.TimeFrame.Minutes,
|
||||
nullvalue=0.0,
|
||||
dtformat='%Y-%m-%d %H:%M:%S',
|
||||
datetime=0,
|
||||
high=3,
|
||||
low=4,
|
||||
open=2,
|
||||
close=1,
|
||||
volume=5,
|
||||
openinterest=None,
|
||||
sig=6,
|
||||
delta=8
|
||||
)
|
||||
|
||||
# 添加数据到Cerebro实例
|
||||
cerebro.adddata(data)
|
||||
|
||||
# 添加策略到Cerebro实例
|
||||
cerebro.addstrategy(MyStrategy_固定止损_跟踪止盈)
|
||||
|
||||
# 添加观察者和分析器到Cerebro实例
|
||||
#cerebro.addobserver(bt.observers.BuySell)
|
||||
cerebro.addobserver(bt.observers.Value)
|
||||
cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')
|
||||
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
|
||||
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trades')
|
||||
初始资金=10000
|
||||
cerebro.broker.setcash(初始资金) # 设置初始资金
|
||||
|
||||
#手续费,单手保证金,合约倍数
|
||||
cerebro.broker.setcommission(commission=14, margin=5000.0,mult=10)#回测参数
|
||||
|
||||
# 运行回测
|
||||
result = cerebro.run()
|
||||
|
||||
# 获取策略分析器中的结果
|
||||
analyzer = result[0].analyzers
|
||||
total_trades = analyzer.trades.get_analysis()['total']['total']
|
||||
winning_trades = analyzer.trades.get_analysis()['won']['total']
|
||||
# 获取TradeAnalyzer分析器的结果
|
||||
trade_analyzer_result = analyzer.trades.get_analysis()
|
||||
# 获取总收益额
|
||||
total_profit = trade_analyzer_result.pnl.net.total
|
||||
|
||||
if total_trades > 0:
|
||||
win_rate = winning_trades / total_trades
|
||||
else:
|
||||
win_rate = 0.0
|
||||
# 打印回测报告
|
||||
print('回测报告:')
|
||||
print('期初权益', 初始资金)
|
||||
print('期末权益', 初始资金+round(total_profit))
|
||||
print('盈亏额', round(total_profit))
|
||||
print('最大回撤率,', round(analyzer.drawdown.get_analysis()['drawdown'],2),'%')
|
||||
print('胜率,', round(win_rate*100,2),'%')
|
||||
print("交易次数,", total_trades)
|
||||
print("盈利次数,", winning_trades)
|
||||
print("亏损次数,", total_trades - winning_trades)
|
||||
print('总手续费+滑点,', 手续费汇总)
|
||||
手续费汇总=0
|
||||
|
||||
# 设置中文显示
|
||||
mpl.rcParams["font.sans-serif"] = ["SimHei"]
|
||||
mpl.rcParams["axes.unicode_minus"] = False
|
||||
|
||||
# 保存回测图像文件
|
||||
plot = cerebro.plot()[0][0]
|
||||
plot_filename = os.path.splitext(os.path.basename(csv_file))[0] +'ss'+ '_plot.png'
|
||||
plot_path = os.path.join('部分回测报告', plot_filename)
|
||||
plot.savefig(plot_path)
|
||||
|
||||
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
@@ -0,0 +1,309 @@
|
||||
'''逐行解释代码:
|
||||
|
||||
1.导入所需的模块和库,包括 time、table(来自 matplotlib.pyplot)、pandas、numpy、numba 和 operator。
|
||||
|
||||
2.定义了一个名为 process 的函数,用于处理买卖盘的字典数据。
|
||||
|
||||
3.定义了一个名为 data 的函数,用于读取并处理 tick 数据,生成分钟级别的 bar 数据。
|
||||
|
||||
4.定义了一个名为 orderflow_df_new 的函数,用于处理 tick 数据和分钟级别的 bar 数据,生成订单流数据。
|
||||
|
||||
5.定义了一个名为 GetOrderFlow_dj 的函数,用于计算订单流的指标(堆积)。
|
||||
|
||||
6.定义了一个名为 back_data 的函数,用于保存回测数据。
|
||||
|
||||
7.在 if __name__ == "__main__": 下,首先调用 data() 函数获取 tick 数据和分钟级别的 bar 数据。
|
||||
|
||||
然后调用 orderflow_df_new() 函数,传入 tick 数据和 bar 数据,生成订单流数据 ofdata。
|
||||
|
||||
打印输出 ofdata。
|
||||
|
||||
8.调用 back_data() 函数,将订单流数据保存为回测数据。
|
||||
|
||||
打印输出 "done",表示程序执行完毕。
|
||||
|
||||
总体而言,该代码的功能是从 tick 数据中生成分钟级别的 bar 数据,然后根据 bar 数据计算订单流,并将订单流数据保存为回测数据。
|
||||
使用说明:使用前需要调整的相关参数如下
|
||||
1.确定python到csv文件夹下运行,修改csv文件为需要运行的csv
|
||||
2.dataload函数:一、确定datetime函数和其他key值是否和现在的一致,不一致的修改;二、resample函数中rule的取样周期进行修改,默认为5T,即5分钟。
|
||||
3.back_data函数和main中需要注意修改相应的时间节点,将开盘的初始数据设置为0,
|
||||
4.如果生成的时间和实际时间相差8小时,可以调用timedelta函数修改
|
||||
'''
|
||||
# GetOrderFlow_dj函数需要进一步了解,先不修改
|
||||
|
||||
import time
|
||||
from matplotlib.pyplot import table
|
||||
from datetime import timedelta
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from numba import *
|
||||
from numba import cuda
|
||||
import operator
|
||||
|
||||
import os
|
||||
|
||||
# 对于含时区的datetime,可以通过timedelta来修改数据
|
||||
#from datetime import datetime, timedelta
|
||||
#os.environ['tz'] = 'Asia/ShangHai'
|
||||
#time.tzset()
|
||||
|
||||
def process(bidDict,askDict):
|
||||
bidDictResult,askDictResult = {},{}
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
#print('bidDict:',list(bidDict.keys()))
|
||||
#print('askDict:',list(askDict.keys()))
|
||||
#print('sList:',sList)
|
||||
#240884432
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
bidDictResult[s] = bidDict[s]
|
||||
else:
|
||||
bidDictResult[s] = 0
|
||||
if s in askDict:
|
||||
askDictResult[s] = askDict[s]
|
||||
else:
|
||||
askDictResult[s] = 0
|
||||
|
||||
return bidDictResult,askDictResult
|
||||
|
||||
|
||||
|
||||
|
||||
def dataload(data):
|
||||
#日期修正
|
||||
data['业务日期'] = data['业务日期'].dt.strftime('%Y-%m-%d')
|
||||
data['datetime'] = data['业务日期'] + ' '+data['最后修改时间'].dt.time.astype(str) + '.' + data['最后修改毫秒'].astype(str)
|
||||
# 将 'datetime' 列的数据类型更改为 datetime 格式,如果数据转换少8个小时,可以用timedelta处理
|
||||
data['datetime'] = pd.to_datetime(data['datetime'], errors='coerce', format='%Y-%m-%d %H:%M:%S.%f')
|
||||
# 如果需要,可以将 datetime 列格式化为字符串
|
||||
#data['formatted_date'] = data['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S.%f')
|
||||
#计算瞬时成交量
|
||||
data['volume'] = data['数量'] - data['数量'].shift(1)
|
||||
data['volume'] = data['volume'].fillna(0)
|
||||
#整理好要用的tick数据元素,具体按照数据的表头进行修改
|
||||
tickdata =pd.DataFrame({'datetime':data['datetime'],'symbol':data['合约代码'],'lastprice':data['最新价'],
|
||||
'volume':data['volume'],'bid_p':data['申买价一'],'bid_v':data['申买量一'],'ask_p':data['申卖价一'],'ask_v':data['申卖量一']})
|
||||
#tickdata['datetime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
|
||||
# # 找到满足条件的行的索引
|
||||
# condition = tickdata['datetime'].dt.time == pd.to_datetime('22:59:59').time()
|
||||
# indexes_to_update = tickdata.index[condition]
|
||||
|
||||
# # 遍历索引,将不一致的日期更新为上一行的日期
|
||||
# for idx in indexes_to_update:
|
||||
# if idx > 0:
|
||||
# tickdata.at[idx, 'datetime'] = tickdata.at[idx - 1, 'datetime'].replace(hour=22, minute=59, second=59)
|
||||
|
||||
# 确保日期列按升序排序
|
||||
tickdata.sort_values(by='datetime', inplace=True)
|
||||
# 时序重采样 https://zhuanlan.zhihu.com/p/70353374
|
||||
bardata = tickdata.resample(on = 'datetime',rule = '1T',label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
#240884432
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
return tickdata,bardata
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def orderflow_df_new(df_tick,df_min):
|
||||
df_of=pd.DataFrame({})
|
||||
t1 = time.time()
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
endArray = pd.to_datetime(df_min['datetime']).values
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
dt=endArray[index]
|
||||
for indexTick in range(indexFinal,len(df_tick)):
|
||||
if tTickArray[indexTick] > tEnd:
|
||||
break
|
||||
elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] <= tEnd):
|
||||
if indexTick==0:
|
||||
Bp = round(bp1TickArray[indexTick],2)
|
||||
Ap = round(ap1TickArray[indexTick],2)
|
||||
else:
|
||||
Bp = round(bp1TickArray[indexTick - 1],2)
|
||||
Ap = round(ap1TickArray[indexTick - 1],2)
|
||||
LastPrice = round(lastTickArray[indexTick],2)
|
||||
Volume = volumeTickArray[indexTick]
|
||||
if LastPrice >= Ap:
|
||||
if LastPrice in askDict.keys():
|
||||
askDict[LastPrice] += Volume
|
||||
else:
|
||||
askDict[LastPrice] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if LastPrice in bidDict.keys():
|
||||
bidDict[LastPrice] += Volume
|
||||
else:
|
||||
bidDict[LastPrice] = Volume
|
||||
indexFinal = indexTick
|
||||
|
||||
bidDictResult,askDictResult = process(bidDict,askDict)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
# 过滤'volume'列小于等于0的行
|
||||
df = df[df['volume'] > 0]
|
||||
# 重新排序DataFrame,按照'datetime'列进行升序排序
|
||||
df = df.sort_values(by='datetime', ascending=True)
|
||||
# 重新设置索引,以便索引能够正确对齐
|
||||
df = df.reset_index(drop=True)
|
||||
#df['ticktime']=tTickArray[indexTick]
|
||||
df['dj']=GetOrderFlow_dj(df)
|
||||
#print(df)
|
||||
df_of = pd.concat([df_of, df], ignore_index=True)
|
||||
print(time.time() - t1)
|
||||
return df_of
|
||||
|
||||
def GetOrderFlow_dj(kData):
|
||||
itemAskBG=['rgb(0,255,255)', 'rgb(255,0,255)', "rgb(255,182,193)"] # 买盘背景色
|
||||
itemBidBG=['rgb(173,255,47)', 'rgb(255,127,80)', "rgb(32,178,170)"] # 卖盘背景色
|
||||
Config={
|
||||
'Value1':3,
|
||||
'Value2':3,
|
||||
'Value3':3,
|
||||
'Value4':True,
|
||||
}
|
||||
aryData=kData
|
||||
djcout=0
|
||||
for index,row in aryData.iterrows():
|
||||
kItem=aryData.iloc[index]
|
||||
high=kItem['high']
|
||||
low=kItem['low']
|
||||
close=kItem['close']
|
||||
open=kItem['open']
|
||||
dtime=kItem['datetime']
|
||||
price_s=kItem['price']
|
||||
Ask_s=kItem['Ask']
|
||||
Bid_s=kItem['Bid']
|
||||
delta=kItem['delta']
|
||||
|
||||
price_s=price_s
|
||||
Ask_s=Ask_s
|
||||
Bid_s=Bid_s
|
||||
|
||||
gj=0
|
||||
xq=0
|
||||
gxx=0
|
||||
xxx=0
|
||||
for i in np.arange (0, len(price_s),1) :
|
||||
duiji={
|
||||
'price':0,
|
||||
'time':0,
|
||||
'longshort':0,
|
||||
'cout':0,
|
||||
'color':'blue'
|
||||
}
|
||||
if i==0 :
|
||||
delta=delta
|
||||
|
||||
order= {
|
||||
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
if i>=0 and i<len(price_s)-1:
|
||||
if (order["Bid"]["Value"]>Ask_s[i+1]*int(Config['Value1'])):
|
||||
order["Bid"]["Color"]=itemAskBG[1]
|
||||
gxx+=1
|
||||
gj+=1
|
||||
if gj>=int(Config['Value2']) and Config['Value4']==True:
|
||||
duiji['price']=price_s[i]
|
||||
duiji['time']=dtime
|
||||
duiji['longshort']=-1
|
||||
duiji['cout']=gj
|
||||
duiji['color']='rgba(0,139,0,0.45)'#绿色
|
||||
if float(duiji['price'])>0:
|
||||
djcout+=-1
|
||||
else :
|
||||
gj=0
|
||||
if i>=1 and i<len(price_s)-1:
|
||||
if (order["Ask"]["Value"]>Bid_s[i-1]*int(Config['Value1'])):
|
||||
xq+=1
|
||||
xxx+=1
|
||||
order["Ask"]["Color"]=itemBidBG[1]
|
||||
if xq>=int(Config['Value2']) and Config['Value4']==True:
|
||||
duiji['price']=price_s[i]
|
||||
duiji['time']=dtime
|
||||
duiji['longshort']=1
|
||||
duiji['cout']=xq
|
||||
duiji['color']='rgba(255,0,0,0.45)' #红色
|
||||
if float(duiji['price'])>0:
|
||||
djcout+=1
|
||||
else :
|
||||
xq=0
|
||||
return djcout
|
||||
|
||||
def back_data(df):
|
||||
# 创建新的DataFrame并填充需要的列
|
||||
new_df = pd.DataFrame()
|
||||
new_df['datetime'] = pd.to_datetime(df['datetime'], format='%Y/%m/%d %H:%M')
|
||||
new_df['close'] = df['close']
|
||||
new_df['open'] = df['open']
|
||||
new_df['high'] = df['high']
|
||||
new_df['low'] = df['low']
|
||||
new_df['volume'] = df['volume']
|
||||
new_df['sig'] = df['dj']
|
||||
new_df['symbol'] = df['symbol']
|
||||
new_df['delta'] = df['delta']
|
||||
new_df.to_csv(f'./tick生成的OF数据/back_ofdata_dj.csv',index=False)
|
||||
#new_df.to_csv(f'{sym}back_ofdata_dj.csv',index=False)
|
||||
|
||||
if __name__ == "__main__":
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
data=pd.read_csv('rb主力连续_20230103.csv',encoding='GBK',parse_dates=['业务日期','最后修改时间']) #
|
||||
print(data)
|
||||
tick,bar=dataload(data)
|
||||
ofdata = orderflow_df_new(tick,bar)
|
||||
print(ofdata)
|
||||
#保存orderflow数据
|
||||
# os.mkdir('./tick生成的OF数据'),或者在to_csv中修改生成的文件名
|
||||
folder_path = "tick生成的OF数据"
|
||||
if not os.path.exists(folder_path):
|
||||
os.mkdir('tick生成的OF数据')
|
||||
ofdata.to_csv('./tick生成的OF数据/ofdata_dj.csv')
|
||||
#保存回测数据
|
||||
back_data(ofdata)
|
||||
print('done')
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
'''逐行解释代码:
|
||||
|
||||
1.导入所需的模块和库,包括 time、table(来自 matplotlib.pyplot)、pandas、numpy、numba 和 operator。
|
||||
|
||||
2.定义了一个名为 process 的函数,用于处理买卖盘的字典数据。
|
||||
|
||||
3.定义了一个名为 data 的函数,用于读取并处理 tick 数据,生成分钟级别的 bar 数据。
|
||||
|
||||
4.定义了一个名为 orderflow_df_new 的函数,用于处理 tick 数据和分钟级别的 bar 数据,生成订单流数据。
|
||||
|
||||
5.定义了一个名为 GetOrderFlow_dj 的函数,用于计算订单流的指标(堆积)。
|
||||
|
||||
6.定义了一个名为 back_data 的函数,用于保存回测数据。
|
||||
|
||||
7.在 if __name__ == "__main__": 下,首先调用 data() 函数获取 tick 数据和分钟级别的 bar 数据。
|
||||
|
||||
然后调用 orderflow_df_new() 函数,传入 tick 数据和 bar 数据,生成订单流数据 ofdata。
|
||||
|
||||
打印输出 ofdata。
|
||||
|
||||
8.调用 back_data() 函数,将订单流数据保存为回测数据。
|
||||
|
||||
打印输出 "done",表示程序执行完毕。
|
||||
|
||||
总体而言,该代码的功能是从 tick 数据中生成分钟级别的 bar 数据,然后根据 bar 数据计算订单流,并将订单流数据保存为回测数据。
|
||||
使用说明:使用前需要调整的相关参数如下
|
||||
1.确定python到csv文件夹下运行,修改csv文件为需要运行的csv
|
||||
2.dataload函数:一、确定datetime函数和其他key值是否和现在的一致,不一致的修改;二、resample函数中rule的取样周期进行修改,默认为5T,即5分钟。
|
||||
3.back_data函数和main中需要注意修改相应的时间节点,将开盘的初始数据设置为0,
|
||||
4.如果生成的时间和实际时间相差8小时,可以调用timedelta函数修改
|
||||
'''
|
||||
# GetOrderFlow_dj函数需要进一步了解,先不修改
|
||||
|
||||
import time
|
||||
from matplotlib.pyplot import table
|
||||
from datetime import timedelta
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from numba import *
|
||||
from numba import cuda
|
||||
import operator
|
||||
|
||||
import os
|
||||
|
||||
# 对于含时区的datetime,可以通过timedelta来修改数据
|
||||
#from datetime import datetime, timedelta
|
||||
#os.environ['tz'] = 'Asia/ShangHai'
|
||||
#time.tzset()
|
||||
|
||||
def process(bidDict,askDict):
|
||||
bidDictResult,askDictResult = {},{}
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
#print('bidDict:',list(bidDict.keys()))
|
||||
#print('askDict:',list(askDict.keys()))
|
||||
#print('sList:',sList)
|
||||
#240884432
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
bidDictResult[s] = bidDict[s]
|
||||
else:
|
||||
bidDictResult[s] = 0
|
||||
if s in askDict:
|
||||
askDictResult[s] = askDict[s]
|
||||
else:
|
||||
askDictResult[s] = 0
|
||||
|
||||
return bidDictResult,askDictResult
|
||||
|
||||
|
||||
|
||||
|
||||
def dataload(data):
|
||||
#日期修正
|
||||
data['业务日期'] = data['业务日期'].dt.strftime('%Y-%m-%d')
|
||||
data['datetime'] = data['业务日期'] + ' '+data['最后修改时间'].dt.time.astype(str) + '.' + data['最后修改毫秒'].astype(str)
|
||||
# 将 'datetime' 列的数据类型更改为 datetime 格式,如果数据转换少8个小时,可以用timedelta处理
|
||||
data['datetime'] = pd.to_datetime(data['datetime'], errors='coerce', format='%Y-%m-%d %H:%M:%S.%f')
|
||||
# 如果需要,可以将 datetime 列格式化为字符串
|
||||
#data['formatted_date'] = data['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S.%f')
|
||||
#计算瞬时成交量
|
||||
data['volume'] = data['数量'] - data['数量'].shift(1)
|
||||
data['volume'] = data['volume'].fillna(0)
|
||||
#整理好要用的tick数据元素,具体按照数据的表头进行修改
|
||||
tickdata =pd.DataFrame({'datetime':data['datetime'],'symbol':data['合约代码'],'lastprice':data['最新价'],
|
||||
'volume':data['volume'],'bid_p':data['申买价一'],'bid_v':data['申买量一'],'ask_p':data['申卖价一'],'ask_v':data['申卖量一']})
|
||||
#tickdata['datetime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
|
||||
# # 找到满足条件的行的索引
|
||||
# condition = tickdata['datetime'].dt.time == pd.to_datetime('22:59:59').time()
|
||||
# indexes_to_update = tickdata.index[condition]
|
||||
|
||||
# # 遍历索引,将不一致的日期更新为上一行的日期
|
||||
# for idx in indexes_to_update:
|
||||
# if idx > 0:
|
||||
# tickdata.at[idx, 'datetime'] = tickdata.at[idx - 1, 'datetime'].replace(hour=22, minute=59, second=59)
|
||||
|
||||
# 确保日期列按升序排序
|
||||
tickdata.sort_values(by='datetime', inplace=True)
|
||||
# 时序重采样 https://zhuanlan.zhihu.com/p/70353374
|
||||
bardata = tickdata.resample(on = 'datetime',rule = '1T',label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
#240884432
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
return tickdata,bardata
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def orderflow_df_new(df_tick,df_min):
|
||||
df_of=pd.DataFrame({})
|
||||
t1 = time.time()
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
endArray = pd.to_datetime(df_min['datetime']).values
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
dt=endArray[index]
|
||||
for indexTick in range(indexFinal,len(df_tick)):
|
||||
if tTickArray[indexTick] > tEnd:
|
||||
break
|
||||
elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] <= tEnd):
|
||||
if indexTick==0:
|
||||
Bp = round(bp1TickArray[indexTick],2)
|
||||
Ap = round(ap1TickArray[indexTick],2)
|
||||
else:
|
||||
Bp = round(bp1TickArray[indexTick - 1],2)
|
||||
Ap = round(ap1TickArray[indexTick - 1],2)
|
||||
LastPrice = round(lastTickArray[indexTick],2)
|
||||
Volume = volumeTickArray[indexTick]
|
||||
if LastPrice >= Ap:
|
||||
if LastPrice in askDict.keys():
|
||||
askDict[LastPrice] += Volume
|
||||
else:
|
||||
askDict[LastPrice] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if LastPrice in bidDict.keys():
|
||||
bidDict[LastPrice] += Volume
|
||||
else:
|
||||
bidDict[LastPrice] = Volume
|
||||
indexFinal = indexTick
|
||||
|
||||
bidDictResult,askDictResult = process(bidDict,askDict)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
# 过滤'volume'列小于等于0的行
|
||||
df = df[df['volume'] > 0]
|
||||
# 重新排序DataFrame,按照'datetime'列进行升序排序
|
||||
df = df.sort_values(by='datetime', ascending=True)
|
||||
# 重新设置索引,以便索引能够正确对齐
|
||||
df = df.reset_index(drop=True)
|
||||
#df['ticktime']=tTickArray[indexTick]
|
||||
df['dj']=GetOrderFlow_dj(df)
|
||||
#print(df)
|
||||
df_of = pd.concat([df_of, df], ignore_index=True)
|
||||
print(time.time() - t1)
|
||||
return df_of
|
||||
|
||||
def GetOrderFlow_dj(kData):
|
||||
itemAskBG=['rgb(0,255,255)', 'rgb(255,0,255)', "rgb(255,182,193)"] # 买盘背景色
|
||||
itemBidBG=['rgb(173,255,47)', 'rgb(255,127,80)', "rgb(32,178,170)"] # 卖盘背景色
|
||||
Config={
|
||||
'Value1':3,
|
||||
'Value2':3,
|
||||
'Value3':3,
|
||||
'Value4':True,
|
||||
}
|
||||
aryData=kData
|
||||
djcout=0
|
||||
for index,row in aryData.iterrows():
|
||||
kItem=aryData.iloc[index]
|
||||
high=kItem['high']
|
||||
low=kItem['low']
|
||||
close=kItem['close']
|
||||
open=kItem['open']
|
||||
dtime=kItem['datetime']
|
||||
price_s=kItem['price']
|
||||
Ask_s=kItem['Ask']
|
||||
Bid_s=kItem['Bid']
|
||||
delta=kItem['delta']
|
||||
|
||||
price_s=price_s
|
||||
Ask_s=Ask_s
|
||||
Bid_s=Bid_s
|
||||
|
||||
gj=0
|
||||
xq=0
|
||||
gxx=0
|
||||
xxx=0
|
||||
for i in np.arange (0, len(price_s),1) :
|
||||
duiji={
|
||||
'price':0,
|
||||
'time':0,
|
||||
'longshort':0,
|
||||
'cout':0,
|
||||
'color':'blue'
|
||||
}
|
||||
if i==0 :
|
||||
delta=delta
|
||||
|
||||
order= {
|
||||
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
if i>=0 and i<len(price_s)-1:
|
||||
if (order["Bid"]["Value"]>Ask_s[i+1]*int(Config['Value1'])):
|
||||
order["Bid"]["Color"]=itemAskBG[1]
|
||||
gxx+=1
|
||||
gj+=1
|
||||
if gj>=int(Config['Value2']) and Config['Value4']==True:
|
||||
duiji['price']=price_s[i]
|
||||
duiji['time']=dtime
|
||||
duiji['longshort']=-1
|
||||
duiji['cout']=gj
|
||||
duiji['color']='rgba(0,139,0,0.45)'#绿色
|
||||
if float(duiji['price'])>0:
|
||||
djcout+=-1
|
||||
else :
|
||||
gj=0
|
||||
if i>=1 and i<len(price_s)-1:
|
||||
if (order["Ask"]["Value"]>Bid_s[i-1]*int(Config['Value1'])):
|
||||
xq+=1
|
||||
xxx+=1
|
||||
order["Ask"]["Color"]=itemBidBG[1]
|
||||
if xq>=int(Config['Value2']) and Config['Value4']==True:
|
||||
duiji['price']=price_s[i]
|
||||
duiji['time']=dtime
|
||||
duiji['longshort']=1
|
||||
duiji['cout']=xq
|
||||
duiji['color']='rgba(255,0,0,0.45)' #红色
|
||||
if float(duiji['price'])>0:
|
||||
djcout+=1
|
||||
else :
|
||||
xq=0
|
||||
return djcout
|
||||
|
||||
def back_data(df):
|
||||
# 创建新的DataFrame并填充需要的列
|
||||
new_df = pd.DataFrame()
|
||||
new_df['datetime'] = pd.to_datetime(df['datetime'], format='%Y/%m/%d %H:%M')
|
||||
new_df['close'] = df['close']
|
||||
new_df['open'] = df['open']
|
||||
new_df['high'] = df['high']
|
||||
new_df['low'] = df['low']
|
||||
new_df['volume'] = df['volume']
|
||||
new_df['sig'] = df['dj']
|
||||
new_df['symbol'] = df['symbol']
|
||||
new_df['delta'] = df['delta']
|
||||
new_df.to_csv(f'./tick生成的OF数据/back_ofdata_dj.csv',index=False)
|
||||
#new_df.to_csv(f'{sym}back_ofdata_dj.csv',index=False)
|
||||
|
||||
if __name__ == "__main__":
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
data=pd.read_csv('rb主力连续_20230103.csv',encoding='GBK',parse_dates=['业务日期','最后修改时间']) #
|
||||
print(data)
|
||||
tick,bar=dataload(data)
|
||||
ofdata = orderflow_df_new(tick,bar)
|
||||
print(ofdata)
|
||||
#保存orderflow数据
|
||||
# os.mkdir('./tick生成的OF数据'),或者在to_csv中修改生成的文件名
|
||||
folder_path = "tick生成的OF数据"
|
||||
if not os.path.exists(folder_path):
|
||||
os.mkdir('tick生成的OF数据')
|
||||
ofdata.to_csv('./tick生成的OF数据/ofdata_dj.csv')
|
||||
#保存回测数据
|
||||
back_data(ofdata)
|
||||
print('done')
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 54,
|
||||
"id": "30ee221d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 55,
|
||||
"id": "c826c49d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.read_csv('E:/data/ag/tick生成的OF数据/back_ofdata_dj.csv')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 56,
|
||||
"id": "887ba88c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"delta_values = df['delta'].abs()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 64,
|
||||
"id": "a662ed7c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 计算正数部分的百分位数、中位数和标准差\n",
|
||||
"percentile = delta_values.quantile(0.70)\n",
|
||||
"median = delta_values.median()\n",
|
||||
"std = delta_values.std()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 65,
|
||||
"id": "69d1e7cb",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"全部数据绝对值的百分位:740.0\n",
|
||||
"全部数据绝对值的中位数:426.0\n",
|
||||
"全部数据绝对值的标准差:722.8068551884389\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 打印相关结果\n",
|
||||
"print(f\"全部数据绝对值的百分位:{percentile}\")\n",
|
||||
"print(f\"全部数据绝对值的中位数:{median}\")\n",
|
||||
"print(f\"全部数据绝对值的标准差:{std}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 59,
|
||||
"id": "979f66c9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# positive_values = [x for x in delta_values if x > 0]\n",
|
||||
"# negative_values = [x for x in delta_values if x < 0]\n",
|
||||
"positive_values = df['delta'][df['delta'] > 0]\n",
|
||||
"negative_values = df['delta'][df['delta'] < 0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 60,
|
||||
"id": "3f0334e8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 计算正数部分的百分位数、中位数和标准差\n",
|
||||
"positive_percentile = positive_values.quantile(0.70)\n",
|
||||
"positive_median = positive_values.median()\n",
|
||||
"positive_std = positive_values.std()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 62,
|
||||
"id": "9daebce5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 计算负数部分的百分位数、中位数和标准差\n",
|
||||
"negative_percentile = negative_values.quantile(0.70)\n",
|
||||
"negative_median = negative_values.median()\n",
|
||||
"negative_std = negative_values.std()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 63,
|
||||
"id": "0406696f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"正数的百分位:1014.8000000000011\n",
|
||||
"正数的中位数:432.0\n",
|
||||
"正数的标准差:708.9579385007327\n",
|
||||
"负数的百分位:-998.0\n",
|
||||
"负数的中位数:-421.0\n",
|
||||
"负数的标准差:736.3260520762277\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 打印相关结果\n",
|
||||
"print(f\"正数的百分位:{positive_percentile}\")\n",
|
||||
"print(f\"正数的中位数:{positive_median}\")\n",
|
||||
"print(f\"正数的标准差:{positive_std}\")\n",
|
||||
"\n",
|
||||
"print(f\"负数的百分位:{negative_percentile}\")\n",
|
||||
"print(f\"负数的中位数:{negative_median}\")\n",
|
||||
"print(f\"负数的标准差:{negative_std}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bd9ed5a7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# positive_values.tail()\n",
|
||||
"# negative_values.tail()\n",
|
||||
"# pos_qua_nums = positive_values.iloc[-120:-1].quantile(0.95)\n",
|
||||
"# print(pos_qua_nums)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "39fe34e9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['delta_cumsum'] = df['delta'].cumsum()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ea2ad82f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['delta'].head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f71b1dc3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['delta_cumsum'].head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "29cf2703",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"delta_cumsum_values = df['delta_cumsum']#.abs()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7f8ff173",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 计算和值的正数部分的百分位数、中位数和标准差\n",
|
||||
"cumsum_percentile = delta_cumsum_values.quantile(0.95)\n",
|
||||
"cumsum_median = delta_cumsum_values.median()\n",
|
||||
"cumsum_std = delta_cumsum_values.std()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c2c57b8a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 打印相关结果\n",
|
||||
"print(f\"和值的全部数据绝对值的百分位:{cumsum_percentile}\")\n",
|
||||
"print(f\"和值的全部数据绝对值的中位数:{cumsum_median}\")\n",
|
||||
"print(f\"和值的全部数据绝对值的标准差:{cumsum_std}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "82860da9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"positive_cumsum_values = df['delta_cumsum'][df['delta_cumsum'] > 0]\n",
|
||||
"negative_cumsum_values = df['delta_cumsum'][df['delta_cumsum'] < 0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "56f9f922",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"positive_cumsum_values.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b8dcab86",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"negative_cumsum_values.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "db782086",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 计算正数部分的百分位数、中位数和标准差\n",
|
||||
"positive_cumsum_percentile = positive_cumsum_values.quantile(0.7)\n",
|
||||
"positive_cumsum_median = positive_cumsum_values.median()\n",
|
||||
"positive_cumsum_std = positive_cumsum_values.std()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2430d9b7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 计算负数部分的百分位数、中位数和标准差\n",
|
||||
"negative_cumsum_percentile = negative_cumsum_values.quantile(0.7)\n",
|
||||
"negative_cumsum_median = negative_cumsum_values.median()\n",
|
||||
"negative_cumsum_std = negative_cumsum_values.std()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "698948f6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 打印相关结果\n",
|
||||
"print(f\"和值的正数百分位:{positive_cumsum_percentile}\")\n",
|
||||
"print(f\"和值的正的中位数:{positive_cumsum_median}\")\n",
|
||||
"print(f\"和值的正数标准差:{positive_cumsum_std}\")\n",
|
||||
"\n",
|
||||
"print(f\"和值的负数百分位:{negative_cumsum_percentile}\")\n",
|
||||
"print(f\"和值的负数中位数:{negative_cumsum_median}\")\n",
|
||||
"print(f\"和值的负数标准差:{negative_cumsum_std}\")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,892 @@
|
||||
'''
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
该代码的主要目的是处理Tick数据并生成交易信号。代码中定义了一个tickcome函数,它接收到Tick数据后会进行一系列的处理,包括构建Tick字典、更新上一个Tick的成交量、保存Tick数据、生成K线数据等。其中涉及到的一些函数有:
|
||||
|
||||
on_tick(tick): 处理单个Tick数据,根据Tick数据生成K线数据。
|
||||
tickdata(df, symbol): 处理Tick数据,生成K线数据。
|
||||
orderflow_df_new(df_tick, df_min, symbol): 处理Tick和K线数据,生成订单流数据。
|
||||
GetOrderFlow_dj(kData): 计算订单流的信号指标。
|
||||
除此之外,代码中还定义了一个MyTrader类,继承自TraderApiBase,用于实现交易相关的功能。
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
'''
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from multiprocessing import Process, Queue
|
||||
import queue
|
||||
import threading
|
||||
from AlgoPlus.CTP.MdApi import run_tick_engine
|
||||
from AlgoPlus.CTP.FutureAccount import get_simulate_account
|
||||
from AlgoPlus.CTP.FutureAccount import FutureAccount
|
||||
from AlgoPlus.CTP.TraderApiBase import TraderApiBase
|
||||
from AlgoPlus.ta.time_bar import tick_to_bar
|
||||
import pandas as pd
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import time as s_time
|
||||
import operator
|
||||
import time
|
||||
import numpy as np
|
||||
import os
|
||||
import re
|
||||
|
||||
# 加入邮件通知
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText # 导入 MIMEText 类发送纯文本邮件
|
||||
from email.mime.multipart import MIMEMultipart # 导入 MIMEMultipart 类发送带有附件的邮件
|
||||
from email.mime.application import MIMEApplication # 导入 MIMEApplication 类发送二进制附件
|
||||
|
||||
## 配置邮件信息
|
||||
receivers = ["240884432@qq.com"] # 设置邮件接收人地址
|
||||
subject = "订单流策略交易信号" # 设置邮件主题
|
||||
#text = " " # 设置邮件正文
|
||||
# file_path = "test.txt" # 设置邮件附件文件路径
|
||||
|
||||
## 配置邮件服务器信息
|
||||
smtp_server = "smtp.qq.com" # 设置发送邮件的 SMTP 服务器地址
|
||||
smtp_port = 465 # 设置发送邮件的 SMTP 服务器端口号,一般为 25 端口 465
|
||||
sender = "240884432@qq.com" # 设置发送邮件的邮箱地址
|
||||
username = "240884432@qq.com" # 设置发送邮件的邮箱用户名
|
||||
password = "ifjgwlnzdvrfbjgf" #zrmpcgttataabhjh,设置发送邮件的邮箱密码或授权码
|
||||
|
||||
tickdatadict = {} # 存储Tick数据的字典
|
||||
quotedict = {} # 存储行情数据的字典
|
||||
ofdatadict = {} # 存储K线数据的字典
|
||||
trade_dfs = {} #pd.DataFrame({}) # 存储交易数据的DataFrame对象
|
||||
previous_volume = {} # 上一个Tick的成交量
|
||||
tsymbollist={}
|
||||
|
||||
clearing_time_dict = {'sc': s_time(2,30), 'bc': s_time(1,0), 'lu': s_time(23,0), 'nr': s_time(23,0),'au': s_time(2,30), 'ag': s_time(2,30),
|
||||
'ss': s_time(1,0), 'sn': s_time(1,0), 'ni': s_time(1,0), 'pb': s_time(1,0),'zn': s_time(1,0), 'al': s_time(1,0), 'cu': s_time(1,0),
|
||||
'ru': s_time(23,0), 'rb': s_time(23,0), 'hc': s_time(23,0), 'fu': s_time(23,0), 'bu': s_time(23,0), 'sp': s_time(23,0),
|
||||
'PF': s_time(23,0), 'SR': s_time(23,0), 'CF': s_time(23,0), 'CY': s_time(23,0), 'RM': s_time(23,0), 'MA': s_time(23,0),
|
||||
'TA': s_time(23,0), 'ZC': s_time(23,0), 'FG': s_time(23,0), 'OI': s_time(23,0), 'SA': s_time(23,0),
|
||||
'p': s_time(23,0), 'j': s_time(23,0), 'jm': s_time(23,0), 'i': s_time(23,0), 'l': s_time(23,0), 'v': s_time(23,0),
|
||||
'pp': s_time(23,0), 'eg': s_time(23,0), 'c': s_time(23,0), 'cs': s_time(23,0), 'y': s_time(23,0), 'm': s_time(23,0),
|
||||
'a': s_time(23,0), 'b': s_time(23,0), 'rr': s_time(23,0), 'eb': s_time(23,0), 'pg': s_time(23,0)}
|
||||
|
||||
|
||||
def send_mail(text):
|
||||
msg = MIMEMultipart()
|
||||
msg["From"] = sender
|
||||
msg["To"] = ";".join(receivers)
|
||||
msg["Subject"] = subject
|
||||
msg.attach(MIMEText(text, "plain", "utf-8"))
|
||||
smtp = smtplib.SMTP_SSL(smtp_server, smtp_port)
|
||||
smtp.login(username, password)
|
||||
smtp.sendmail(sender, receivers, msg.as_string())
|
||||
smtp.quit()
|
||||
|
||||
#交易程序---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
class ParamObj:
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
symbol = None #合约名称
|
||||
Lots = None #下单手数
|
||||
py = None #设置委托价格的偏移,更加容易促成成交
|
||||
trailing_stop_percent = None #跟踪出场参数
|
||||
fixed_stop_loss_percent = None #固定出场参数
|
||||
dj_X = None #开仓的堆积参数
|
||||
delta = None #开仓的delta参数
|
||||
sum_delta = None #开仓的delta累积参数
|
||||
失衡=None
|
||||
堆积=None
|
||||
周期=None
|
||||
|
||||
# 策略需要用到的变量
|
||||
cont_df = 0
|
||||
pos = 0
|
||||
short_trailing_stop_price = 0
|
||||
long_trailing_stop_price = 0
|
||||
sl_long_price = 0
|
||||
sl_shor_price = 0
|
||||
out_long = 0
|
||||
out_short = 0
|
||||
clearing_executed = False
|
||||
kgdata = True
|
||||
|
||||
def __init__(self, symbol, Lots, py, trailing_stop_percent, fixed_stop_loss_percent, dj_X, delta, sum_delta,失衡,堆积,周期):
|
||||
self.symbol = symbol
|
||||
self.Lots = Lots
|
||||
self.py = py
|
||||
self.trailing_stop_percent = trailing_stop_percent
|
||||
self.fixed_stop_loss_percent = fixed_stop_loss_percent
|
||||
self.dj_X = dj_X
|
||||
self.delta = delta
|
||||
self.sum_delta = sum_delta
|
||||
self.失衡=失衡
|
||||
self.堆积=堆积
|
||||
self.周期=周期
|
||||
|
||||
|
||||
class MyTrader(TraderApiBase):
|
||||
def __init__(self, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
self.param_dict = {}
|
||||
self.queue_dict = {}
|
||||
self.品种=' '
|
||||
|
||||
|
||||
|
||||
# 邮件通知模块
|
||||
|
||||
|
||||
def tickcome(self,md_queue):
|
||||
global previous_volume
|
||||
data=md_queue
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
ActionDay = data['ActionDay'].decode() # 交易日日期
|
||||
update_time = data['UpdateTime'].decode() # 更新时间
|
||||
|
||||
update_millisec = str(data['UpdateMillisec']) # 更新毫秒数
|
||||
created_at = ActionDay[:4] + '-' + ActionDay[4:6] + '-' + ActionDay[6:] + ' ' + update_time + '.' + update_millisec #创建时间
|
||||
# 构建tick字典
|
||||
tick = {
|
||||
'symbol': instrument_id, # 品种代码和交易所ID
|
||||
'created_at':datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S.%f"),
|
||||
#'created_at': created_at, # 创建时间
|
||||
'price': float(data['LastPrice']), # 最新价
|
||||
'last_volume': int(data['Volume']) - previous_volume.get(instrument_id, 0) if previous_volume.get(instrument_id, 0) != 0 else 0, # 瞬时成交量
|
||||
'bid_p': float(data['BidPrice1']), # 买价
|
||||
'bid_v': int(data['BidVolume1']), # 买量
|
||||
'ask_p': float(data['AskPrice1']), # 卖价
|
||||
'ask_v': int(data['AskVolume1']), # 卖量
|
||||
'UpperLimitPrice': float(data['UpperLimitPrice']), # 涨停价
|
||||
'LowerLimitPrice': float(data['LowerLimitPrice']), # 跌停价
|
||||
'TradingDay': data['TradingDay'].decode(), # 交易日日期
|
||||
'cum_volume': int(data['Volume']), # 最新总成交量
|
||||
'cum_amount': float(data['Turnover']), # 最新总成交额
|
||||
'cum_position': int(data['OpenInterest']), # 合约持仓量
|
||||
}
|
||||
# print('&&&&&&&&',instrument_id, tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 更新上一个Tick的成交量
|
||||
previous_volume[instrument_id] = int(data['Volume'])
|
||||
if tick['last_volume']>0:
|
||||
#print(tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 处理Tick数据
|
||||
self.on_tick(tick)
|
||||
|
||||
def can_time(self,hour, minute):
|
||||
hour = str(hour)
|
||||
minute = str(minute)
|
||||
if len(minute) == 1:
|
||||
minute = "0" + minute
|
||||
return int(hour + minute)
|
||||
|
||||
def on_tick(self,tick):
|
||||
|
||||
tm=self.can_time(tick['created_at'].hour,tick['created_at'].minute)
|
||||
#print(tick['symbol'])
|
||||
#print(1)
|
||||
#if tm>1500 and tm<2100 :
|
||||
# return
|
||||
if tick['last_volume']==0:
|
||||
return
|
||||
quotes = tick
|
||||
timetick=str(tick['created_at']).replace('+08:00', '')
|
||||
tsymbol=tick['symbol']
|
||||
if tsymbol not in tsymbollist.keys():
|
||||
# 获取tick的买卖价和买卖量
|
||||
|
||||
tsymbollist[tsymbol]=tick
|
||||
bid_p=quotes['bid_p']
|
||||
ask_p=quotes['ask_p']
|
||||
bid_v=quotes['bid_v']
|
||||
ask_v=quotes['ask_v']
|
||||
else:
|
||||
# 获取上一个tick的买卖价和买卖量
|
||||
rquotes =tsymbollist[tsymbol]
|
||||
bid_p=rquotes['bid_p']
|
||||
ask_p=rquotes['ask_p']
|
||||
bid_v=rquotes['bid_v']
|
||||
ask_v=rquotes['ask_v']
|
||||
tsymbollist[tsymbol]=tick
|
||||
tick_dt=pd.DataFrame({'datetime':timetick,'symbol':tick['symbol'],'mainsym':tick['symbol'].rstrip('0123456789').upper(),'lastprice':tick['price'],
|
||||
'vol':tick['last_volume'],
|
||||
'bid_p':bid_p,'ask_p':ask_p,'bid_v':bid_v,'ask_v':ask_v},index=[0])
|
||||
sym = tick_dt['symbol'][0]
|
||||
#print(tick_dt)
|
||||
self.tickdata(tick_dt,sym)
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def data_of(self,symbol, df):
|
||||
global trade_dfs
|
||||
# 将df数据合并到trader_df中
|
||||
# if symbol not in trade_dfs.keys():
|
||||
# trade_df = pd.DataFrame({})
|
||||
# else:
|
||||
# trade_df = trade_dfs[symbol]
|
||||
trade_dfs[symbol] = pd.concat([trade_dfs[symbol], df], ignore_index=True)
|
||||
# print('!!!!!!!!!!!trader_df: ', symbol, df['datetime'].iloc[-1])
|
||||
#print(trader_df)
|
||||
|
||||
def process(self,bidDict, askDict, symbol):
|
||||
try:
|
||||
# 尝试从quotedict中获取对应品种的报价数据
|
||||
dic = quotedict[symbol]
|
||||
bidDictResult = dic['bidDictResult']
|
||||
askDictResult = dic['askDictResult']
|
||||
except:
|
||||
# 如果获取失败,则初始化bidDictResult和askDictResult为空字典
|
||||
bidDictResult, askDictResult = {}, {}
|
||||
|
||||
# 将所有买盘字典和卖盘字典的key合并,并按升序排序
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
|
||||
# 遍历所有的key,将相同key的值进行累加
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
if s in bidDictResult:
|
||||
bidDictResult[s] = int(bidDict[s]) + bidDictResult[s]
|
||||
else:
|
||||
bidDictResult[s] = int(bidDict[s])
|
||||
if s not in askDictResult:
|
||||
askDictResult[s] = 0
|
||||
else:
|
||||
if s in askDictResult:
|
||||
askDictResult[s] = int(askDict[s]) + askDictResult[s]
|
||||
else:
|
||||
askDictResult[s] = int(askDict[s])
|
||||
if s not in bidDictResult:
|
||||
bidDictResult[s] = 0
|
||||
|
||||
# 构建包含bidDictResult和askDictResult的字典,并存入quotedict中
|
||||
df = {'bidDictResult': bidDictResult, 'askDictResult': askDictResult}
|
||||
quotedict[symbol] = df
|
||||
|
||||
return bidDictResult, askDictResult
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
|
||||
def tickdata(self,df,symbol):
|
||||
tickdata =pd.DataFrame({'datetime':df['datetime'],'symbol':df['symbol'],'lastprice':df['lastprice'],
|
||||
'volume':df['vol'],'bid_p':df['bid_p'],'bid_v':df['bid_v'],'ask_p':df['ask_p'],'ask_v':df['ask_v']})
|
||||
try:
|
||||
if symbol in tickdatadict.keys():
|
||||
rdf=tickdatadict[symbol]
|
||||
rdftm=pd.to_datetime(rdf['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
now=str(tickdata['datetime'][0])
|
||||
if now>rdftm:
|
||||
try:
|
||||
oo=ofdatadict[symbol]
|
||||
self.data_of(symbol, oo)
|
||||
#print('oo',oo)
|
||||
if symbol in quotedict.keys():
|
||||
quotedict.pop(symbol)
|
||||
if symbol in tickdatadict.keys():
|
||||
tickdatadict.pop(symbol)
|
||||
if symbol in ofdatadict.keys():
|
||||
ofdatadict.pop(symbol)
|
||||
except IOError as e:
|
||||
print('rdftm捕获到异常',e)
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
else:
|
||||
tickdata['bartime'] = rdf['bartime']
|
||||
tickdata['open'] = rdf['open']
|
||||
tickdata['high'] = max(tickdata['lastprice'].values,rdf['high'].values)
|
||||
tickdata['low'] = min(tickdata['lastprice'].values,rdf['low'].values)
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['volume']=df['vol']+rdf['volume'].values
|
||||
tickdata['starttime'] = rdf['starttime']
|
||||
else :
|
||||
print('新bar的第一个tick进入')
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
except IOError as e:
|
||||
print('捕获到异常',e)
|
||||
|
||||
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['bartime'])
|
||||
param = self.param_dict[self.品种]
|
||||
bardata = tickdata.resample(on = 'bartime',rule = param.周期,label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
bardata['bartime'] = pd.to_datetime(bardata['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
tickdatadict[symbol]=bardata
|
||||
tickdata['volume']=df['vol'].values
|
||||
#print(bardata['symbol'].values,bardata['bartime'].values)
|
||||
self.orderflow_df_new(tickdata,bardata,symbol)
|
||||
# time.sleep(0.5)
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def orderflow_df_new(self,df_tick,df_min,symbol):
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
#endArray = pd.to_datetime(df_min['bartime']).values
|
||||
endArray = df_min['bartime'].values
|
||||
#print(endArray)
|
||||
deltaArray = np.zeros((len(endArray),))
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
dt=endArray[index]
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
# for indexTick in range(indexFinal,len(df_tick)):
|
||||
# if tTickArray[indexTick] >= tEnd:
|
||||
# break
|
||||
# elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] < tEnd):
|
||||
Bp = round(bp1TickArray[0],4)
|
||||
Ap = round(ap1TickArray[0],4)
|
||||
LastPrice = round(lastTickArray[0],4)
|
||||
Volume = volumeTickArray[0]
|
||||
if LastPrice >= Ap:
|
||||
if str(LastPrice) in askDict.keys():
|
||||
askDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
askDict[str(LastPrice)] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if str(LastPrice) in bidDict.keys():
|
||||
bidDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
bidDict[str(LastPrice)] = Volume
|
||||
# indexFinal = indexTick
|
||||
bidDictResult,askDictResult = self.process(bidDict,askDict,symbol)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
#print(prinslist,asklist,bidlist)
|
||||
#print(len(prinslist),len(bidDictResult),len(askDictResult))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
#df=pd.DataFrame({'price':pd.Series(bidDictResult.keys()),'Ask':pd.Series(askDictResult.values()),'Bid':pd.Series(bidDictResult.values())})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
#df['ticktime']=tTickArray[0]
|
||||
df['dj'] = self.GetOrderFlow_dj(df)
|
||||
ofdatadict[symbol]=df
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def GetOrderFlow_dj(self,kData):
|
||||
param = self.param_dict[self.品种]
|
||||
Config = {
|
||||
'Value1': param.失衡,
|
||||
'Value2': param.堆积,
|
||||
'Value4': True,
|
||||
}
|
||||
aryData = kData
|
||||
djcout = 0
|
||||
|
||||
# 遍历kData中的每一行,计算djcout指标
|
||||
for index, row in aryData.iterrows():
|
||||
kItem = aryData.iloc[index]
|
||||
high = kItem['high']
|
||||
low = kItem['low']
|
||||
close = kItem['close']
|
||||
open = kItem['open']
|
||||
dtime = kItem['datetime']
|
||||
price_s = kItem['price']
|
||||
Ask_s = kItem['Ask']
|
||||
Bid_s = kItem['Bid']
|
||||
delta = kItem['delta']
|
||||
|
||||
price_s = price_s
|
||||
Ask_s = Ask_s
|
||||
Bid_s = Bid_s
|
||||
|
||||
gj = 0
|
||||
xq = 0
|
||||
gxx = 0
|
||||
xxx = 0
|
||||
|
||||
# 遍历price_s中的每一个元素,计算相关指标
|
||||
for i in np.arange(0, len(price_s), 1):
|
||||
duiji = {
|
||||
'price': 0,
|
||||
'time': 0,
|
||||
'longshort': 0,
|
||||
}
|
||||
|
||||
if i == 0:
|
||||
delta = delta
|
||||
|
||||
order= {
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
#空头堆积
|
||||
if i >= 0 and i < len(price_s) - 1:
|
||||
if (order["Bid"]["Value"] > Ask_s[i + 1] * int(Config['Value1'])):
|
||||
gxx += 1
|
||||
gj += 1
|
||||
if gj >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = -1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += -1
|
||||
else:
|
||||
gj = 0
|
||||
#多头堆积
|
||||
if i >= 1 and i < len(price_s) - 1:
|
||||
if (order["Ask"]["Value"] > Bid_s[i - 1] * int(Config['Value1'])):
|
||||
xq += 1
|
||||
xxx += 1
|
||||
if xq >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = 1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += 1
|
||||
else:
|
||||
xq = 0
|
||||
|
||||
# 返回计算得到的djcout值
|
||||
return djcout
|
||||
|
||||
#读取保存的数据
|
||||
def read_to_csv(self,symbol):
|
||||
# 文件夹路径和文件路径
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
param = self.param_dict[symbol]
|
||||
# symbol = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
folder_path = "traderdata"
|
||||
file_path = os.path.join(folder_path, f"{str(symbol)}_traderdata.csv")
|
||||
# 如果文件夹不存在则创建
|
||||
if not os.path.exists(folder_path):
|
||||
os.makedirs(folder_path)
|
||||
|
||||
# 读取保留的模型数据CSV文件
|
||||
if os.path.exists(file_path):
|
||||
df = pd.read_csv(file_path)
|
||||
if not df.empty and param.kgdata==True:
|
||||
# 选择最后一行数据
|
||||
row = df.iloc[-1]
|
||||
|
||||
# 根据CSV文件的列名将数据赋值给相应的属性
|
||||
param.pos = int(row['pos'])
|
||||
param.short_trailing_stop_price = float(row['short_trailing_stop_price'])
|
||||
param.long_trailing_stop_price = float(row['long_trailing_stop_price'])
|
||||
param.sl_long_price = float(row['sl_long_price'])
|
||||
param.sl_shor_price = float(row['sl_shor_price'])
|
||||
# param.out_long = int(row['out_long'])
|
||||
# param.out_short = int(row['out_short'])
|
||||
print("找到历史交易数据文件,已经更新持仓,止损止盈数据", df.iloc[-1])
|
||||
param.kgdata=False
|
||||
else:
|
||||
pass
|
||||
#print("没有找到历史交易数据文件", file_path)
|
||||
#如果没有找到CSV,则初始化变量
|
||||
|
||||
pass
|
||||
|
||||
#保存数据
|
||||
def save_to_csv(self,symbol):
|
||||
param = self.param_dict[symbol]
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
# symbol = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
# 创建DataFrame
|
||||
|
||||
data = {
|
||||
'datetime': [trade_dfs[symbol]['datetime'].iloc[-1]],
|
||||
'pos': [param.pos],
|
||||
'short_trailing_stop_price': [param.short_trailing_stop_price],
|
||||
'long_trailing_stop_price': [param.long_trailing_stop_price],
|
||||
'sl_long_price': [param.sl_long_price],
|
||||
'sl_shor_price': [param.sl_shor_price],
|
||||
# 'out_long': [param.out_long],
|
||||
# 'out_short': [param.out_short]
|
||||
}
|
||||
|
||||
df = pd.DataFrame(data)
|
||||
|
||||
# 将DataFrame保存到CSV文件
|
||||
df.to_csv(f"traderdata/{str(symbol)}_traderdata.csv", index=False)
|
||||
|
||||
#每日收盘重置数据
|
||||
def day_data_reset(self, symbol):
|
||||
param = self.param_dict[symbol]
|
||||
sec = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
# 获取当前时间
|
||||
current_time = datetime.now().time()
|
||||
|
||||
# 第一时间范围(日盘收盘)
|
||||
clearing_time1_start = s_time(15,00)
|
||||
clearing_time1_end = s_time(15,15)
|
||||
|
||||
# 创建一个标志变量,用于记录是否已经执行过
|
||||
param.clearing_executed = False
|
||||
# 检查当前时间第一个操作的时间范围内
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not param.clearing_executed :
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
trade_dfs[symbol].drop(trade_dfs[symbol].index,inplace=True)#清除当天的行情数据
|
||||
|
||||
# 检查当前时间是否在第二个操作的时间范围内(夜盘收盘)
|
||||
elif sec in clearing_time_dict.keys():
|
||||
clearing_time2_start = clearing_time_dict[sec]
|
||||
clearing_time2_end = s_time(clearing_time2_start.hour, clearing_time2_start.minute+15)
|
||||
if clearing_time2_start <= current_time <= clearing_time2_end and not param.clearing_executed :
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
trade_dfs[symbol].drop(trade_dfs[symbol].index,inplace=True) #清除当天的行情数据
|
||||
else:
|
||||
param.clearing_executed = False
|
||||
pass
|
||||
return param.clearing_executed
|
||||
|
||||
def OnRtnTrade(self, pTrade):
|
||||
print("||成交回报||", pTrade)
|
||||
|
||||
def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast):
|
||||
print("||OnRspOrderInsert||", pInputOrder, pRspInfo, nRequestID, bIsLast)
|
||||
|
||||
# 订单状态通知
|
||||
def OnRtnOrder(self, pOrder):
|
||||
print("||订单回报||", pOrder)
|
||||
|
||||
def cal_sig(self, symbol_queue):
|
||||
while True:
|
||||
try:
|
||||
data = symbol_queue.get(block=True, timeout=5) # 如果5秒没收到新的tick行情,则抛出异常
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
size = symbol_queue.qsize()
|
||||
if size > 1:
|
||||
print(f'当前{instrument_id}共享队列长度为{size}, 有点阻塞!!!!!')
|
||||
self.read_to_csv(instrument_id)
|
||||
self.day_data_reset(instrument_id)
|
||||
param = self.param_dict[instrument_id]
|
||||
self.品种=instrument_id
|
||||
self.tickcome(data)
|
||||
trade_df = trade_dfs[instrument_id]
|
||||
#新K线开始,启动交易程序 and 保存行情数据
|
||||
self.read_to_csv(instrument_id)
|
||||
# size = symbol_queue.qsize()
|
||||
# if size > 2:
|
||||
# print(f'!!!!!当前{instrument_id}共享队列长度为:',size)
|
||||
if len(trade_df)>param.cont_df:
|
||||
# 检查文件是否存在
|
||||
csv_file_path = f"traderdata/{instrument_id}_ofdata.csv"
|
||||
if os.path.exists(csv_file_path):
|
||||
# 仅保存最后一行数据
|
||||
trade_df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
else:
|
||||
# 创建新文件并保存整个DataFrame
|
||||
trade_df.to_csv(csv_file_path, index=False)
|
||||
|
||||
# 更新跟踪止损价格
|
||||
if param.long_trailing_stop_price >0 and param.pos>0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧多头出线',param.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
param.long_trailing_stop_price = trade_df['low'].iloc[-1] if param.long_trailing_stop_price<trade_df['low'].iloc[-1] else param.long_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#print('datetime+sig: ',dt,'多头出线',param.long_trailing_stop_price)
|
||||
if param.short_trailing_stop_price >0 and param.pos<0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧空头出线',param.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
param.short_trailing_stop_price = trade_df['high'].iloc[-1] if trade_df['high'].iloc[-1] <param.short_trailing_stop_price else param.short_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#print('datetime+sig: ',dt,'空头出线',param.short_trailing_stop_price)
|
||||
|
||||
param.out_long=param.long_trailing_stop_price * (1 - param.trailing_stop_percent)
|
||||
param.out_short=param.short_trailing_stop_price*(1 + param.trailing_stop_percent)
|
||||
#print('datetime+sig: ',dt,'空头出线',param.out_short)
|
||||
#print('datetime+sig: ',dt,'多头出线',param.out_long)
|
||||
# 跟踪出场
|
||||
if param.out_long >0:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'预设——多头止盈——','TR',param.out_long,'low', trade_df['low'].iloc[-1])
|
||||
if trade_df['low'].iloc[-1] < param.out_long and param.pos>0 and param.sl_long_price>0 and trade_df['low'].iloc[-1]>param.sl_long_price:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'多头止盈','TR',param.out_long,'low', trade_df['low'].iloc[-1])
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.long_trailing_stop_price = 0
|
||||
param.out_long=0
|
||||
param.sl_long_price=0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
if param.out_short>0:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'预设——空头止盈——: ','TR',param.out_short,'high', trade_df['high'].iloc[-1])
|
||||
if trade_df['high'].iloc[-1] > param.out_short and param.pos<0 and param.sl_shor_price>0 and trade_df['high'].iloc[-1]<param.sl_shor_price:
|
||||
print('datetime+sig: ',trade_df['datetime'].iloc[-1],'空头止盈: ','TR',param.out_short,'high', trade_df['high'].iloc[-1])
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.short_trailing_stop_price = 0
|
||||
param.sl_shor_price=0
|
||||
self.out_shor=0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 固定止损
|
||||
fixed_stop_loss_L = param.sl_long_price * (1 - param.fixed_stop_loss_percent)
|
||||
if param.pos>0:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '预设——多头止损', 'SL', fixed_stop_loss_L, 'close', trade_df['close'].iloc[-1])
|
||||
if param.sl_long_price>0 and fixed_stop_loss_L>0 and param.pos > 0 and trade_df['close'].iloc[-1] < fixed_stop_loss_L:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '多头止损', 'SL', fixed_stop_loss_L, 'close', trade_df['close'].iloc[-1])
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.long_trailing_stop_price = 0
|
||||
param.sl_long_price=0
|
||||
param.out_long = 0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
fixed_stop_loss_S = param.sl_shor_price * (1 + param.fixed_stop_loss_percent)
|
||||
if param.pos<0:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '预设——空头止损', 'SL', fixed_stop_loss_S, 'close', trade_df['close'].iloc[-1])
|
||||
if param.sl_shor_price>0 and fixed_stop_loss_S>0 and param.pos < 0 and trade_df['close'].iloc[-1] > fixed_stop_loss_S:
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '空头止损', 'SL', fixed_stop_loss_S, 'close', trade_df['close'].iloc[-1])
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.short_trailing_stop_price = 0
|
||||
param.sl_shor_price=0
|
||||
param.out_short = 0
|
||||
param.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#日均线
|
||||
trade_df['dayma']=trade_df['close'].mean()
|
||||
|
||||
# 计算累积的delta值
|
||||
trade_df['delta'] = trade_df['delta'].astype(float)
|
||||
trade_df['delta累计'] = trade_df['delta'].cumsum()
|
||||
|
||||
#大于日均线
|
||||
开多1=trade_df['dayma'].iloc[-1] > 0 and trade_df['close'].iloc[-1] > trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量大于X
|
||||
开多4=trade_df['delta累计'].iloc[-1] > param.sum_delta and trade_df['delta'].iloc[-1] > param.delta
|
||||
|
||||
#小于日均线
|
||||
开空1=trade_df['dayma'].iloc[-1]>0 and trade_df['close'].iloc[-1] < trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量小于X
|
||||
开空4=trade_df['delta累计'].iloc[-1] < -param.sum_delta and trade_df['delta'].iloc[-1] < -param.delta
|
||||
开多组合= 开多1 and 开多4 and trade_df['dj'].iloc[-1]>param.dj_X
|
||||
开空条件= 开空1 and 开空4 and trade_df['dj'].iloc[-1]<-param.dj_X
|
||||
|
||||
平多条件=trade_df['dj'].iloc[-1]<-param.dj_X
|
||||
平空条件=trade_df['dj'].iloc[-1]>param.dj_X
|
||||
#开仓
|
||||
#多头开仓条件
|
||||
if param.pos<0 and 平空条件 :
|
||||
print('平空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+param.py)
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
param.sl_shor_price=0
|
||||
param.short_trailing_stop_price=0
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '反手平空:', '平仓价格:', data['AskPrice1']+param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 发送邮件
|
||||
text = f"平空交易: 交易品种为{data['InstrumentID']}, 交易时间为{trade_df['datetime'].iloc[-1]}, 反手平空的平仓价格为{data['AskPrice1']+param.py}, 交易手数位{param.Lots}"
|
||||
send_mail(text)
|
||||
|
||||
if param.pos==0 and 开多组合:
|
||||
print('开多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+param.py)
|
||||
#开多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'0')
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '多头开仓', '开仓价格:', data['AskPrice1']+param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
param.pos=1
|
||||
param.long_trailing_stop_price=data['AskPrice1']
|
||||
param.sl_long_price=data['AskPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 发送邮件
|
||||
text = f"开多交易: 交易品种为{data['InstrumentID']}, 交易时间为{trade_df['datetime'].iloc[-1]}, 多头开仓的开仓价格{data['AskPrice1']+param.py}, 交易手数位{param.Lots}"
|
||||
send_mail(text)
|
||||
|
||||
if param.pos>0 and 平多条件 :
|
||||
print('平多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1']-param.py)
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
param.long_trailing_stop_price=0
|
||||
param.sl_long_price=0
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '反手平多', '平仓价格:', data['BidPrice1']-param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#发送邮件
|
||||
text = f"平多交易: 交易品种为{data['InstrumentID']}, 交易时间为{trade_df['datetime'].iloc[-1]}, 反手平多的平仓价格{data['BidPrice1']-param.py}, 交易手数位{param.Lots}"
|
||||
send_mail(text)
|
||||
|
||||
if param.pos==0 and 开空条件 :
|
||||
print('开空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1'])
|
||||
#开空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'0')
|
||||
print('datetime+sig: ', trade_df['datetime'].iloc[-1], '空头开仓', '开仓价格:', data['BidPrice1']-param.py,'堆积数:', trade_df['dj'].iloc[-1])
|
||||
param.pos=-1
|
||||
param.short_trailing_stop_price=data['BidPrice1']
|
||||
param.sl_shor_price=data['BidPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 发送邮件
|
||||
text = f"开空交易: 交易品种为{data['InstrumentID']}, 交易时间为{trade_df['datetime'].iloc[-1]}, 空头开仓的开仓价格{data['BidPrice1']-param.py}, 交易手数位{param.Lots}"
|
||||
send_mail(text)
|
||||
|
||||
print(trade_df)
|
||||
param.cont_df=len(trade_df)
|
||||
except queue.Empty:
|
||||
# print(f"当前合约队列为空,等待新数据插入。")
|
||||
pass
|
||||
|
||||
# 将CTP推送的行情数据分发给对应线程队列去执行
|
||||
def distribute_tick(self):
|
||||
while True:
|
||||
if self.status == 0:
|
||||
data = None
|
||||
while not self.md_queue.empty():
|
||||
data = self.md_queue.get(block=False)
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
try:
|
||||
self.queue_dict[instrument_id].put(data, block=False) # 往对应合约队列中插入行情
|
||||
# print(f"{instrument_id}合约数据插入。")
|
||||
except queue.Full:
|
||||
# 当某个线程阻塞导致对应队列容量超限时抛出异常,不会影响其他合约的信号计算
|
||||
print(f"{instrument_id}合约信号计算阻塞导致对应队列已满,请检查对应代码逻辑后重启。")
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
def start(self, param_dict):
|
||||
threads = []
|
||||
self.param_dict = param_dict
|
||||
for symbol in param_dict.keys():
|
||||
trade_dfs[symbol] = pd.DataFrame({})
|
||||
self.queue_dict[symbol] = queue.Queue(20) #为每个合约创建一个限制数为10的队列,当计算发生阻塞导致队列达到限制数时会抛出异常
|
||||
t = threading.Thread(target=self.cal_sig, args=(self.queue_dict[symbol],)) # 为每个合约单独创建一个线程计算开仓逻辑
|
||||
threads.append(t)
|
||||
t.start()
|
||||
self.distribute_tick()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
def run_trader(param_dict, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
my_trader = MyTrader(broker_id, td_server, investor_id, password, app_id, auth_code, md_queue, page_dir, private_resume_type, public_resume_type)
|
||||
my_trader.start(param_dict)
|
||||
|
||||
if __name__ == '__main__':
|
||||
#global symbol
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
#注意:运行前请先安装好algoplus,
|
||||
# pip install AlgoPlus
|
||||
#http://www.algo.plus/ctp/python/0103001.html
|
||||
|
||||
# 实盘参数字典,需要实盘交易的合约,新建对应的参数对象即可,以下参数仅供测试使用,不作为实盘参考!!!!
|
||||
# 实盘参数字典,需要实盘交易的合约,新建对应的参数对象即可,以下参数仅供测试使用,不作为实盘参考!!!!
|
||||
# 实盘参数字典,需要实盘交易的合约,新建对应的参数对象即可,以下参数仅供测试使用,不作为实盘参考!!!!
|
||||
param_dict = {}
|
||||
param_dict['rb2410'] = ParamObj(symbol='rb2410', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=1,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['ni2405'] = ParamObj(symbol='ni2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=1500,sum_delta=2000,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['j2405'] = ParamObj(symbol='j2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['TA405'] = ParamObj(symbol='TA405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['au2406'] = ParamObj(symbol='au2406', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['sc2405'] = ParamObj(symbol='sc2405', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['bc2406'] = ParamObj(symbol='bc2406', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
# param_dict['lu2406'] = ParamObj(symbol='lu2406', Lots=1, py=5, trailing_stop_percent=0.02, fixed_stop_loss_percent=0.01,dj_X=0,delta=15,sum_delta=20,失衡=3,堆积=3,周期='1T')
|
||||
|
||||
#用simnow模拟,不要忘记屏蔽下方实盘的future_account字典
|
||||
# future_account = get_simulate_account(
|
||||
# investor_id='135858', # simnow账户,注意是登录账户的ID,SIMNOW个人首页查看
|
||||
# password='Zj82334475', # simnow密码
|
||||
# server_name='电信1', # 电信1、电信2、移动、TEST、N视界
|
||||
# subscribe_list=list(param_dict.keys()), # 合约列表
|
||||
# )
|
||||
|
||||
#实盘用这个,不要忘记屏蔽上方simnow的future_account字典
|
||||
future_account = FutureAccount(
|
||||
broker_id='8888', # 期货公司BrokerID
|
||||
server_dict={'TDServer': "103.140.14.210:43205", 'MDServer': '103.140.14.210:43173'}, # TDServer为交易服务器,MDServer为行情服务器。服务器地址格式为"ip:port。"
|
||||
reserve_server_dict={}, # 备用服务器地址
|
||||
investor_id='155878', # 账户
|
||||
password='Zj82334475', # 密码
|
||||
app_id='vntech_vnpy_2.0', # 认证使用AppID
|
||||
auth_code='N46EKN6TJ9U7V06V', # 认证使用授权码
|
||||
subscribe_list=list(param_dict.keys()), # 订阅合约列表
|
||||
md_flow_path='./log', # MdApi流文件存储地址,默认MD_LOCATION
|
||||
td_flow_path='./log', # TraderApi流文件存储地址,默认TD_LOCATION
|
||||
)
|
||||
|
||||
|
||||
print('开始',len(future_account.subscribe_list))
|
||||
# 共享队列
|
||||
share_queue = Queue(maxsize=200)
|
||||
|
||||
# 行情进程
|
||||
md_process = Process(target=run_tick_engine, args=(future_account, [share_queue]))
|
||||
|
||||
|
||||
# 交易进程
|
||||
trader_process = Process(target=run_trader, args=(
|
||||
param_dict,
|
||||
future_account.broker_id,
|
||||
future_account.server_dict['TDServer'],
|
||||
future_account.investor_id,
|
||||
future_account.password,
|
||||
future_account.app_id,
|
||||
future_account.auth_code,
|
||||
share_queue, # 队列
|
||||
future_account.td_flow_path
|
||||
))
|
||||
|
||||
md_process.start()
|
||||
trader_process.start()
|
||||
|
||||
md_process.join()
|
||||
trader_process.join()
|
||||
|
||||
|
||||
@@ -0,0 +1,780 @@
|
||||
'''
|
||||
使用说明:使用前需要调整的相关参数如下
|
||||
1.确定python到csv文件夹下运行,修改csv文件为需要运行的csv
|
||||
2.配置邮件信息和参数。
|
||||
3.tickdata函数中:一、修改时间冲采样resample中rule周期5T为交易周期,
|
||||
4.GetOrderFlow_dj函数:一、堆积函数config参数暂时均为3
|
||||
5.MyTrader类:
|
||||
1) init函数初始化:委托价格的偏移、跟踪出场、固定出差参数、交易手数的设置;
|
||||
2) day_data_reset函数、每日收盘重置数据按照交易品种设置。
|
||||
3)Join函数:修改“开多组合”和“开空组合”
|
||||
6. __main__函数:设置交易账户变量
|
||||
该代码的主要目的是处理Tick数据并生成交易信号。代码中定义了一个tickcome函数,它接收到Tick数据后会进行一系列的处理,包括构建Tick字典、更新上一个Tick的成交量、保存Tick数据、生成K线数据等。其中涉及到的一些函数有:
|
||||
on_tick(tick): 处理单个Tick数据,根据Tick数据生成K线数据。
|
||||
tickdata(df, symbol): 处理Tick数据,生成K线数据。
|
||||
orderflow_df_new(df_tick, df_min, symbol): 处理Tick和K线数据,生成订单流数据。
|
||||
GetOrderFlow_dj(kData): 计算订单流的信号指标。
|
||||
除此之外,代码中还定义了一个MyTrader类,继承自TraderApiBase,用于实现交易相关的功能。
|
||||
'''
|
||||
# 需要完善:__main__函数中手动设置subscribe_list变量,通过时间判断是否需要进行换月修改,并发送邮件通知
|
||||
|
||||
from multiprocessing import Process, Queue
|
||||
from AlgoPlus.CTP.MdApi import run_tick_engine
|
||||
from AlgoPlus.CTP.FutureAccount import get_simulate_account
|
||||
from AlgoPlus.CTP.FutureAccount import FutureAccount
|
||||
from AlgoPlus.CTP.TraderApiBase import TraderApiBase
|
||||
from AlgoPlus.ta.time_bar import tick_to_bar
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
from datetime import time as s_time
|
||||
import operator
|
||||
import time
|
||||
import numpy as np
|
||||
import os
|
||||
import re
|
||||
|
||||
# 加入邮件通知
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText # 导入 MIMEText 类发送纯文本邮件
|
||||
from email.mime.multipart import MIMEMultipart # 导入 MIMEMultipart 类发送带有附件的邮件
|
||||
from email.mime.application import MIMEApplication # 导入 MIMEApplication 类发送二进制附件
|
||||
|
||||
## 配置邮件信息
|
||||
receivers = ["***@qq.com"] # 设置邮件接收人地址
|
||||
subject = "订单流策略交易信号" # 设置邮件主题
|
||||
#text = " " # 设置邮件正文
|
||||
# file_path = "test.txt" # 设置邮件附件文件路径
|
||||
|
||||
## 配置邮件服务器信息
|
||||
smtp_server = "smtp.qq.com" # 设置发送邮件的 SMTP 服务器地址
|
||||
smtp_port = 465 # 设置发送邮件的 SMTP 服务器端口号,一般为 25 端口 465
|
||||
sender = "***@qq.com" # 设置发送邮件的邮箱地址
|
||||
username = "***@qq.com" # 设置发送邮件的邮箱用户名
|
||||
password = "zrmpcgttataabhjh" #zrmpcgttataabhjh,设置发送邮件的邮箱密码或授权码
|
||||
|
||||
tickdatadict = {} # 存储Tick数据的字典
|
||||
quotedict = {} # 存储行情数据的字典
|
||||
ofdatadict = {} # 存储K线数据的字典
|
||||
trader_df = pd.DataFrame({}) # 存储交易数据的DataFrame对象
|
||||
previous_volume = {} # 上一个Tick的成交量
|
||||
tsymbollist={}
|
||||
|
||||
# 邮件通知模块
|
||||
def send_mail(text):
|
||||
msg = MIMEMultipart()
|
||||
msg["From"] = sender
|
||||
msg["To"] = ";".join(receivers)
|
||||
msg["Subject"] = subject
|
||||
msg.attach(MIMEText(text, "plain", "utf-8"))
|
||||
smtp = smtplib.SMTP_SSL(smtp_server, smtp_port)
|
||||
smtp.login(username, password)
|
||||
smtp.sendmail(sender, receivers, msg.as_string())
|
||||
smtp.quit()
|
||||
|
||||
def tickcome(md_queue):
|
||||
global previous_volume
|
||||
|
||||
data=md_queue
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
ActionDay = data['ActionDay'].decode() # 交易日日期
|
||||
update_time = data['UpdateTime'].decode() # 更新时间
|
||||
update_millisec = str(data['UpdateMillisec']) # 更新毫秒数
|
||||
created_at = ActionDay[:4] + '-' + ActionDay[4:6] + '-' + ActionDay[6:] + ' ' + update_time + '.' + update_millisec #创建时间
|
||||
# 构建tick字典
|
||||
tick = {
|
||||
'symbol': instrument_id, # 品种代码和交易所ID
|
||||
'created_at':datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S.%f"),
|
||||
#'created_at': created_at, # 创建时间
|
||||
'price': float(data['LastPrice']), # 最新价
|
||||
'last_volume': int(data['Volume']) - previous_volume.get(instrument_id, 0) if previous_volume.get(instrument_id, 0) != 0 else 0, # 瞬时成交量
|
||||
'bid_p': float(data['BidPrice1']), # 买价
|
||||
'bid_v': int(data['BidVolume1']), # 买量
|
||||
'ask_p': float(data['AskPrice1']), # 卖价
|
||||
'ask_v': int(data['AskVolume1']), # 卖量
|
||||
'UpperLimitPrice': float(data['UpperLimitPrice']), # 涨停价
|
||||
'LowerLimitPrice': float(data['LowerLimitPrice']), # 跌停价
|
||||
'TradingDay': data['TradingDay'].decode(), # 交易日日期
|
||||
'cum_volume': int(data['Volume']), # 最新总成交量
|
||||
'cum_amount': float(data['Turnover']), # 最新总成交额
|
||||
'cum_position': int(data['OpenInterest']), # 合约持仓量
|
||||
}
|
||||
# 更新上一个Tick的成交量
|
||||
previous_volume[instrument_id] = int(data['Volume'])
|
||||
if tick['last_volume']>0:
|
||||
#print(tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 处理Tick数据
|
||||
on_tick(tick)
|
||||
|
||||
def can_time(hour, minute):
|
||||
hour = str(hour)
|
||||
minute = str(minute)
|
||||
if len(minute) == 1:
|
||||
minute = "0" + minute
|
||||
return int(hour + minute)
|
||||
|
||||
def on_tick(tick):
|
||||
|
||||
tm=can_time(tick['created_at'].hour,tick['created_at'].minute)
|
||||
#print(tick['symbol'])
|
||||
#print(1)
|
||||
#if tm>1500 and tm<2100 :
|
||||
# return
|
||||
if tick['last_volume']==0:
|
||||
return
|
||||
quotes = tick
|
||||
timetick=str(tick['created_at']).replace('+08:00', '')
|
||||
tsymbol=tick['symbol']
|
||||
if tsymbol not in tsymbollist.keys():
|
||||
# 获取tick的买卖价和买卖量
|
||||
tsymbollist[tsymbol]=tick
|
||||
bid_p=quotes['bid_p']
|
||||
ask_p=quotes['ask_p']
|
||||
bid_v=quotes['bid_v']
|
||||
ask_v=quotes['ask_v']
|
||||
else:
|
||||
# 获取上一个tick的买卖价和买卖量
|
||||
rquotes =tsymbollist[tsymbol]
|
||||
bid_p=rquotes['bid_p']
|
||||
ask_p=rquotes['ask_p']
|
||||
bid_v=rquotes['bid_v']
|
||||
ask_v=rquotes['ask_v']
|
||||
tsymbollist[tsymbol]=tick
|
||||
tick_dt=pd.DataFrame({'datetime':timetick,'symbol':tick['symbol'],'mainsym':tick['symbol'].rstrip('0123456789').upper(),'lastprice':tick['price'],
|
||||
'vol':tick['last_volume'],
|
||||
'bid_p':bid_p,'ask_p':ask_p,'bid_v':bid_v,'ask_v':ask_v},index=[0])
|
||||
sym = tick_dt['symbol'][0]
|
||||
#print(tick_dt)
|
||||
tickdata(tick_dt,sym)
|
||||
|
||||
# 这个函数的主要目的是将输入的买盘和卖盘字典合并、排序、累加,并将处理后的结果存储在一个全局字典quotedict中,同时返回这个结果。
|
||||
def data_of(df):
|
||||
global trader_df
|
||||
# 将df数据合并到trader_df中
|
||||
trader_df = pd.concat([trader_df, df], ignore_index=True)
|
||||
#print('trader_df: ', len(trader_df))
|
||||
#print(trader_df)
|
||||
|
||||
def process(bidDict, askDict, symbol):
|
||||
try:
|
||||
# 尝试从quotedict中获取对应品种的报价数据
|
||||
dic = quotedict[symbol]
|
||||
bidDictResult = dic['bidDictResult']
|
||||
askDictResult = dic['askDictResult']
|
||||
except:
|
||||
# 如果获取失败,则初始化bidDictResult和askDictResult为空字典
|
||||
bidDictResult, askDictResult = {}, {}
|
||||
|
||||
# 将所有买盘字典和卖盘字典的key合并,并按升序排序
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
|
||||
# 遍历所有的key,将相同key的值进行累加
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
if s in bidDictResult:
|
||||
bidDictResult[s] = int(bidDict[s]) + bidDictResult[s]
|
||||
else:
|
||||
bidDictResult[s] = int(bidDict[s])
|
||||
if s not in askDictResult:
|
||||
askDictResult[s] = 0
|
||||
else:
|
||||
if s in askDictResult:
|
||||
askDictResult[s] = int(askDict[s]) + askDictResult[s]
|
||||
else:
|
||||
askDictResult[s] = int(askDict[s])
|
||||
if s not in bidDictResult:
|
||||
bidDictResult[s] = 0
|
||||
|
||||
# 构建包含bidDictResult和askDictResult的字典,并存入quotedict中
|
||||
df = {'bidDictResult': bidDictResult, 'askDictResult': askDictResult}
|
||||
quotedict[symbol] = df
|
||||
|
||||
return bidDictResult, askDictResult
|
||||
|
||||
def tickdata(df,symbol):
|
||||
tickdata =pd.DataFrame({'datetime':df['datetime'],'symbol':df['symbol'],'lastprice':df['lastprice'],
|
||||
'volume':df['vol'],'bid_p':df['bid_p'],'bid_v':df['bid_v'],'ask_p':df['ask_p'],'ask_v':df['ask_v']})
|
||||
try:
|
||||
if symbol in tickdatadict.keys():
|
||||
rdf=tickdatadict[symbol]
|
||||
rdftm=pd.to_datetime(rdf['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
now=str(tickdata['datetime'][0])
|
||||
if now>rdftm:
|
||||
try:
|
||||
oo=ofdatadict[symbol]
|
||||
data_of(oo)
|
||||
#print('oo',oo)
|
||||
if symbol in quotedict.keys():
|
||||
quotedict.pop(symbol)
|
||||
if symbol in tickdatadict.keys():
|
||||
tickdatadict.pop(symbol)
|
||||
if symbol in ofdatadict.keys():
|
||||
ofdatadict.pop(symbol)
|
||||
except IOError as e:
|
||||
print('rdftm捕获到异常',e)
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
else:
|
||||
tickdata['bartime'] = rdf['bartime']
|
||||
tickdata['open'] = rdf['open']
|
||||
tickdata['high'] = max(tickdata['lastprice'].values,rdf['high'].values)
|
||||
tickdata['low'] = min(tickdata['lastprice'].values,rdf['low'].values)
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['volume']=df['vol']+rdf['volume'].values
|
||||
tickdata['starttime'] = rdf['starttime']
|
||||
else :
|
||||
print('新bar的第一个tick进入')
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
except IOError as e:
|
||||
print('捕获到异常',e)
|
||||
|
||||
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['bartime'])
|
||||
bardata = tickdata.resample(on = 'bartime',rule = '1T',label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
bardata['bartime'] = pd.to_datetime(bardata['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
tickdatadict[symbol]=bardata
|
||||
tickdata['volume']=df['vol'].values
|
||||
#print(bardata['symbol'].values,bardata['bartime'].values)
|
||||
orderflow_df_new(tickdata,bardata,symbol)
|
||||
# time.sleep(0.5)
|
||||
|
||||
def orderflow_df_new(df_tick,df_min,symbol):
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
#endArray = pd.to_datetime(df_min['bartime']).values
|
||||
endArray = df_min['bartime'].values
|
||||
#print(endArray)
|
||||
deltaArray = np.zeros((len(endArray),))
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
dt=endArray[index]
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
# for indexTick in range(indexFinal,len(df_tick)):
|
||||
# if tTickArray[indexTick] >= tEnd:
|
||||
# break
|
||||
# elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] < tEnd):
|
||||
Bp = round(bp1TickArray[0],4)
|
||||
Ap = round(ap1TickArray[0],4)
|
||||
LastPrice = round(lastTickArray[0],4)
|
||||
Volume = volumeTickArray[0]
|
||||
if LastPrice >= Ap:
|
||||
if str(LastPrice) in askDict.keys():
|
||||
askDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
askDict[str(LastPrice)] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if str(LastPrice) in bidDict.keys():
|
||||
bidDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
bidDict[str(LastPrice)] = Volume
|
||||
# indexFinal = indexTick
|
||||
bidDictResult,askDictResult = process(bidDict,askDict,symbol)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
#print(prinslist,asklist,bidlist)
|
||||
#print(len(prinslist),len(bidDictResult),len(askDictResult))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
#df=pd.DataFrame({'price':pd.Series(bidDictResult.keys()),'Ask':pd.Series(askDictResult.values()),'Bid':pd.Series(bidDictResult.values())})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
#df['ticktime']=tTickArray[0]
|
||||
df['dj'] = GetOrderFlow_dj(df)
|
||||
ofdatadict[symbol]=df
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def GetOrderFlow_dj(kData):
|
||||
Config = {
|
||||
'Value1': 3,
|
||||
'Value2': 3,
|
||||
'Value3': 3,
|
||||
'Value4': True,
|
||||
}
|
||||
aryData = kData
|
||||
djcout = 0
|
||||
|
||||
# 遍历kData中的每一行,计算djcout指标
|
||||
for index, row in aryData.iterrows():
|
||||
kItem = aryData.iloc[index]
|
||||
high = kItem['high']
|
||||
low = kItem['low']
|
||||
close = kItem['close']
|
||||
open = kItem['open']
|
||||
dtime = kItem['datetime']
|
||||
price_s = kItem['price']
|
||||
Ask_s = kItem['Ask']
|
||||
Bid_s = kItem['Bid']
|
||||
delta = kItem['delta']
|
||||
|
||||
price_s = price_s
|
||||
Ask_s = Ask_s
|
||||
Bid_s = Bid_s
|
||||
|
||||
gj = 0
|
||||
xq = 0
|
||||
gxx = 0
|
||||
xxx = 0
|
||||
|
||||
# 遍历price_s中的每一个元素,计算相关指标
|
||||
for i in np.arange(0, len(price_s), 1):
|
||||
duiji = {
|
||||
'price': 0,
|
||||
'time': 0,
|
||||
'longshort': 0,
|
||||
}
|
||||
|
||||
if i == 0:
|
||||
delta = delta
|
||||
|
||||
order = {
|
||||
"Price": price_s[i],
|
||||
"Bid": { "Value":Bid_s[i]},
|
||||
"Ask": { "Value":Ask_s[i]}
|
||||
}
|
||||
#空头堆积
|
||||
if i >= 0 and i < len(price_s) - 1:
|
||||
if (order["Bid"]["Value"] > Ask_s[i + 1] * int(Config['Value1'])):
|
||||
gxx += 1
|
||||
gj += 1
|
||||
if gj >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = -1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += -1
|
||||
else:
|
||||
gj = 0
|
||||
#多头堆积
|
||||
if i >= 1 and i < len(price_s) - 1:
|
||||
if (order["Ask"]["Value"] > Bid_s[i - 1] * int(Config['Value1'])):
|
||||
xq += 1
|
||||
xxx += 1
|
||||
if xq >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = 1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += 1
|
||||
else:
|
||||
xq = 0
|
||||
|
||||
# 返回计算得到的djcout值
|
||||
return djcout
|
||||
|
||||
#交易程序---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class MyTrader(TraderApiBase):
|
||||
def __init__(self, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
self.py=5 #设置委托价格的偏移,更加容易促成成交。仅螺纹,其他品种根据最小点波动,自己设置
|
||||
self.cont_df=0
|
||||
self.trailing_stop_percent = 0.02 #跟踪出场参数
|
||||
self.fixed_stop_loss_percent = 0.01 #固定出场参数
|
||||
self.dj_X=1 #开仓的堆积参数
|
||||
|
||||
self.pos=0
|
||||
self.Lots=1
|
||||
self.short_trailing_stop_price = 0
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.sl_shor_price=0
|
||||
self.out_long=0
|
||||
self.out_short=0
|
||||
self.clearing_executed=False
|
||||
self.kgdata=True
|
||||
|
||||
|
||||
#读取保存的数据
|
||||
def read_to_csv(self,symbol):
|
||||
# 文件夹路径和文件路径
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
symbol = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
folder_path = "traderdata"
|
||||
file_path = os.path.join(folder_path, f"{str(symbol)}traderdata.csv")
|
||||
# 如果文件夹不存在则创建
|
||||
if not os.path.exists(folder_path):
|
||||
os.makedirs(folder_path)
|
||||
|
||||
# 读取保留的模型数据CSV文件
|
||||
if os.path.exists(file_path):
|
||||
df = pd.read_csv(file_path)
|
||||
if not df.empty and self.kgdata==True:
|
||||
# 选择最后一行数据
|
||||
row = df.iloc[-1]
|
||||
# 根据CSV文件的列名将数据赋值给相应的属性
|
||||
self.pos = int(row['pos'])
|
||||
self.short_trailing_stop_price = float(row['short_trailing_stop_price'])
|
||||
self.long_trailing_stop_price = float(row['long_trailing_stop_price'])
|
||||
self.sl_long_price = float(row['sl_long_price'])
|
||||
self.sl_shor_price = float(row['sl_shor_price'])
|
||||
# self.out_long = int(row['out_long'])
|
||||
# self.out_short = int(row['out_short'])
|
||||
print("找到历史交易数据文件,已经更新持仓,止损止盈数据", df.iloc[-1])
|
||||
self.kgdata=False
|
||||
else:
|
||||
pass
|
||||
#print("没有找到历史交易数据文件", file_path)
|
||||
#如果没有找到CSV,则初始化变量
|
||||
|
||||
pass
|
||||
|
||||
#保存数据
|
||||
def save_to_csv(self,symbol):
|
||||
# 使用正则表达式提取英文字母并重新赋值给symbol
|
||||
symbol = ''.join(re.findall('[a-zA-Z]', str(symbol)))
|
||||
# 创建DataFrame
|
||||
data = {
|
||||
'datetime': [trader_df['datetime'].iloc[-1]],
|
||||
'pos': [self.pos],
|
||||
'short_trailing_stop_price': [self.short_trailing_stop_price],
|
||||
'long_trailing_stop_price': [self.long_trailing_stop_price],
|
||||
'sl_long_price': [self.sl_long_price],
|
||||
'sl_shor_price': [self.sl_shor_price],
|
||||
# 'out_long': [self.out_long],
|
||||
# 'out_short': [self.out_short]
|
||||
}
|
||||
|
||||
df = pd.DataFrame(data)
|
||||
|
||||
# 将DataFrame保存到CSV文件
|
||||
df.to_csv(f"traderdata/{str(symbol)}traderdata.csv", index=False)
|
||||
|
||||
#每日收盘重置数据
|
||||
def day_data_reset(self):
|
||||
# 获取当前时间
|
||||
current_time = datetime.now().time()
|
||||
|
||||
# 第一时间范围
|
||||
clearing_time1_start = s_time(15,00)
|
||||
clearing_time1_end = s_time(15,15)
|
||||
|
||||
# 第二时间范围
|
||||
clearing_time2_start = s_time(23,0)
|
||||
clearing_time2_end = s_time(23,15)
|
||||
|
||||
# 创建一个标志变量,用于记录是否已经执行过
|
||||
self.clearing_executed = False
|
||||
# 检查当前时间第一个操作的时间范围内
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not self.clearing_executed :
|
||||
self.clearing_executed = True # 设置标志变量为已执行
|
||||
trader_df.drop(trader_df.index,inplace=True)#清除当天的行情数据
|
||||
|
||||
# 检查当前时间是否在第二个操作的时间范围内
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not self.clearing_executed :
|
||||
self.clearing_executed = True # 设置标志变量为已执行
|
||||
trader_df.drop(trader_df.index,inplace=True) #清除当天的行情数据
|
||||
else:
|
||||
self.clearing_executed = False
|
||||
pass
|
||||
return self.clearing_executed
|
||||
|
||||
def OnRtnTrade(self, pTrade):
|
||||
print("||成交回报||", pTrade)
|
||||
|
||||
def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast):
|
||||
print("||OnRspOrderInsert||", pInputOrder, pRspInfo, nRequestID, bIsLast)
|
||||
|
||||
# 订单状态通知
|
||||
def OnRtnOrder(self, pOrder):
|
||||
print("||订单回报||", pOrder)
|
||||
|
||||
def Join(self):
|
||||
data = None
|
||||
while True:
|
||||
if self.status == 0:
|
||||
|
||||
while not self.md_queue.empty():
|
||||
data = self.md_queue.get(block=False)
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
self.read_to_csv(instrument_id)
|
||||
self.day_data_reset()
|
||||
tickcome(data)
|
||||
#新K线开始,启动交易程序 and 保存行情数据
|
||||
if len(trader_df)>self.cont_df:
|
||||
# 检查文件是否存在
|
||||
csv_file_path = f"traderdata/{instrument_id}_ofdata.csv"
|
||||
if os.path.exists(csv_file_path):
|
||||
# 仅保存最后一行数据
|
||||
trader_df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
else:
|
||||
# 创建新文件并保存整个DataFrame
|
||||
trader_df.to_csv(csv_file_path, index=False)
|
||||
|
||||
# 更新跟踪止损价格
|
||||
if self.long_trailing_stop_price >0 and self.pos>0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧多头出线',self.long_trailing_stop_price,'low',self.low[0])
|
||||
|
||||
self.long_trailing_stop_price = trader_df['low'].iloc[-1] if self.long_trailing_stop_price<trader_df['low'].iloc[-1] else self.long_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#print('datetime+sig: ',dt,'多头出线',self.long_trailing_stop_price)
|
||||
if self.short_trailing_stop_price >0 and self.pos<0:
|
||||
|
||||
#print('datetime+sig: ',dt,'旧空头出线',self.short_trailing_stop_price,'high',self.high[0])
|
||||
|
||||
self.short_trailing_stop_price = trader_df['high'].iloc[-1] if trader_df['high'].iloc[-1] <self.short_trailing_stop_price else self.short_trailing_stop_price
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#print('datetime+sig: ',dt,'空头出线',self.short_trailing_stop_price)
|
||||
|
||||
self.out_long=self.long_trailing_stop_price * (1 - self.trailing_stop_percent)
|
||||
self.out_short=self.short_trailing_stop_price*(1 + self.trailing_stop_percent)
|
||||
#print('datetime+sig: ',dt,'空头出线',self.out_short)
|
||||
#print('datetime+sig: ',dt,'多头出线',self.out_long)
|
||||
# 跟踪出场
|
||||
if self.out_long >0:
|
||||
print('datetime+sig: ',trader_df['datetime'].iloc[-1],'预设——多头止盈——','TR',self.out_long,'low', trader_df['low'].iloc[-1])
|
||||
if trader_df['low'].iloc[-1] < self.out_long and self.pos>0 and self.sl_long_price>0 and trader_df['low'].iloc[-1]>self.sl_long_price:
|
||||
print('datetime+sig: ',trader_df['datetime'].iloc[-1],'多头止盈','TR',self.out_long,'low', trader_df['low'].iloc[-1])
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-self.py,self.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-self.py,self.Lots,b'1',b'3')
|
||||
self.long_trailing_stop_price = 0
|
||||
self.out_long=0
|
||||
self.sl_long_price=0
|
||||
self.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
if self.out_short>0:
|
||||
print('datetime+sig: ',trader_df['datetime'].iloc[-1],'预设——空头止盈——: ','TR',self.out_short,'high', trader_df['high'].iloc[-1])
|
||||
if trader_df['high'].iloc[-1] > self.out_short and self.pos<0 and self.sl_shor_price>0 and trader_df['high'].iloc[-1]<self.sl_shor_price:
|
||||
print('datetime+sig: ',trader_df['datetime'].iloc[-1],'空头止盈: ','TR',self.out_short,'high', trader_df['high'].iloc[-1])
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+self.py,self.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+self.py,self.Lots,b'0',b'3')
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_shor=0
|
||||
self.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 固定止损
|
||||
self.fixed_stop_loss_L = self.sl_long_price * (1 - self.fixed_stop_loss_percent)
|
||||
if self.pos>0:
|
||||
print('datetime+sig: ', trader_df['datetime'].iloc[-1], '预设——多头止损', 'SL', self.fixed_stop_loss_L, 'close', trader_df['close'].iloc[-1])
|
||||
if self.sl_long_price>0 and self.fixed_stop_loss_L>0 and self.pos > 0 and trader_df['close'].iloc[-1] < self.fixed_stop_loss_L:
|
||||
print('datetime+sig: ', trader_df['datetime'].iloc[-1], '多头止损', 'SL', self.fixed_stop_loss_L, 'close', trader_df['close'].iloc[-1])
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-self.py,self.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-self.py,self.Lots,b'1',b'3')
|
||||
self.long_trailing_stop_price = 0
|
||||
self.sl_long_price=0
|
||||
self.out_long = 0
|
||||
self.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
self.fixed_stop_loss_S = self.sl_shor_price * (1 + self.fixed_stop_loss_percent)
|
||||
if self.pos<0:
|
||||
print('datetime+sig: ', trader_df['datetime'].iloc[-1], '预设——空头止损', 'SL', self.fixed_stop_loss_S, 'close', trader_df['close'].iloc[-1])
|
||||
if self.sl_shor_price>0 and self.fixed_stop_loss_S>0 and self.pos < 0 and trader_df['close'].iloc[-1] > self.fixed_stop_loss_S:
|
||||
print('datetime+sig: ', trader_df['datetime'].iloc[-1], '空头止损', 'SL', self.fixed_stop_loss_S, 'close', trader_df['close'].iloc[-1])
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+self.py,self.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+self.py,self.Lots,b'0',b'3')
|
||||
self.short_trailing_stop_price = 0
|
||||
self.sl_shor_price=0
|
||||
self.out_short = 0
|
||||
self.pos = 0
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#日均线
|
||||
trader_df['dayma']=trader_df['close'].mean()
|
||||
|
||||
# 计算累积的delta值
|
||||
trader_df['delta'] = trader_df['delta'].astype(float)
|
||||
trader_df['delta累计'] = trader_df['delta'].cumsum()
|
||||
|
||||
#大于日均线
|
||||
开多1=trader_df['dayma'].iloc[-1] > 0 and trader_df['close'].iloc[-1] > trader_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量大于X
|
||||
开多4=trader_df['delta累计'].iloc[-1] > 2000 and trader_df['delta'].iloc[-1] > 1500
|
||||
|
||||
#小于日均线
|
||||
开空1=trader_df['dayma'].iloc[-1]>0 and trader_df['close'].iloc[-1] < trader_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量小于X
|
||||
开空4=trader_df['delta累计'].iloc[-1] < -2000 and trader_df['delta'].iloc[-1] < -1500
|
||||
|
||||
开多组合= 开多1 and 开多4 and trader_df['dj'].iloc[-1]>self.dj_X
|
||||
开空条件= 开空1 and 开空4 and trader_df['dj'].iloc[-1]<-self.dj_X
|
||||
|
||||
平多条件=trader_df['dj'].iloc[-1]<-self.dj_X
|
||||
平空条件=trader_df['dj'].iloc[-1]>self.dj_X
|
||||
#开仓
|
||||
#多头开仓条件
|
||||
if self.pos<0 and 平空条件 :
|
||||
print('平空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+self.py)
|
||||
#insert_order:买卖方向,开仓:0,平仓:1,强平:2,平今:3,平昨:4,强减:5,本地强平:6
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+self.py,self.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+self.py,self.Lots,b'0',b'3')
|
||||
self.pos=0
|
||||
self.sl_shor_price=0
|
||||
self.short_trailing_stop_price=0
|
||||
print('datetime+sig: ', trader_df['datetime'].iloc[-1], '反手平空:', '平仓价格:', data['AskPrice1']+self.py,'堆积数:', trader_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#发送邮件
|
||||
text = f"平空交易: 交易品种为{data['InstrumentID']}, 交易时间为{trader_df['datetime'].iloc[-1]}, 反手平空的平仓价格{data['AskPrice1']+self.py}"
|
||||
send_mail(text)
|
||||
if self.pos==0 and 开多组合:
|
||||
print('开多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'AskPrice1',data['AskPrice1']+self.py)
|
||||
#开多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+self.py,self.Lots,b'0',b'0')
|
||||
print('datetime+sig: ', trader_df['datetime'].iloc[-1], '多头开仓', '开仓价格:', data['AskPrice1']+self.py,'堆积数:', trader_df['dj'].iloc[-1])
|
||||
self.pos=1
|
||||
self.long_trailing_stop_price=data['AskPrice1']
|
||||
self.sl_long_price=data['AskPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#发送邮件
|
||||
text = f"开多交易: 交易品种为{data['InstrumentID']}, 交易时间为{trader_df['datetime'].iloc[-1]}, 多头开仓的开仓价格{data['AskPrice1']+self.py},预设——多头止盈——TR{self.out_long},多头止损SL{self.fixed_stop_loss_L}"
|
||||
send_mail(text)
|
||||
|
||||
|
||||
if self.pos>0 and 平多条件 :
|
||||
print('平多: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1']-self.py)
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-self.py,self.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-self.py,self.Lots,b'1',b'3')
|
||||
self.pos=0
|
||||
self.long_trailing_stop_price=0
|
||||
self.sl_long_price=0
|
||||
print('datetime+sig: ', trader_df['datetime'].iloc[-1], '反手平多', '平仓价格:', data['BidPrice1']-self.py,'堆积数:', trader_df['dj'].iloc[-1])
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
#发送邮件
|
||||
text = f"平多交易: 交易品种为{data['InstrumentID']}, 交易时间为{trader_df['datetime'].iloc[-1]}, 反手平多的平仓价格{data['BidPrice1']-self.py}"
|
||||
send_mail(text)
|
||||
|
||||
if self.pos==0 and 开空条件 :
|
||||
print('开空: ','ExchangeID: ',data['ExchangeID'],'InstrumentID',data['InstrumentID'],'BidPrice1',data['BidPrice1'])
|
||||
#开空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-self.py,self.Lots,b'1',b'0')
|
||||
print('datetime+sig: ', trader_df['datetime'].iloc[-1], '空头开仓', '开仓价格:', data['BidPrice1']-self.py,'堆积数:', trader_df['dj'].iloc[-1])
|
||||
self.pos=-1
|
||||
self.short_trailing_stop_price=data['BidPrice1']
|
||||
self.sl_shor_price=data['BidPrice1']
|
||||
self.save_to_csv(instrument_id)
|
||||
|
||||
# 发送邮件
|
||||
text = f"开空交易: 交易品种为{data['InstrumentID']}, 交易时间为{trader_df['datetime'].iloc[-1]}, 空头开仓的开仓价格{data['BidPrice1']-self.py},预设——空头止盈——TR{self.out_short},空头止损{self.fixed_stop_loss_S}"
|
||||
send_mail(text)
|
||||
|
||||
print(trader_df)
|
||||
self.cont_df=len(trader_df)
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
|
||||
def run_trader(broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
my_trader = MyTrader(broker_id, td_server, investor_id, password, app_id, auth_code, md_queue, page_dir, private_resume_type, public_resume_type)
|
||||
my_trader.Join()
|
||||
|
||||
if __name__ == '__main__':
|
||||
#global symbol
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
#注意:运行前请先安装好algoplus,
|
||||
# pip install AlgoPlus
|
||||
#http://www.algo.plus/ctp/python/0103001.html
|
||||
|
||||
|
||||
#用simnow模拟,不要忘记屏蔽下方实盘的future_account字典
|
||||
future_account = get_simulate_account(
|
||||
investor_id='135858', # simnow账户,注意是登录账户的ID,SIMNOW个人首页查看
|
||||
password='Zj82334475', # simnow密码
|
||||
server_name='TEST', # 电信1、电信2、移动、TEST、N视界
|
||||
subscribe_list=[b'rb2405'], # 合约列表
|
||||
)
|
||||
|
||||
#实盘用这个,不要忘记屏蔽上方simnow的future_account字典
|
||||
# future_account = FutureAccount(
|
||||
# broker_id='', # 期货公司BrokerID
|
||||
# server_dict={'TDServer': "ip:port", 'MDServer': 'ip:port'}, # TDServer为交易服务器,MDServer为行情服务器。服务器地址格式为"ip:port。"
|
||||
# reserve_server_dict={}, # 备用服务器地址
|
||||
# investor_id='', # 账户
|
||||
# password='', # 密码
|
||||
# app_id='simnow_client_test', # 认证使用AppID
|
||||
# auth_code='0000000000000000', # 认证使用授权码
|
||||
# subscribe_list=[b'rb2405'], # 订阅合约列表
|
||||
# md_flow_path='./log', # MdApi流文件存储地址,默认MD_LOCATION
|
||||
# td_flow_path='./log', # TraderApi流文件存储地址,默认TD_LOCATION
|
||||
# )
|
||||
|
||||
|
||||
print('开始',len(future_account.subscribe_list))
|
||||
# 共享队列
|
||||
share_queue = Queue(maxsize=200)
|
||||
|
||||
# 行情进程
|
||||
md_process = Process(target=run_tick_engine, args=(future_account, [share_queue]))
|
||||
|
||||
|
||||
# 交易进程
|
||||
trader_process = Process(target=run_trader, args=(
|
||||
future_account.broker_id,
|
||||
future_account.server_dict['TDServer'],
|
||||
future_account.investor_id,
|
||||
future_account.password,
|
||||
future_account.app_id,
|
||||
future_account.auth_code,
|
||||
share_queue, # 队列
|
||||
future_account.td_flow_path
|
||||
))
|
||||
|
||||
md_process.start()
|
||||
trader_process.start()
|
||||
# success = f"行情和交易启动成功!{future_account.subscribe_list}"
|
||||
# send_mail(success)
|
||||
|
||||
|
||||
md_process.join()
|
||||
trader_process.join()
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
'''
|
||||
Author: zhoujie2104231 zhoujie@me.com
|
||||
Date: 2024-02-25 11:17:14
|
||||
LastEditors: zhoujie2104231 zhoujie@me.com
|
||||
LastEditTime: 2024-02-25 21:40:34
|
||||
# 使用说明:使用前需要调整的相关参数如下
|
||||
# 1.确定python到csv文件夹下运行,并修改到对应的csv文件
|
||||
# 2.设置按照index拆分的表名,此处是按照“合约代码”的不同进行拆分
|
||||
# 3.使用gbk或者utf-8编译
|
||||
'''
|
||||
import csv
|
||||
import os
|
||||
import pandas as pd
|
||||
|
||||
def read_large_csv(file_path, chunk_size):
|
||||
reader = pd.read_csv(file_path, iterator=True, encoding="utf-8")
|
||||
chunks = []
|
||||
while True:
|
||||
try:
|
||||
chunk = reader.get_chunk(chunk_size)
|
||||
chunks.append(chunk)
|
||||
except StopIteration:
|
||||
break
|
||||
return pd.concat(chunks, ignore_index=True)
|
||||
|
||||
filepath = './合成tick数据/merged_data_new.csv'
|
||||
chunk_size = 10000
|
||||
data = read_large_csv(filepath, chunk_size)
|
||||
|
||||
groups = data.groupby(data['合约代码'])
|
||||
|
||||
folder_path = "split_csvs"
|
||||
if not os.path.exists(folder_path):
|
||||
os.mkdir('split_csvs')
|
||||
|
||||
for group in groups:
|
||||
group[1].to_csv('./split_csvs/{}.csv'.format(str(group[0])), index = False, encoding = 'utf-8')
|
||||
print("%s.csv创建成功!" %(group[0]))
|
||||
@@ -0,0 +1,64 @@
|
||||
'''
|
||||
Author: zhoujie2104231 zhoujie@me.com
|
||||
Date: 2024-02-25 16:19:47
|
||||
LastEditors: zhoujie2104231 zhoujie@me.com
|
||||
LastEditTime: 2024-02-25 16:22:11
|
||||
FilePath: \Gitee_Code\trading_strategy\SS_Code\SF08\split_data_finall.py
|
||||
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
'''
|
||||
import csv
|
||||
import os
|
||||
import pandas as pd
|
||||
|
||||
def read_large_csv(file_path, chunk_size):
|
||||
reader = pd.read_csv(file_path, iterator=True, encoding="utf-8")
|
||||
chunks = []
|
||||
while True:
|
||||
try:
|
||||
chunk = reader.get_chunk(chunk_size)
|
||||
chunks.append(chunk)
|
||||
except StopIteration:
|
||||
break
|
||||
return pd.concat(chunks, ignore_index=True)
|
||||
|
||||
|
||||
# 读取原始CSV文件
|
||||
# with open('merged_data_new.csv', 'r', encoding="utf-8") as f:
|
||||
# reader = csv.reader(f)
|
||||
# data = list(reader)
|
||||
# print("读取文件成功")
|
||||
|
||||
filepath = 'merged_data_new.csv'
|
||||
chunk_size = 10000
|
||||
data = read_large_csv(filepath, chunk_size)
|
||||
|
||||
print("读取文件成功")
|
||||
|
||||
|
||||
# 创建一个字典,key为symbol列的值,value为一个列表,存放与该symbol值相关的数据行
|
||||
symbol_data = {}
|
||||
header_row = data[0]
|
||||
for row in data[1:]: # 跳过第一行标题
|
||||
symbol = row[2]
|
||||
if symbol not in symbol_data:
|
||||
symbol_data[symbol] = []
|
||||
symbol_data[symbol].append(row)
|
||||
|
||||
print("数据字典创建成功")
|
||||
|
||||
# 创建与symbol列值对应的目录
|
||||
folder_path = "split_csvs"
|
||||
if not os.path.exists(folder_path):
|
||||
os.mkdir('split_csvs')
|
||||
|
||||
for symbol in symbol_data:
|
||||
os.mkdir(os.path.join('split_csvs', symbol))
|
||||
|
||||
# 将数据写入拆分后的CSV文件中
|
||||
for symbol, rows in symbol_data.items():
|
||||
with open(os.path.join('split_csvs', symbol, f'{symbol}.csv'), 'w', newline='') as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows([header_row])
|
||||
writer.writerows(rows)
|
||||
|
||||
print("csv拆分成功")
|
||||
@@ -0,0 +1,132 @@
|
||||
'''
|
||||
Author: zhoujie2104231 zhoujie@me.com
|
||||
# Date: 2024-02-25 17:51:46
|
||||
LastEditors: zhoujie2104231 zhoujie@me.com
|
||||
LastEditTime: 2024-03-07 22:48:22
|
||||
# 使用说明:使用前需要调整的相关参数如下
|
||||
# 1.确定python到csv文件夹下运行,
|
||||
# 2.统一代码的添加:主力连续为888,指数连续可以用999,次主力连续可以使用889,其他的可以不用添加统一代码,注释掉。
|
||||
# 3.文件夹下的文件名按照datetime进行排序修改
|
||||
# 4.data按照时间排序需要根据参数修改['业务日期','最后修改时间','最后修改毫秒'],如果前面文件名按照时间修改好了,不用修改
|
||||
# 5.使用gbk或者utf-8编译
|
||||
'''
|
||||
|
||||
import pandas as pd
|
||||
import os
|
||||
|
||||
# import datetime as dt
|
||||
|
||||
def split_alpha_numeric(string):
|
||||
"""
|
||||
Split a string into alphabetical and numerical characters.
|
||||
|
||||
Args:
|
||||
string: The string to split.
|
||||
|
||||
Returns:
|
||||
A tuple containing two strings, the first containing the alphabetical
|
||||
characters and the second containing the numerical characters.
|
||||
"""
|
||||
|
||||
alpha_chars = ""
|
||||
numeric_chars = ""
|
||||
|
||||
for char in string:
|
||||
if char.isalpha():
|
||||
alpha_chars += char
|
||||
elif char.isdigit():
|
||||
numeric_chars += char
|
||||
|
||||
return alpha_chars, numeric_chars
|
||||
|
||||
#第一中方法:
|
||||
# 获取当前目录下的所有csv文件
|
||||
all_csv_files = [file for file in os.listdir('.') if file.endswith('.csv')]
|
||||
|
||||
# csv需要筛选的文件名字符
|
||||
sp_char = '_2021'
|
||||
|
||||
# 获取当前目录下的所有文件名包含sp_char的csv文件
|
||||
csv_files = [sp_file for sp_file in all_csv_files if sp_char in sp_file]
|
||||
print("csv_files:", csv_files)
|
||||
|
||||
# 另一种遍历方式
|
||||
# folder_path = "D:/data_transfer/ag888"
|
||||
|
||||
# name_chr = "202309"
|
||||
# csv_files = []
|
||||
|
||||
# for root, dirs, files in os.walk(folder_path):
|
||||
# for file in files:
|
||||
# if file.endswith('.csv'):
|
||||
# # 获取文件名(不包含扩展名)
|
||||
# filename = os.path.splitext(file)[0]
|
||||
# match_file = re.search(r'(?<=^.{7}).{6}(?=.{2})',filename)
|
||||
# try:
|
||||
# if match_file.group() == name_chr:#
|
||||
# full_filename = filename + ".csv"
|
||||
# csv_files.append(full_filename)
|
||||
# else:
|
||||
# #print("文件夹中有csv文件,但没有文件名含%s的csv文件"%(name_chr))
|
||||
# pass
|
||||
# except AttributeError:
|
||||
# continue
|
||||
# else:
|
||||
# #print("文件夹中没有csv文件")
|
||||
# pass
|
||||
|
||||
|
||||
# 将当前的数据按照文件名进行排序,生成list文件
|
||||
#csv_files.sort(key=lambda x: int(x.split('.')[0]))
|
||||
|
||||
# 创建新的DataFrame来存储合并后的数据
|
||||
merged_df = pd.DataFrame()
|
||||
|
||||
# 循环遍历每个csv文件
|
||||
for file in csv_files:
|
||||
# 读取csv文件,并使用第一行为列标题,编译不通过可以改为gbk
|
||||
df = pd.read_csv(file, header=0, encoding='gbk')
|
||||
|
||||
# 删除重复行
|
||||
df.drop_duplicates(inplace=True)
|
||||
|
||||
# 将数据合并到新的DataFrame中
|
||||
merged_df = pd.concat([merged_df, df], ignore_index=True)
|
||||
|
||||
# 删除重复列
|
||||
merged_df.drop_duplicates(subset=merged_df.columns.tolist(), inplace=True)
|
||||
|
||||
# 重置行索引
|
||||
merged_df.reset_index(inplace=True, drop=True)
|
||||
print("合约代码:", merged_df["合约代码"])
|
||||
|
||||
# 插入新的数据
|
||||
# code_value = csv_files[0].split
|
||||
# merged_df.insert(loc=1,column="统一代码", value="rb888")
|
||||
alpha_chars, numeric_chars = split_alpha_numeric(merged_df["合约代码"][0])
|
||||
print("Alphabetical characters:", alpha_chars)
|
||||
# print("Numerical characters:", numeric_chars[1])
|
||||
|
||||
# 添加主力连续的合约代码,主力连续为888,指数连续可以用999,次主力连续可以使用889,表头用“统一代码”
|
||||
code_value = alpha_chars + "888"
|
||||
print("code_value characters:", code_value)
|
||||
merged_df.insert(loc=1,column="统一代码", value=code_value)
|
||||
|
||||
|
||||
# 将合并后的数据保存到csv文件中
|
||||
folder_path = "合成tick数据2019-2021"
|
||||
if not os.path.exists(folder_path):
|
||||
os.mkdir('合成tick数据2019-2021')
|
||||
|
||||
# sorted_merged_df = merged_df.sort_values(by= ['业务日期','最后修改时间','最后修改毫秒'], ascending=[True, True, True])
|
||||
# sorted_merged_df.to_csv('./合成tick数据/%s.csv'%(code_value), index=False)
|
||||
|
||||
merged_df['时间'] = pd.to_datetime(merged_df['时间'])
|
||||
sorted_merged_df = merged_df.sort_values(by = ['时间'], ascending=True)
|
||||
sorted_merged_df.to_csv('./合成tick数据2019-2021/%s%s.csv'%(code_value,sp_char), index=False)
|
||||
del merged_df
|
||||
del sorted_merged_df
|
||||
#merged_df.to_csv('./合成tick数据/%s.csv'%(code_value), index=False) #数据按照时间排序,前面文件夹按照时间修改好了可以直接用这里
|
||||
|
||||
# 打印提示信息
|
||||
print("CSV文件合并成功!")
|
||||
@@ -0,0 +1,134 @@
|
||||
'''
|
||||
Author: zhoujie2104231 zhoujie@me.com
|
||||
# Date: 2024-02-25 17:51:46
|
||||
LastEditors: zhoujie2104231 zhoujie@me.com
|
||||
LastEditTime: 2024-03-17 16:59:35
|
||||
# 使用说明:使用前需要调整的相关参数如下
|
||||
# 1.确定python到csv文件夹下运行,
|
||||
# 2.统一代码的添加:主力连续为888,指数连续可以用999,次主力连续可以使用889,其他的可以不用添加统一代码,注释掉。
|
||||
# 3.文件夹下的文件名按照datetime进行排序修改
|
||||
# 4.data按照时间排序需要根据参数修改['业务日期','最后修改时间','最后修改毫秒'],如果前面文件名按照时间修改好了,不用修改
|
||||
# 5.使用gbk或者utf-8编译
|
||||
'''
|
||||
|
||||
import pandas as pd
|
||||
import os
|
||||
|
||||
# import datetime as dt
|
||||
|
||||
def split_alpha_numeric(string):
|
||||
"""
|
||||
Split a string into alphabetical and numerical characters.
|
||||
|
||||
Args:
|
||||
string: The string to split.
|
||||
|
||||
Returns:
|
||||
A tuple containing two strings, the first containing the alphabetical
|
||||
characters and the second containing the numerical characters.
|
||||
"""
|
||||
|
||||
alpha_chars = ""
|
||||
numeric_chars = ""
|
||||
|
||||
for char in string:
|
||||
if char.isalpha():
|
||||
alpha_chars += char
|
||||
elif char.isdigit():
|
||||
numeric_chars += char
|
||||
|
||||
return alpha_chars, numeric_chars
|
||||
|
||||
#第一中方法:
|
||||
# 获取当前目录下的所有csv文件
|
||||
all_csv_files = [file for file in os.listdir('.') if file.endswith('.csv')]
|
||||
|
||||
# csv需要筛选的文件名字符
|
||||
sp_char = '_2023'
|
||||
|
||||
# 获取当前目录下的所有文件名包含sp_char的csv文件
|
||||
csv_files = [sp_file for sp_file in all_csv_files if sp_char in sp_file]
|
||||
print("csv_files:", csv_files)
|
||||
|
||||
# 另一种遍历方式
|
||||
# folder_path = "D:/data_transfer/ag888"
|
||||
|
||||
# name_chr = "202309"
|
||||
# csv_files = []
|
||||
|
||||
# for root, dirs, files in os.walk(folder_path):
|
||||
# for file in files:
|
||||
# if file.endswith('.csv'):
|
||||
# # 获取文件名(不包含扩展名)
|
||||
# filename = os.path.splitext(file)[0]
|
||||
# match_file = re.search(r'(?<=^.{7}).{6}(?=.{2})',filename)
|
||||
# try:
|
||||
# if match_file.group() == name_chr:#
|
||||
# full_filename = filename + ".csv"
|
||||
# csv_files.append(full_filename)
|
||||
# else:
|
||||
# #print("文件夹中有csv文件,但没有文件名含%s的csv文件"%(name_chr))
|
||||
# pass
|
||||
# except AttributeError:
|
||||
# continue
|
||||
# else:
|
||||
# #print("文件夹中没有csv文件")
|
||||
# pass
|
||||
|
||||
|
||||
# 将当前的数据按照文件名进行排序,生成list文件
|
||||
#csv_files.sort(key=lambda x: int(x.split('.')[0]))
|
||||
|
||||
# 创建新的DataFrame来存储合并后的数据
|
||||
merged_df = pd.DataFrame()
|
||||
|
||||
# 循环遍历每个csv文件
|
||||
for file in csv_files:
|
||||
# 读取csv文件,并使用第一行为列标题,编译不通过可以改为gbk
|
||||
df = pd.read_csv(file, header=0, encoding='gbk')
|
||||
|
||||
# 删除重复行
|
||||
df.drop_duplicates(inplace=True)
|
||||
|
||||
# 将数据合并到新的DataFrame中
|
||||
merged_df = pd.concat([merged_df, df], ignore_index=True)
|
||||
|
||||
# 删除重复列
|
||||
merged_df.drop_duplicates(subset=merged_df.columns.tolist(), inplace=True)
|
||||
|
||||
# 重置行索引
|
||||
merged_df.reset_index(inplace=True, drop=True)
|
||||
print("合约代码:", merged_df["合约代码"])
|
||||
|
||||
# 插入新的数据
|
||||
# code_value = csv_files[0].split
|
||||
# merged_df.insert(loc=1,column="统一代码", value="rb888")
|
||||
alpha_chars, numeric_chars = split_alpha_numeric(merged_df["合约代码"][0])
|
||||
print("Alphabetical characters:", alpha_chars)
|
||||
# print("Numerical characters:", numeric_chars[1])
|
||||
|
||||
# 添加主力连续的合约代码,主力连续为888,指数连续可以用999,次主力连续可以使用889,表头用“统一代码”
|
||||
code_value = alpha_chars + "888"
|
||||
print("code_value characters:", code_value)
|
||||
merged_df.insert(loc=1,column="统一代码", value=code_value)
|
||||
|
||||
|
||||
# 将合并后的数据保存到csv文件中
|
||||
folder_path = "合成tick数据2022-2023"
|
||||
if not os.path.exists(folder_path):
|
||||
os.mkdir('合成tick数据2022-2023')
|
||||
|
||||
sorted_merged_df = merged_df.sort_values(by= ['业务日期','最后修改时间','最后修改毫秒'], ascending=[True, True, True])
|
||||
sorted_merged_df.to_csv('./合成tick数据2022-2023/%s%s.csv'%(code_value,sp_char), index=False)
|
||||
|
||||
del merged_df
|
||||
del sorted_merged_df
|
||||
|
||||
# merged_df['时间'] = pd.to_datetime(merged_df['时间'])
|
||||
# sorted_merged_df = merged_df.sort_values(by = ['时间'], ascending=True)
|
||||
# sorted_merged_df.to_csv('./合成tick数据/%s.csv'%(code_value), index=False)
|
||||
|
||||
#merged_df.to_csv('./合成tick数据/%s.csv'%(code_value), index=False) #数据按照时间排序,前面文件夹按照时间修改好了可以直接用这里
|
||||
|
||||
# 打印提示信息
|
||||
print("CSV文件合并成功!")
|
||||
@@ -0,0 +1,526 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import os"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"root_path = r\"C:/Users/zhouj/Desktop/data\"\n",
|
||||
"output_path = r\"C:/Users/zhouj/Desktop/a88.csv\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 等差复权\n",
|
||||
"adjust = df['close'].shift() - df['open']\n",
|
||||
"adjust = np.where(df['symbol'] != df['symbol'].shift(), adjust, 0)\n",
|
||||
"df['open_adj'] = df['open'] + adjust.cumsum()\n",
|
||||
"df['close_adj'] = df['close'] + adjust.cumsum()\n",
|
||||
"df['low_adj'] = df['low'] + adjust.cumsum()\n",
|
||||
"df['high_adj'] = df['high'] + adjust.cumsum()\n",
|
||||
"# 等比复权\n",
|
||||
"adjust = df['close'].shift() / df['open']\n",
|
||||
"adjust = np.where(df['symbol'] != df['symbol'].shift(), adjust, 1)\n",
|
||||
"df['open_adj'] = df['open'] * adjust.cumprod()\n",
|
||||
"df['close_adj'] = df['close'] * adjust.cumprod()\n",
|
||||
"df['low_adj'] = df['low'] * adjust.cumprod()\n",
|
||||
"df['high_adj'] = df['high'] * adjust.cumprod()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"files = []\n",
|
||||
"\n",
|
||||
"for r, ds, fs in os.walk(root_path):\n",
|
||||
" for f in fs:\n",
|
||||
" # if f[0:4] == '2023':\n",
|
||||
" abs_filepath = os.path.join(r, f)\n",
|
||||
" files.append(abs_filepath)\n",
|
||||
"files = sorted(files)\n",
|
||||
"\n",
|
||||
"df = pd.DataFrame()\n",
|
||||
"for f in files:\n",
|
||||
" df_temp = pd.read_csv(\n",
|
||||
" f,\n",
|
||||
" usecols=[1, 2, 3, 4, 8, 13, 14, 15, 16],\n",
|
||||
" names=[\n",
|
||||
" \"统一代码\",\n",
|
||||
" \"合约代码\",\n",
|
||||
" \"时间\",\n",
|
||||
" \"最新\",\n",
|
||||
" \"成交量\",\n",
|
||||
" \"买一价\",\n",
|
||||
" \"卖一价\",\n",
|
||||
" \"买一量\",\n",
|
||||
" \"卖一量\",\n",
|
||||
" ],\n",
|
||||
" skiprows=1,\n",
|
||||
" encoding=\"utf-8\",\n",
|
||||
" )\n",
|
||||
" # df_temp = pd.read_csv(f, usecols=[0,5], names=[\n",
|
||||
" # 'datetime', 'volume'])\n",
|
||||
" df = pd.concat([df, df_temp])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# files = []\n",
|
||||
"\n",
|
||||
"# for r, ds, fs in os.walk(root_path):\n",
|
||||
"# for f in fs:\n",
|
||||
"# # if f[0:4] == '2023':\n",
|
||||
"# abs_filepath = os.path.join(r, f)\n",
|
||||
"# files.append(abs_filepath)\n",
|
||||
"# files = sorted(files)\n",
|
||||
"\n",
|
||||
"# df = pd.DataFrame()\n",
|
||||
"# for f in files:\n",
|
||||
"# df_temp = pd.read_csv(\n",
|
||||
"# f,\n",
|
||||
"# usecols=[0, 1, 4, 11, 20, 21, 22, 23, 24, 25],\n",
|
||||
"# names=[\n",
|
||||
"# \"交易日\",\n",
|
||||
"# \"合约代码\",\n",
|
||||
"# \"最新价\",\n",
|
||||
"# \"数量\",\n",
|
||||
"# \"最后修改时间\",\n",
|
||||
"# \"最后修改毫秒\",\n",
|
||||
"# \"申买价一\",\n",
|
||||
"# \"申买量一\",\n",
|
||||
"# \"申卖价一\",\n",
|
||||
"# \"申卖量一\",\n",
|
||||
"# ],\n",
|
||||
"# skiprows=1,\n",
|
||||
"# encoding=\"gbk\",\n",
|
||||
"# )\n",
|
||||
"# # df_temp = pd.read_csv(f, usecols=[0,5], names=[\n",
|
||||
"# # 'datetime', 'volume'])\n",
|
||||
"# df = pd.concat([df, df_temp])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.reset_index(drop=True, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.info()\n",
|
||||
"# 21754840"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" 统一代码 合约代码 时间 最新 成交量 买一价 卖一价 \\\n",
|
||||
"1305669 a888 a1905 2019-04-22 15:00:00.568 3309.0 0 3308.0 3311.0 \n",
|
||||
"1305670 a888 a1905 2019-04-22 15:00:36.638 3309.0 0 3308.0 3311.0 \n",
|
||||
"1305671 a888 a1909 2019-04-22 20:59:00.014 3412.0 224 3411.0 3412.0 \n",
|
||||
"1305672 a888 a1909 2019-04-22 21:00:00.461 3412.0 108 3412.0 3413.0 \n",
|
||||
"1305673 a888 a1909 2019-04-22 21:00:00.958 3411.0 150 3410.0 3411.0 \n",
|
||||
"\n",
|
||||
" 买一量 卖一量 \n",
|
||||
"1305669 25 10 \n",
|
||||
"1305670 25 10 \n",
|
||||
"1305671 2 8 \n",
|
||||
"1305672 10 19 \n",
|
||||
"1305673 43 3 \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(df.loc[1305669:1305673])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 等比复权\n",
|
||||
"# df['复权因子'] = df['卖一价'].shift() / df['买一价']\n",
|
||||
"df['复权因子'] = np.where(df['合约代码'] != df['合约代码'].shift(), df['卖一价'].shift() / df['买一价'], 1)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(1)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['买一价_adj'] = df['买一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['卖一价_adj'] = df['卖一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['最新_adj'] = df['最新'] * df['复权因子'].cumprod()\n",
|
||||
"# df['low_adj'] = df['low'] * adjust.cumprod()\n",
|
||||
"# df['high_adj'] = df['high'] * adjust.cumprod()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 等差复权\n",
|
||||
"df['复权因子'] = np.where(df['合约代码'] != df['合约代码'].shift(), df['卖一价'].shift() - df['买一价'], 0)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(0)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['买一价_adj'] = df['买一价'] + df['复权因子'].cumsum()\n",
|
||||
"df['卖一价_adj'] = df['卖一价'] + df['复权因子'].cumsum()\n",
|
||||
"df['最新_adj'] = df['最新'] + df['复权因子'].cumsum()\n",
|
||||
"# df['low_adj'] = df['low'] + df['复权因子'].cumsum()\n",
|
||||
"# df['high_adj'] = df['high'] + df['复权因子'].cumsum()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" 统一代码 合约代码 时间 最新 成交量 买一价 卖一价 \\\n",
|
||||
"1305669 a888 a1905 2019-04-22 15:00:00.568 3309.0 0 3308.0 3311.0 \n",
|
||||
"1305670 a888 a1905 2019-04-22 15:00:36.638 3309.0 0 3308.0 3311.0 \n",
|
||||
"1305671 a888 a1909 2019-04-22 20:59:00.014 3412.0 224 3411.0 3412.0 \n",
|
||||
"1305672 a888 a1909 2019-04-22 21:00:00.461 3412.0 108 3412.0 3413.0 \n",
|
||||
"1305673 a888 a1909 2019-04-22 21:00:00.958 3411.0 150 3410.0 3411.0 \n",
|
||||
"\n",
|
||||
" 买一量 卖一量 复权因子 买一价_adj 卖一价_adj 最新_adj \n",
|
||||
"1305669 25 10 0.0 3308.0 3311.0 3309.0 \n",
|
||||
"1305670 25 10 0.0 3308.0 3311.0 3309.0 \n",
|
||||
"1305671 2 8 -100.0 3311.0 3312.0 3312.0 \n",
|
||||
"1305672 10 19 0.0 3312.0 3313.0 3312.0 \n",
|
||||
"1305673 43 3 0.0 3310.0 3311.0 3311.0 \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(df.loc[1305669:1305673])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['买一价'] = df['买一价_adj']\n",
|
||||
"df['卖一价'] = df['卖一价_adj']\n",
|
||||
"df['最新'] = df['最新_adj']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" 统一代码 合约代码 时间 最新 成交量 买一价 卖一价 \\\n",
|
||||
"1305669 a888 a1905 2019-04-22 15:00:00.568 3309.0 0 3308.0 3311.0 \n",
|
||||
"1305670 a888 a1905 2019-04-22 15:00:36.638 3309.0 0 3308.0 3311.0 \n",
|
||||
"1305671 a888 a1909 2019-04-22 20:59:00.014 3312.0 224 3311.0 3312.0 \n",
|
||||
"1305672 a888 a1909 2019-04-22 21:00:00.461 3312.0 108 3312.0 3313.0 \n",
|
||||
"1305673 a888 a1909 2019-04-22 21:00:00.958 3311.0 150 3310.0 3311.0 \n",
|
||||
"\n",
|
||||
" 买一量 卖一量 复权因子 买一价_adj 卖一价_adj 最新_adj \n",
|
||||
"1305669 25 10 0.0 3308.0 3311.0 3309.0 \n",
|
||||
"1305670 25 10 0.0 3308.0 3311.0 3309.0 \n",
|
||||
"1305671 2 8 -100.0 3311.0 3312.0 3312.0 \n",
|
||||
"1305672 10 19 0.0 3312.0 3313.0 3312.0 \n",
|
||||
"1305673 43 3 0.0 3310.0 3311.0 3311.0 \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(df.loc[1305669:1305673])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# df.drop('复权因子', axis=1)\n",
|
||||
"# df.drop('买一价_adj', axis=1)\n",
|
||||
"# df.drop('卖一价_adj', axis=1)\n",
|
||||
"del df['复权因子']\n",
|
||||
"del df['买一价_adj']\n",
|
||||
"del df['卖一价_adj']\n",
|
||||
"del df['最新_adj']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" 统一代码 合约代码 时间 最新 成交量 买一价 卖一价 \\\n",
|
||||
"1305670 a888 a1905 2019-04-22 15:00:36.638 3309.0 0 3308.0 3311.0 \n",
|
||||
"1305671 a888 a1909 2019-04-22 20:59:00.014 3312.0 224 3311.0 3312.0 \n",
|
||||
"1305672 a888 a1909 2019-04-22 21:00:00.461 3312.0 108 3312.0 3313.0 \n",
|
||||
"1305673 a888 a1909 2019-04-22 21:00:00.958 3311.0 150 3310.0 3311.0 \n",
|
||||
"1305674 a888 a1909 2019-04-22 21:00:01.464 3312.0 86 3311.0 3312.0 \n",
|
||||
"\n",
|
||||
" 买一量 卖一量 \n",
|
||||
"1305670 25 10 \n",
|
||||
"1305671 2 8 \n",
|
||||
"1305672 10 19 \n",
|
||||
"1305673 43 3 \n",
|
||||
"1305674 18 80 \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(df.loc[1305670:1305674])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.to_csv(output_path, index=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"drop_index1 = df.query('最后修改时间>\"15:00:00\" & 最后修改时间<\"21:00:00\"')[\n",
|
||||
" \"最后修改时间\"\n",
|
||||
"].index\n",
|
||||
"# drop_index1 = df.query('最后修改时间>\"15:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index2 = df.query('最后修改时间>\"01:00:00\" & 最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index2 = df.query('最后修改时间>\"01:00:00\" & 最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"drop_index2 = df.query('最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"drop_index3 = df.query('最后修改时间>\"23:00:00\" & 最后修改时间<\"23:59:59\"')[\n",
|
||||
" \"最后修改时间\"\n",
|
||||
"].index\n",
|
||||
"drop_index4 = df.query('最后修改时间>\"11:30:00\" & 最后修改时间<\"13:30:00\"')[\n",
|
||||
" \"最后修改时间\"\n",
|
||||
"].index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.drop(labels=drop_index1, axis=0, inplace=True)\n",
|
||||
"df.drop(drop_index2, axis=0, inplace=True)\n",
|
||||
"df.drop(drop_index3, axis=0, inplace=True)\n",
|
||||
"df.drop(drop_index4, axis=0, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.reset_index(drop=True, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"datetime\"] = pd.to_datetime(\n",
|
||||
" pd.to_datetime(df[\"交易日\"].astype(str)).astype(str)\n",
|
||||
" + \" \"\n",
|
||||
" + df[\"最后修改时间\"].astype(str)\n",
|
||||
" + \".\"\n",
|
||||
" + df[\"最后修改毫秒\"].astype(str)\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.rename(\n",
|
||||
" columns={\n",
|
||||
" \"最新价\": \"lastprice\",\n",
|
||||
" \"数量\": \"volume\",\n",
|
||||
" \"申买价一\": \"bid_p\",\n",
|
||||
" \"申买量一\": \"bid_v\",\n",
|
||||
" \"申卖价一\": \"ask_p\",\n",
|
||||
" \"申卖量一\": \"ask_v\",\n",
|
||||
" \"合约代码\": \"symbol\",\n",
|
||||
" },\n",
|
||||
" inplace=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"vol_diff\"] = df[\"volume\"].diff()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[df[\"vol_diff\"].isnull(), \"vol_diff\"] = df.loc[df[\"vol_diff\"].isnull(), \"volume\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"volume\"] = df[\"vol_diff\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.to_csv(output_path)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "orderflow",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 使用说明:\n",
|
||||
" 1.需要修改chdir到当前目录\n",
|
||||
" 2.需要修改最后输出的文件名称\n",
|
||||
" 3.依据情况需要修改保留的列数"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"import os"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"文件中所有CSV文件: ['ag888_2019.csv', 'ag888_2020.csv', 'ag888_2021.csv', 'ag888_2022.csv', 'ag888_2022_2023.csv', 'ag888_2023.csv']\n",
|
||||
"需要筛选的文件名关键字: ['_2022']\n",
|
||||
"使用新年份格式采集!!!\n",
|
||||
"筛选结果后的CSV文件: ['ag888_2022.csv', 'ag888_2022_2023.csv']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"os.chdir('E:/data/ag')\n",
|
||||
"all_csv_files = [file for file in os.listdir('.') if file.endswith('.csv')]\n",
|
||||
"all_csv_files = sorted(all_csv_files)\n",
|
||||
"print(\"文件中所有CSV文件:\",all_csv_files)\n",
|
||||
"\n",
|
||||
"sp_chars = ['_2022']\n",
|
||||
"sp_chars = sorted(sp_chars)\n",
|
||||
"print(\"需要筛选的文件名关键字:\",sp_chars)\n",
|
||||
"\n",
|
||||
"# 设置后面数据的采集对于的行数# 用 \"old_type\" 或者 \"new_type\" 区分\n",
|
||||
"if all(char in ['_2019','_2020','_2021'] for char in sp_chars):\n",
|
||||
" year_type = 'old_type'\n",
|
||||
" print(\"使用旧年份格式采集!!!\")\n",
|
||||
"elif all(char in ['_2022','_2023'] for char in sp_chars):\n",
|
||||
" year_type = 'new_type' \n",
|
||||
" print(\"使用新年份格式采集!!!\")\n",
|
||||
"else:\n",
|
||||
" print(\"文件夹中CSV没有相关年份的数据或者新旧年份混用!!!\")\n",
|
||||
"\n",
|
||||
"csv_files = [file for file in all_csv_files if any(sp_char in file for sp_char in sp_chars)]\n",
|
||||
"print(\"筛选结果后的CSV文件:\",csv_files)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.DataFrame()\n",
|
||||
"for f in csv_files:\n",
|
||||
" if year_type == 'old_type':\n",
|
||||
" df_temp = pd.read_csv(\n",
|
||||
" f,\n",
|
||||
" usecols=[1, 2, 3, 4, 8, 13, 14, 15, 16],\n",
|
||||
" names=[\n",
|
||||
" \"统一代码\",\n",
|
||||
" \"合约代码\",\n",
|
||||
" \"时间\",\n",
|
||||
" \"最新\",\n",
|
||||
" \"成交量\",\n",
|
||||
" \"买一价\",\n",
|
||||
" \"卖一价\",\n",
|
||||
" \"买一量\",\n",
|
||||
" \"卖一量\",\n",
|
||||
" ],\n",
|
||||
" skiprows=1,\n",
|
||||
" encoding=\"utf-8\",\n",
|
||||
" )\n",
|
||||
" elif year_type == 'new_type':\n",
|
||||
" df_temp = pd.read_csv(\n",
|
||||
" f,\n",
|
||||
" usecols=[0, 1, 2, 5, 12, 21, 22, 23, 24, 25, 26, 44],\n",
|
||||
" names=[\n",
|
||||
" \"交易日\",\n",
|
||||
" \"统一代码\",\n",
|
||||
" \"合约代码\",\n",
|
||||
" \"最新价\",\n",
|
||||
" \"数量\",\n",
|
||||
" \"最后修改时间\",\n",
|
||||
" \"最后修改毫秒\",\n",
|
||||
" \"申买价一\",\n",
|
||||
" \"申买量一\",\n",
|
||||
" \"申卖价一\",\n",
|
||||
" \"申卖量一\",\n",
|
||||
" \"业务日期\",\n",
|
||||
" ],\n",
|
||||
" skiprows=1,\n",
|
||||
" encoding=\"utf-8\",\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # df_temp = pd.read_csv(f, usecols=[0,5], names=[\n",
|
||||
" # 'datetime', 'volume'])\n",
|
||||
" df = pd.concat([df, df_temp])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 查看数据的头部和尾部:head()、tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.reset_index(drop=True, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查看dataframe的基本情况\n",
|
||||
"df.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 等比复权,先不考虑\n",
|
||||
"# df['复权因子'] = df['卖一价'].shift() / df['买一价']\n",
|
||||
"df['复权因子'] = np.where(df['合约代码'] != df['合约代码'].shift(), df['卖一价'].shift() / df['买一价'], 1)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(1)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['买一价_adj'] = df['买一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['卖一价_adj'] = df['卖一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['最新_adj'] = df['最新'] * df['复权因子'].cumprod()\n",
|
||||
"# df['low_adj'] = df['low'] * adjust.cumprod()\n",
|
||||
"# df['high_adj'] = df['high'] * adjust.cumprod()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 等差复权\n",
|
||||
"df['复权因子'] = np.where(df['合约代码'] != df['合约代码'].shift(), df['申卖价一'].shift() - df['申买价一'], 0)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(0)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['申买价一_adj'] = df['申买价一'] + df['复权因子'].cumsum()\n",
|
||||
"df['申卖价一_adj'] = df['申卖价一'] + df['复权因子'].cumsum()\n",
|
||||
"df['最新价_adj'] = df['最新价'] + df['复权因子'].cumsum()\n",
|
||||
"# df['low_adj'] = df['low'] + df['复权因子'].cumsum()\n",
|
||||
"# df['high_adj'] = df['high'] + df['复权因子'].cumsum()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查找换期需要复权的索引\n",
|
||||
"non_zero_indices = df[df['复权因子'] != 0].index\n",
|
||||
"print(non_zero_indices)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查看未调整买价、卖价和最新价的数据\n",
|
||||
"df.loc[non_zero_indices[0]-5:non_zero_indices[0]+5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 将调整后的数值替换原来的值\n",
|
||||
"df['申买价一'] = df['申买价一_adj']\n",
|
||||
"df['申卖价一'] = df['申卖价一_adj']\n",
|
||||
"df['最新价'] = df['最新价_adj']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查看调整买价、卖价和最新价的数据\n",
|
||||
"df.loc[non_zero_indices[0]-5:non_zero_indices[0]+5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 删除多余的值\n",
|
||||
"del df['复权因子']\n",
|
||||
"del df['申买价一_adj']\n",
|
||||
"del df['申卖价一_adj']\n",
|
||||
"del df['最新价_adj']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[non_zero_indices[0]-5:non_zero_indices[0]+5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.to_csv('./ag888_2022_2023.csv', index=False)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "orderflow",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,428 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import os"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"root_path = r\"E:/data/ag\"\n",
|
||||
"output_path = r\"E:/data/ag/ag888.csv\"\n",
|
||||
"# df_tmp = pd.read_csv('E:/data/rb/rb888_2023.csv',encoding=\"utf-8\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"files = []\n",
|
||||
"\n",
|
||||
"for r, ds, fs in os.walk(root_path):\n",
|
||||
" for f in fs:\n",
|
||||
" # if f[0:4] == '2023':\n",
|
||||
" abs_filepath = os.path.join(r, f)\n",
|
||||
" files.append(abs_filepath)\n",
|
||||
"files = sorted(files)\n",
|
||||
"\n",
|
||||
"df = pd.DataFrame()\n",
|
||||
"for f in files:\n",
|
||||
" df_temp = pd.read_csv(\n",
|
||||
" f,\n",
|
||||
" usecols=[0, 1, 2, 5, 12, 21, 22, 23, 24, 25, 26, 44],\n",
|
||||
" names=[\n",
|
||||
" \"交易日\",\n",
|
||||
" \"统一代码\",\n",
|
||||
" \"合约代码\",\n",
|
||||
" \"最新价\",\n",
|
||||
" \"数量\",\n",
|
||||
" \"最后修改时间\",\n",
|
||||
" \"最后修改毫秒\",\n",
|
||||
" \"申买价一\",\n",
|
||||
" \"申买量一\",\n",
|
||||
" \"申卖价一\",\n",
|
||||
" \"申卖量一\",\n",
|
||||
" \"业务日期\",\n",
|
||||
" ],\n",
|
||||
" skiprows=1,\n",
|
||||
" encoding=\"utf-8\",\n",
|
||||
" )\n",
|
||||
" # df_temp = pd.read_csv(f, usecols=[0,5], names=[\n",
|
||||
" # 'datetime', 'volume'])\n",
|
||||
" df = pd.concat([df, df_temp])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#df_tmp = pd.read_csv('E:/data/rb/rb888_2023.csv',encoding=\"utf-8\")\n",
|
||||
"#df_tmp.tail()\n",
|
||||
"#df_tmp.tail().to_csv(\"E:/data/rb/rb_tail.csv\",index= False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.reset_index(drop=True, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.info()\n",
|
||||
"# 21754840"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[2493107:2493111]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 等比复权,先不考虑\n",
|
||||
"# df['复权因子'] = df['卖一价'].shift() / df['买一价']\n",
|
||||
"df['复权因子'] = np.where(df['合约代码'] != df['合约代码'].shift(), df['卖一价'].shift() / df['买一价'], 1)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(1)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['买一价_adj'] = df['买一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['卖一价_adj'] = df['卖一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['最新_adj'] = df['最新'] * df['复权因子'].cumprod()\n",
|
||||
"# df['low_adj'] = df['low'] * adjust.cumprod()\n",
|
||||
"# df['high_adj'] = df['high'] * adjust.cumprod()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 等差复权\n",
|
||||
"df['复权因子'] = np.where(df['合约代码'] != df['合约代码'].shift(), df['申卖价一'].shift() - df['申买价一'], 0)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(0)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['申买价一_adj'] = df['申买价一'] + df['复权因子'].cumsum()\n",
|
||||
"df['申卖价一_adj'] = df['申卖价一'] + df['复权因子'].cumsum()\n",
|
||||
"df['最新价_adj'] = df['最新价'] + df['复权因子'].cumsum()\n",
|
||||
"# df['low_adj'] = df['low'] + df['复权因子'].cumsum()\n",
|
||||
"# df['high_adj'] = df['high'] + df['复权因子'].cumsum()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[391880:391890]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['申买价一'] = df['申买价一_adj']\n",
|
||||
"df['申卖价一'] = df['申卖价一_adj']\n",
|
||||
"df['最新价'] = df['最新价_adj']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[391880:391890]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"non_zero_indices = df[df['复权因子'] != 0].index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(non_zero_indices)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# df.drop('复权因子', axis=1)\n",
|
||||
"# df.drop('买一价_adj', axis=1)\n",
|
||||
"# df.drop('卖一价_adj', axis=1)\n",
|
||||
"del df['复权因子']\n",
|
||||
"del df['申买价一_adj']\n",
|
||||
"del df['申卖价一_adj']\n",
|
||||
"del df['最新价_adj']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[391880:391890]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.to_csv(output_path, index=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head().to_csv(\"E:/data/rb/rb_ch_temp.csv\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"drop_index1 = df.query('最后修改时间>\"15:00:00\" & 最后修改时间<\"21:00:00\"')[\n",
|
||||
" \"最后修改时间\"\n",
|
||||
"].index\n",
|
||||
"# drop_index1 = df.query('最后修改时间>\"15:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index2 = df.query('最后修改时间>\"01:00:00\" & 最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index2 = df.query('最后修改时间>\"01:00:00\" & 最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"drop_index2 = df.query('最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"drop_index3 = df.query('最后修改时间>\"23:00:00\" & 最后修改时间<\"23:59:59\"')[\n",
|
||||
" \"最后修改时间\"\n",
|
||||
"].index\n",
|
||||
"drop_index4 = df.query('最后修改时间>\"11:30:00\" & 最后修改时间<\"13:30:00\"')[\n",
|
||||
" \"最后修改时间\"\n",
|
||||
"].index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.drop(labels=drop_index1, axis=0, inplace=True)\n",
|
||||
"df.drop(drop_index2, axis=0, inplace=True)\n",
|
||||
"df.drop(drop_index3, axis=0, inplace=True)\n",
|
||||
"df.drop(drop_index4, axis=0, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.reset_index(drop=True, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"datetime\"] = pd.to_datetime(\n",
|
||||
" pd.to_datetime(df[\"交易日\"].astype(str)).astype(str)\n",
|
||||
" + \" \"\n",
|
||||
" + df[\"最后修改时间\"].astype(str)\n",
|
||||
" + \".\"\n",
|
||||
" + df[\"最后修改毫秒\"].astype(str)\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.rename(\n",
|
||||
" columns={\n",
|
||||
" \"最新价\": \"lastprice\",\n",
|
||||
" \"数量\": \"volume\",\n",
|
||||
" \"申买价一\": \"bid_p\",\n",
|
||||
" \"申买量一\": \"bid_v\",\n",
|
||||
" \"申卖价一\": \"ask_p\",\n",
|
||||
" \"申卖量一\": \"ask_v\",\n",
|
||||
" \"合约代码\": \"symbol\",\n",
|
||||
" },\n",
|
||||
" inplace=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"vol_diff\"] = df[\"volume\"].diff()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[df[\"vol_diff\"].isnull(), \"vol_diff\"] = df.loc[df[\"vol_diff\"].isnull(), \"volume\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"volume\"] = df[\"vol_diff\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.to_csv(output_path)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "orderflow",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"import os"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"os.chdir('E:/data/ag')\n",
|
||||
"all_csv_files = [file for file in os.listdir('.') if file.endswith('.csv')]\n",
|
||||
"all_csv_files = sorted(all_csv_files)\n",
|
||||
"print(\"文件中所有CSV文件:\",all_csv_files)\n",
|
||||
"\n",
|
||||
"sp_chars = ['_2023','_2022']\n",
|
||||
"sp_chars = sorted(sp_chars)\n",
|
||||
"print(\"需要筛选的文件名关键字:\",sp_chars)\n",
|
||||
"\n",
|
||||
"csv_files = [file for file in all_csv_files if any(sp_char in file for sp_char in sp_chars)]\n",
|
||||
"print(\"筛选结果后的CSV文件:\",csv_files)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.DataFrame()\n",
|
||||
"for f in csv_files:\n",
|
||||
" df_temp = pd.read_csv(\n",
|
||||
" f,\n",
|
||||
" usecols=[0, 1, 2, 5, 12, 21, 22, 23, 24, 25, 26, 44],\n",
|
||||
" names=[\n",
|
||||
" \"交易日\",\n",
|
||||
" \"统一代码\",\n",
|
||||
" \"合约代码\",\n",
|
||||
" \"最新价\",\n",
|
||||
" \"数量\",\n",
|
||||
" \"最后修改时间\",\n",
|
||||
" \"最后修改毫秒\",\n",
|
||||
" \"申买价一\",\n",
|
||||
" \"申买量一\",\n",
|
||||
" \"申卖价一\",\n",
|
||||
" \"申卖量一\",\n",
|
||||
" \"业务日期\",\n",
|
||||
" ],\n",
|
||||
" skiprows=1,\n",
|
||||
" encoding=\"utf-8\",\n",
|
||||
" )\n",
|
||||
" # df_temp = pd.read_csv(f, usecols=[0,5], names=[\n",
|
||||
" # 'datetime', 'volume'])\n",
|
||||
" df = pd.concat([df, df_temp])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 查看数据的头部和尾部:head()、tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.reset_index(drop=True, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查看dataframe的基本情况\n",
|
||||
"df.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 等比复权,先不考虑\n",
|
||||
"# df['复权因子'] = df['卖一价'].shift() / df['买一价']\n",
|
||||
"df['复权因子'] = np.where(df['合约代码'] != df['合约代码'].shift(), df['卖一价'].shift() / df['买一价'], 1)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(1)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['买一价_adj'] = df['买一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['卖一价_adj'] = df['卖一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['最新_adj'] = df['最新'] * df['复权因子'].cumprod()\n",
|
||||
"# df['low_adj'] = df['low'] * adjust.cumprod()\n",
|
||||
"# df['high_adj'] = df['high'] * adjust.cumprod()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 等差复权\n",
|
||||
"df['复权因子'] = np.where(df['合约代码'] != df['合约代码'].shift(), df['申卖价一'].shift() - df['申买价一'], 0)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(0)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['申买价一_adj'] = df['申买价一'] + df['复权因子'].cumsum()\n",
|
||||
"df['申卖价一_adj'] = df['申卖价一'] + df['复权因子'].cumsum()\n",
|
||||
"df['最新价_adj'] = df['最新价'] + df['复权因子'].cumsum()\n",
|
||||
"# df['low_adj'] = df['low'] + df['复权因子'].cumsum()\n",
|
||||
"# df['high_adj'] = df['high'] + df['复权因子'].cumsum()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查找换期需要复权的索引\n",
|
||||
"non_zero_indices = df[df['复权因子'] != 0].index\n",
|
||||
"print(non_zero_indices)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查看未调整买价、卖价和最新价的数据\n",
|
||||
"df.loc[non_zero_indices[0]-5:non_zero_indices[0]+5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 将调整后的数值替换原来的值\n",
|
||||
"df['申买价一'] = df['申买价一_adj']\n",
|
||||
"df['申卖价一'] = df['申卖价一_adj']\n",
|
||||
"df['最新价'] = df['最新价_adj']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查看调整买价、卖价和最新价的数据\n",
|
||||
"df.loc[non_zero_indices[0]-5:non_zero_indices[0]+5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 删除多余的值\n",
|
||||
"del df['复权因子']\n",
|
||||
"del df['申买价一_adj']\n",
|
||||
"del df['申卖价一_adj']\n",
|
||||
"del df['最新价_adj']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[non_zero_indices[0]-5:non_zero_indices[0]+5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.to_csv('./ag888_2022_2023.csv', index=False)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "orderflow",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,958 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import os"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"root_path = r\".\\tick\\rb\"\n",
|
||||
"output_path = r\".\\data\\rb.csv\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"files = []\n",
|
||||
"\n",
|
||||
"for r, ds, fs in os.walk(root_path):\n",
|
||||
" for f in fs:\n",
|
||||
" # if f[0:4] == '2023':\n",
|
||||
" abs_filepath = os.path.join(r, f)\n",
|
||||
" files.append(abs_filepath)\n",
|
||||
"files = sorted(files)\n",
|
||||
"\n",
|
||||
"df = pd.DataFrame()\n",
|
||||
"for f in files:\n",
|
||||
" df_temp = pd.read_csv(\n",
|
||||
" f,\n",
|
||||
" usecols=[0, 1, 4, 11, 20, 21, 22, 23, 24, 25],\n",
|
||||
" names=[\n",
|
||||
" \"交易日\",\n",
|
||||
" \"合约代码\",\n",
|
||||
" \"最新价\",\n",
|
||||
" \"数量\",\n",
|
||||
" \"最后修改时间\",\n",
|
||||
" \"最后修改毫秒\",\n",
|
||||
" \"申买价一\",\n",
|
||||
" \"申买量一\",\n",
|
||||
" \"申卖价一\",\n",
|
||||
" \"申卖量一\",\n",
|
||||
" ],\n",
|
||||
" skiprows=1,\n",
|
||||
" encoding=\"gbk\",\n",
|
||||
" )\n",
|
||||
" # df_temp = pd.read_csv(f, usecols=[0,5], names=[\n",
|
||||
" # 'datetime', 'volume'])\n",
|
||||
" df = pd.concat([df, df_temp])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>交易日</th>\n",
|
||||
" <th>合约代码</th>\n",
|
||||
" <th>最新价</th>\n",
|
||||
" <th>数量</th>\n",
|
||||
" <th>最后修改时间</th>\n",
|
||||
" <th>最后修改毫秒</th>\n",
|
||||
" <th>申买价一</th>\n",
|
||||
" <th>申买量一</th>\n",
|
||||
" <th>申卖价一</th>\n",
|
||||
" <th>申卖量一</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>41323</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>1201905</td>\n",
|
||||
" <td>14:59:59</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>247</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>116</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>41324</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>1202028</td>\n",
|
||||
" <td>14:59:59</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>224</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>16</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>41325</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>1202060</td>\n",
|
||||
" <td>15:00:00</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>23</td>\n",
|
||||
" <td>4004.0</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>41326</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>1202060</td>\n",
|
||||
" <td>15:00:00</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>23</td>\n",
|
||||
" <td>4004.0</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>41327</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>1202060</td>\n",
|
||||
" <td>15:17:29</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>23</td>\n",
|
||||
" <td>4004.0</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" 交易日 合约代码 最新价 数量 最后修改时间 最后修改毫秒 申买价一 申买量一 \\\n",
|
||||
"41323 20231229 rb2405 4003.0 1201905 14:59:59 0 4002.0 247 \n",
|
||||
"41324 20231229 rb2405 4003.0 1202028 14:59:59 500 4002.0 224 \n",
|
||||
"41325 20231229 rb2405 4002.0 1202060 15:00:00 0 4003.0 23 \n",
|
||||
"41326 20231229 rb2405 4002.0 1202060 15:00:00 500 4003.0 23 \n",
|
||||
"41327 20231229 rb2405 4002.0 1202060 15:17:29 500 4003.0 23 \n",
|
||||
"\n",
|
||||
" 申卖价一 申卖量一 \n",
|
||||
"41323 4003.0 116 \n",
|
||||
"41324 4003.0 16 \n",
|
||||
"41325 4004.0 7 \n",
|
||||
"41326 4004.0 7 \n",
|
||||
"41327 4004.0 7 "
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>交易日</th>\n",
|
||||
" <th>合约代码</th>\n",
|
||||
" <th>最新价</th>\n",
|
||||
" <th>数量</th>\n",
|
||||
" <th>最后修改时间</th>\n",
|
||||
" <th>最后修改毫秒</th>\n",
|
||||
" <th>申买价一</th>\n",
|
||||
" <th>申买量一</th>\n",
|
||||
" <th>申卖价一</th>\n",
|
||||
" <th>申卖量一</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4302.0</td>\n",
|
||||
" <td>4643</td>\n",
|
||||
" <td>08:59:00</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4302.0</td>\n",
|
||||
" <td>115</td>\n",
|
||||
" <td>4305.0</td>\n",
|
||||
" <td>96</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4305.0</td>\n",
|
||||
" <td>5750</td>\n",
|
||||
" <td>09:00:00</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4305.0</td>\n",
|
||||
" <td>359</td>\n",
|
||||
" <td>4310.0</td>\n",
|
||||
" <td>36</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4306.0</td>\n",
|
||||
" <td>8039</td>\n",
|
||||
" <td>09:00:01</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4306.0</td>\n",
|
||||
" <td>18</td>\n",
|
||||
" <td>4308.0</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4308.0</td>\n",
|
||||
" <td>9065</td>\n",
|
||||
" <td>09:00:01</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4308.0</td>\n",
|
||||
" <td>43</td>\n",
|
||||
" <td>4310.0</td>\n",
|
||||
" <td>74</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4310.0</td>\n",
|
||||
" <td>9682</td>\n",
|
||||
" <td>09:00:02</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4311.0</td>\n",
|
||||
" <td>4</td>\n",
|
||||
" <td>4314.0</td>\n",
|
||||
" <td>19</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" 交易日 合约代码 最新价 数量 最后修改时间 最后修改毫秒 申买价一 申买量一 申卖价一 \\\n",
|
||||
"0 20220104 rb2205 4302.0 4643 08:59:00 500 4302.0 115 4305.0 \n",
|
||||
"1 20220104 rb2205 4305.0 5750 09:00:00 500 4305.0 359 4310.0 \n",
|
||||
"2 20220104 rb2205 4306.0 8039 09:00:01 0 4306.0 18 4308.0 \n",
|
||||
"3 20220104 rb2205 4308.0 9065 09:00:01 500 4308.0 43 4310.0 \n",
|
||||
"4 20220104 rb2205 4310.0 9682 09:00:02 0 4311.0 4 4314.0 \n",
|
||||
"\n",
|
||||
" 申卖量一 \n",
|
||||
"0 96 \n",
|
||||
"1 36 \n",
|
||||
"2 7 \n",
|
||||
"3 74 \n",
|
||||
"4 19 "
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.reset_index(drop=True, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"<class 'pandas.core.frame.DataFrame'>\n",
|
||||
"RangeIndex: 19813536 entries, 0 to 19813535\n",
|
||||
"Data columns (total 10 columns):\n",
|
||||
" # Column Dtype \n",
|
||||
"--- ------ ----- \n",
|
||||
" 0 交易日 int64 \n",
|
||||
" 1 合约代码 object \n",
|
||||
" 2 最新价 float64\n",
|
||||
" 3 数量 int64 \n",
|
||||
" 4 最后修改时间 object \n",
|
||||
" 5 最后修改毫秒 int64 \n",
|
||||
" 6 申买价一 float64\n",
|
||||
" 7 申买量一 int64 \n",
|
||||
" 8 申卖价一 float64\n",
|
||||
" 9 申卖量一 int64 \n",
|
||||
"dtypes: float64(3), int64(5), object(2)\n",
|
||||
"memory usage: 1.5+ GB\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.info()\n",
|
||||
"# 21754840"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"drop_index1 = df.query('最后修改时间>\"15:00:00\" & 最后修改时间<\"21:00:00\"')[\n",
|
||||
" \"最后修改时间\"\n",
|
||||
"].index\n",
|
||||
"# drop_index1 = df.query('最后修改时间>\"15:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index2 = df.query('最后修改时间>\"01:00:00\" & 最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index2 = df.query('最后修改时间>\"01:00:00\" & 最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"drop_index2 = df.query('最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"drop_index3 = df.query('最后修改时间>\"23:00:00\" & 最后修改时间<\"23:59:59\"')[\n",
|
||||
" \"最后修改时间\"\n",
|
||||
"].index\n",
|
||||
"drop_index4 = df.query('最后修改时间>\"11:30:00\" & 最后修改时间<\"13:30:00\"')[\n",
|
||||
" \"最后修改时间\"\n",
|
||||
"].index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.drop(labels=drop_index1, axis=0, inplace=True)\n",
|
||||
"df.drop(drop_index2, axis=0, inplace=True)\n",
|
||||
"df.drop(drop_index3, axis=0, inplace=True)\n",
|
||||
"df.drop(drop_index4, axis=0, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>交易日</th>\n",
|
||||
" <th>合约代码</th>\n",
|
||||
" <th>最新价</th>\n",
|
||||
" <th>数量</th>\n",
|
||||
" <th>最后修改时间</th>\n",
|
||||
" <th>最后修改毫秒</th>\n",
|
||||
" <th>申买价一</th>\n",
|
||||
" <th>申买量一</th>\n",
|
||||
" <th>申卖价一</th>\n",
|
||||
" <th>申卖量一</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>19813530</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>1201836</td>\n",
|
||||
" <td>14:59:58</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>288</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>140</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19813531</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>1201905</td>\n",
|
||||
" <td>14:59:59</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>247</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>116</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19813532</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>1202028</td>\n",
|
||||
" <td>14:59:59</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>224</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>16</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19813533</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>1202060</td>\n",
|
||||
" <td>15:00:00</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>23</td>\n",
|
||||
" <td>4004.0</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19813534</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>1202060</td>\n",
|
||||
" <td>15:00:00</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>23</td>\n",
|
||||
" <td>4004.0</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" 交易日 合约代码 最新价 数量 最后修改时间 最后修改毫秒 申买价一 申买量一 \\\n",
|
||||
"19813530 20231229 rb2405 4003.0 1201836 14:59:58 500 4002.0 288 \n",
|
||||
"19813531 20231229 rb2405 4003.0 1201905 14:59:59 0 4002.0 247 \n",
|
||||
"19813532 20231229 rb2405 4003.0 1202028 14:59:59 500 4002.0 224 \n",
|
||||
"19813533 20231229 rb2405 4002.0 1202060 15:00:00 0 4003.0 23 \n",
|
||||
"19813534 20231229 rb2405 4002.0 1202060 15:00:00 500 4003.0 23 \n",
|
||||
"\n",
|
||||
" 申卖价一 申卖量一 \n",
|
||||
"19813530 4003.0 140 \n",
|
||||
"19813531 4003.0 116 \n",
|
||||
"19813532 4003.0 16 \n",
|
||||
"19813533 4004.0 7 \n",
|
||||
"19813534 4004.0 7 "
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"<class 'pandas.core.frame.DataFrame'>\n",
|
||||
"Int64Index: 19812430 entries, 1 to 19813534\n",
|
||||
"Data columns (total 10 columns):\n",
|
||||
" # Column Dtype \n",
|
||||
"--- ------ ----- \n",
|
||||
" 0 交易日 int64 \n",
|
||||
" 1 合约代码 object \n",
|
||||
" 2 最新价 float64\n",
|
||||
" 3 数量 int64 \n",
|
||||
" 4 最后修改时间 object \n",
|
||||
" 5 最后修改毫秒 int64 \n",
|
||||
" 6 申买价一 float64\n",
|
||||
" 7 申买量一 int64 \n",
|
||||
" 8 申卖价一 float64\n",
|
||||
" 9 申卖量一 int64 \n",
|
||||
"dtypes: float64(3), int64(5), object(2)\n",
|
||||
"memory usage: 1.6+ GB\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.reset_index(drop=True, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"datetime\"] = pd.to_datetime(\n",
|
||||
" pd.to_datetime(df[\"交易日\"].astype(str)).astype(str)\n",
|
||||
" + \" \"\n",
|
||||
" + df[\"最后修改时间\"].astype(str)\n",
|
||||
" + \".\"\n",
|
||||
" + df[\"最后修改毫秒\"].astype(str)\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>交易日</th>\n",
|
||||
" <th>合约代码</th>\n",
|
||||
" <th>最新价</th>\n",
|
||||
" <th>数量</th>\n",
|
||||
" <th>最后修改时间</th>\n",
|
||||
" <th>最后修改毫秒</th>\n",
|
||||
" <th>申买价一</th>\n",
|
||||
" <th>申买量一</th>\n",
|
||||
" <th>申卖价一</th>\n",
|
||||
" <th>申卖量一</th>\n",
|
||||
" <th>datetime</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>19812425</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>1201836</td>\n",
|
||||
" <td>14:59:58</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>288</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>140</td>\n",
|
||||
" <td>2023-12-29 14:59:58.500</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19812426</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>1201905</td>\n",
|
||||
" <td>14:59:59</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>247</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>116</td>\n",
|
||||
" <td>2023-12-29 14:59:59.000</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19812427</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>1202028</td>\n",
|
||||
" <td>14:59:59</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>224</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>16</td>\n",
|
||||
" <td>2023-12-29 14:59:59.500</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19812428</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>1202060</td>\n",
|
||||
" <td>15:00:00</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>23</td>\n",
|
||||
" <td>4004.0</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" <td>2023-12-29 15:00:00.000</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19812429</th>\n",
|
||||
" <td>20231229</td>\n",
|
||||
" <td>rb2405</td>\n",
|
||||
" <td>4002.0</td>\n",
|
||||
" <td>1202060</td>\n",
|
||||
" <td>15:00:00</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4003.0</td>\n",
|
||||
" <td>23</td>\n",
|
||||
" <td>4004.0</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" <td>2023-12-29 15:00:00.500</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" 交易日 合约代码 最新价 数量 最后修改时间 最后修改毫秒 申买价一 申买量一 \\\n",
|
||||
"19812425 20231229 rb2405 4003.0 1201836 14:59:58 500 4002.0 288 \n",
|
||||
"19812426 20231229 rb2405 4003.0 1201905 14:59:59 0 4002.0 247 \n",
|
||||
"19812427 20231229 rb2405 4003.0 1202028 14:59:59 500 4002.0 224 \n",
|
||||
"19812428 20231229 rb2405 4002.0 1202060 15:00:00 0 4003.0 23 \n",
|
||||
"19812429 20231229 rb2405 4002.0 1202060 15:00:00 500 4003.0 23 \n",
|
||||
"\n",
|
||||
" 申卖价一 申卖量一 datetime \n",
|
||||
"19812425 4003.0 140 2023-12-29 14:59:58.500 \n",
|
||||
"19812426 4003.0 116 2023-12-29 14:59:59.000 \n",
|
||||
"19812427 4003.0 16 2023-12-29 14:59:59.500 \n",
|
||||
"19812428 4004.0 7 2023-12-29 15:00:00.000 \n",
|
||||
"19812429 4004.0 7 2023-12-29 15:00:00.500 "
|
||||
]
|
||||
},
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.rename(\n",
|
||||
" columns={\n",
|
||||
" \"最新价\": \"lastprice\",\n",
|
||||
" \"数量\": \"volume\",\n",
|
||||
" \"申买价一\": \"bid_p\",\n",
|
||||
" \"申买量一\": \"bid_v\",\n",
|
||||
" \"申卖价一\": \"ask_p\",\n",
|
||||
" \"申卖量一\": \"ask_v\",\n",
|
||||
" \"合约代码\": \"symbol\",\n",
|
||||
" },\n",
|
||||
" inplace=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"vol_diff\"] = df[\"volume\"].diff()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>交易日</th>\n",
|
||||
" <th>symbol</th>\n",
|
||||
" <th>lastprice</th>\n",
|
||||
" <th>volume</th>\n",
|
||||
" <th>最后修改时间</th>\n",
|
||||
" <th>最后修改毫秒</th>\n",
|
||||
" <th>bid_p</th>\n",
|
||||
" <th>bid_v</th>\n",
|
||||
" <th>ask_p</th>\n",
|
||||
" <th>ask_v</th>\n",
|
||||
" <th>datetime</th>\n",
|
||||
" <th>vol_diff</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4305.0</td>\n",
|
||||
" <td>5750</td>\n",
|
||||
" <td>09:00:00</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4305.0</td>\n",
|
||||
" <td>359</td>\n",
|
||||
" <td>4310.0</td>\n",
|
||||
" <td>36</td>\n",
|
||||
" <td>2022-01-04 09:00:00.500</td>\n",
|
||||
" <td>NaN</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4306.0</td>\n",
|
||||
" <td>8039</td>\n",
|
||||
" <td>09:00:01</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4306.0</td>\n",
|
||||
" <td>18</td>\n",
|
||||
" <td>4308.0</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" <td>2022-01-04 09:00:01.000</td>\n",
|
||||
" <td>2289.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4308.0</td>\n",
|
||||
" <td>9065</td>\n",
|
||||
" <td>09:00:01</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4308.0</td>\n",
|
||||
" <td>43</td>\n",
|
||||
" <td>4310.0</td>\n",
|
||||
" <td>74</td>\n",
|
||||
" <td>2022-01-04 09:00:01.500</td>\n",
|
||||
" <td>1026.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4310.0</td>\n",
|
||||
" <td>9682</td>\n",
|
||||
" <td>09:00:02</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>4311.0</td>\n",
|
||||
" <td>4</td>\n",
|
||||
" <td>4314.0</td>\n",
|
||||
" <td>19</td>\n",
|
||||
" <td>2022-01-04 09:00:02.000</td>\n",
|
||||
" <td>617.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>20220104</td>\n",
|
||||
" <td>rb2205</td>\n",
|
||||
" <td>4314.0</td>\n",
|
||||
" <td>10328</td>\n",
|
||||
" <td>09:00:02</td>\n",
|
||||
" <td>500</td>\n",
|
||||
" <td>4314.0</td>\n",
|
||||
" <td>137</td>\n",
|
||||
" <td>4316.0</td>\n",
|
||||
" <td>19</td>\n",
|
||||
" <td>2022-01-04 09:00:02.500</td>\n",
|
||||
" <td>646.0</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" 交易日 symbol lastprice volume 最后修改时间 最后修改毫秒 bid_p bid_v \\\n",
|
||||
"0 20220104 rb2205 4305.0 5750 09:00:00 500 4305.0 359 \n",
|
||||
"1 20220104 rb2205 4306.0 8039 09:00:01 0 4306.0 18 \n",
|
||||
"2 20220104 rb2205 4308.0 9065 09:00:01 500 4308.0 43 \n",
|
||||
"3 20220104 rb2205 4310.0 9682 09:00:02 0 4311.0 4 \n",
|
||||
"4 20220104 rb2205 4314.0 10328 09:00:02 500 4314.0 137 \n",
|
||||
"\n",
|
||||
" ask_p ask_v datetime vol_diff \n",
|
||||
"0 4310.0 36 2022-01-04 09:00:00.500 NaN \n",
|
||||
"1 4308.0 7 2022-01-04 09:00:01.000 2289.0 \n",
|
||||
"2 4310.0 74 2022-01-04 09:00:01.500 1026.0 \n",
|
||||
"3 4314.0 19 2022-01-04 09:00:02.000 617.0 \n",
|
||||
"4 4316.0 19 2022-01-04 09:00:02.500 646.0 "
|
||||
]
|
||||
},
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[df[\"vol_diff\"].isnull(), \"vol_diff\"] = df.loc[df[\"vol_diff\"].isnull(), \"volume\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"volume\"] = df[\"vol_diff\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.to_csv(output_path)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "orderflow",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.17"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,801 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 使用说明:\n",
|
||||
" 1.需要修改chdir到当前目录\n",
|
||||
" 2.需要修改最后输出的文件名称\n",
|
||||
" 3.依据情况需要修改保留的列数\n",
|
||||
" 4.不同品种的交易时间不一样,要修改删除"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"import os\n",
|
||||
"import datetime as datetime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"os.chdir('E:/data/ru')\n",
|
||||
"all_csv_files = [file for file in os.listdir('.') if file.endswith('.csv')]\n",
|
||||
"all_csv_files = sorted(all_csv_files)\n",
|
||||
"print(\"文件中所有CSV文件:\",all_csv_files)\n",
|
||||
"\n",
|
||||
"sp_old_chars = ['_2019','_2020','_2021']\n",
|
||||
"sp_old_chars = sorted(sp_old_chars)\n",
|
||||
"print(\"旧格式文件名关键字:\",sp_old_chars)\n",
|
||||
"sp_new_chars = ['_2022','_2023']\n",
|
||||
"sp_new_chars = sorted(sp_new_chars)\n",
|
||||
"print(\"新格式文件名关键字:\",sp_new_chars)\n",
|
||||
"\n",
|
||||
"# # 设置后面数据的采集对于的行数# 用 \"old_type\" 或者 \"new_type\" 区分\n",
|
||||
"# if all(char in ['_2019','_2020','_2021'] for char in sp_old_chars):\n",
|
||||
"# year_type = 'old_type'\n",
|
||||
"# print(\"使用旧年份格式采集!!!\")\n",
|
||||
"# elif all(char in ['_2022','_2023'] for char in sp_chars):\n",
|
||||
"# year_type = 'new_type' \n",
|
||||
"# print(\"使用新年份格式采集!!!\")\n",
|
||||
"# else:\n",
|
||||
"# print(\"文件夹中CSV没有相关年份的数据或者新旧年份混用!!!\")\n",
|
||||
"\n",
|
||||
"csv_old_files = [file for file in all_csv_files if any(sp_char in file for sp_char in sp_old_chars)]\n",
|
||||
"print(\"筛选结果后的CSV文件:\",csv_old_files)\n",
|
||||
"csv_new_files = [file for file in all_csv_files if any(sp_char in file for sp_char in sp_new_chars)]\n",
|
||||
"print(\"筛选结果后的CSV文件:\",csv_new_files)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_old = pd.DataFrame()\n",
|
||||
"for f in csv_old_files:\n",
|
||||
" df_old_temp = pd.read_csv(\n",
|
||||
" f,\n",
|
||||
" usecols=[1, 2, 3, 4, 8, 13, 14, 15, 16],\n",
|
||||
" names=[\n",
|
||||
" \"统一代码\",\n",
|
||||
" \"合约代码\",\n",
|
||||
" \"时间\",\n",
|
||||
" \"最新\",\n",
|
||||
" \"成交量\",\n",
|
||||
" \"买一价\",\n",
|
||||
" \"卖一价\",\n",
|
||||
" \"买一量\",\n",
|
||||
" \"卖一量\",\n",
|
||||
" ],\n",
|
||||
" skiprows=1,\n",
|
||||
" encoding=\"utf-8\",\n",
|
||||
" parse_dates=['时间']#注意此处增加的排序,为了后面按时间排序\n",
|
||||
" )\n",
|
||||
" # df_temp = pd.read_csv(f, usecols=[0,5], names=[\n",
|
||||
" # 'datetime', 'volume'])\n",
|
||||
" df_old = pd.concat([df_old, df_old_temp])\n",
|
||||
"del df_old_temp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_old =pd.DataFrame({'main_contract':df_old['统一代码'],'symbol':df_old['合约代码'],'datetime':df_old['时间'],'lastprice':df_old['最新'],'volume':df_old['成交量'],\n",
|
||||
" 'bid_p':df_old['买一价'],'ask_p':df_old['卖一价'],'bid_v':df_old['买一量'],'ask_v':df_old['卖一量']})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_old['time'] = df_old['datetime'].dt.strftime('%H:%M:%S')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_old.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_old.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 不同品种交易时间不一样,需要修改\n",
|
||||
"# 商品期货\n",
|
||||
"drop_index1 = df_old.query('time>\"15:00:00\" & time<\"21:00:00\"')[\"time\"].index\n",
|
||||
"# drop_index1 = df_old.query('time>\"15:00:00\"')[\"time\"].index\n",
|
||||
"# drop_index2 = df_old.query('time>\"01:00:00\" & time<\"09:00:00\"')[\"time\"].index\n",
|
||||
"#drop_index2 = df_old.query('time>\"02:30:00\" & time<\"09:00:00\"')[\"time\"].index\n",
|
||||
"drop_index2 = df_old.query('time<\"09:00:00\"')[\"time\"].index\n",
|
||||
"drop_index3 = df_old.query('time>\"23:00:00\" & time<\"23:59:59\"')[\"time\"].index\n",
|
||||
"# drop_index3 = df_old.query('time>\"11:30:00\" & time<\"13:30:00\"')[\"time\"].index\n",
|
||||
"drop_index4 = df_old.query('time>\"10:15:00\" & time<\"10:30:00\"')[\"time\"].index\n",
|
||||
"\n",
|
||||
"# 清理不在交易时间段的数据\n",
|
||||
"df_old.drop(labels=drop_index1, axis=0, inplace=True)\n",
|
||||
"df_old.drop(drop_index2, axis=0, inplace=True)\n",
|
||||
"df_old.drop(drop_index3, axis=0, inplace=True)\n",
|
||||
"df_old.drop(drop_index4, axis=0, inplace=True)\n",
|
||||
"\n",
|
||||
"df_old.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_old.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"del df_old['time']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_old.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_new = pd.DataFrame()\n",
|
||||
"for f in csv_new_files:\n",
|
||||
" df_new_temp = pd.read_csv(\n",
|
||||
" f,\n",
|
||||
" usecols=[0, 1, 2, 5, 12, 21, 22, 23, 24, 25, 26, 44],\n",
|
||||
" names=[\n",
|
||||
" \"交易日\",\n",
|
||||
" \"统一代码\",\n",
|
||||
" \"合约代码\",\n",
|
||||
" \"最新价\",\n",
|
||||
" \"数量\",\n",
|
||||
" \"最后修改时间\",\n",
|
||||
" \"最后修改毫秒\",\n",
|
||||
" \"申买价一\",\n",
|
||||
" \"申买量一\",\n",
|
||||
" \"申卖价一\",\n",
|
||||
" \"申卖量一\",\n",
|
||||
" \"业务日期\",\n",
|
||||
" ],\n",
|
||||
" skiprows=1,\n",
|
||||
" encoding=\"utf-8\",\n",
|
||||
" parse_dates=['业务日期','最后修改时间','最后修改毫秒']#注意此处增加的排序,为了后面按时间排序\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # df_temp = pd.read_csv(f, usecols=[0,5], names=[\n",
|
||||
" # 'datetime', 'volume'])\n",
|
||||
" df_new = pd.concat([df_new, df_new_temp])\n",
|
||||
"del df_new_temp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 不同品种交易时间不一样,需要修改\n",
|
||||
"# 商品期货\n",
|
||||
"drop_index1 = df_new.query('最后修改时间>\"15:00:00\" & 最后修改时间<\"21:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index1 = df_new.query('最后修改时间>\"15:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index2 = df_new.query('最后修改时间>\"01:00:00\" & 最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index2 = df_new.query('最后修改时间>\"02:30:00\" & 最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"drop_index2 = df_new.query('最后修改时间<\"09:00:00\"')[\"最后修改时间\"].index\n",
|
||||
"drop_index3 = df_new.query('最后修改时间>\"23:00:00\" & 最后修改时间<\"23:59:59\"')[\"最后修改时间\"].index\n",
|
||||
"# drop_index3 = df_new.query('最后修改时间>\"11:30:00\" & 最后修改时间<\"13:30:00\"')[\"最后修改时间\"].index\n",
|
||||
"drop_index4 = df_new.query('最后修改时间>\"10:15:00\" & 最后修改时间<\"10:30:00\"')[\"最后修改时间\"].index\n",
|
||||
"\n",
|
||||
"# 清理不在交易时间段的数据\n",
|
||||
"df_new.drop(labels=drop_index1, axis=0, inplace=True)\n",
|
||||
"df_new.drop(drop_index2, axis=0, inplace=True)\n",
|
||||
"df_new.drop(drop_index3, axis=0, inplace=True)\n",
|
||||
"df_new.drop(drop_index4, axis=0, inplace=True)\n",
|
||||
"\n",
|
||||
"df_new.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#日期修正\n",
|
||||
"#df_new['业务日期'] = pd.to_datetime(df_new['业务日期'])\n",
|
||||
"df_new['业务日期'] = df_new['业务日期'].dt.strftime('%Y-%m-%d')\n",
|
||||
"df_new['datetime'] = df_new['业务日期'] + ' '+df_new['最后修改时间'].dt.time.astype(str) + '.' + df_new['最后修改毫秒'].astype(str)\n",
|
||||
"# 将 'datetime' 列的数据类型更改为 datetime 格式,如果数据转换少8个小时,可以用timedelta处理\n",
|
||||
"df_new['datetime'] = pd.to_datetime(df_new['datetime'], errors='coerce', format='%Y-%m-%d %H:%M:%S.%f')\n",
|
||||
"# 如果需要,可以将 datetime 列格式化为字符串\n",
|
||||
"#df_new['formatted_date'] = df_new['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S.%f')\n",
|
||||
"#计算瞬时成交量\n",
|
||||
"df_new['volume'] = df_new['数量'] - df_new['数量'].shift(1)\n",
|
||||
"df_new['volume'] = df_new['volume'].fillna(0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_new =pd.DataFrame({'main_contract':df_new['统一代码'],'symbol':df_new['合约代码'],'datetime':df_new['datetime'],'lastprice':df_new['最新价'],'volume':df_new['volume'],\n",
|
||||
" 'bid_p':df_new['申买价一'],'ask_p':df_new['申卖价一'],'bid_v':df_new['申买量一'],'ask_v':df_new['申卖量一']})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_old.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_old.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_new.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_new.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.DataFrame()\n",
|
||||
"df = pd.concat([df_old, df_new],axis=0, ignore_index=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"del df_old,df_new"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['main_contract'] = df['main_contract'].astype(str)\n",
|
||||
"df['symbol'] = df['symbol'].astype(str)\n",
|
||||
"df['datetime'] = pd.to_datetime(df['datetime'], errors='coerce', format='%Y-%m-%d %H:%M:%S.%f')\n",
|
||||
"df['lastprice'] = df['lastprice'].astype(float)\n",
|
||||
"df['volume'] = df['volume'].astype(int)\n",
|
||||
"df['bid_p'] = df['bid_p'].astype(float)\n",
|
||||
"df['ask_p'] = df['ask_p'].astype(float)\n",
|
||||
"df['bid_v'] = df['bid_v'].astype(int)\n",
|
||||
"df['ask_v'] = df['ask_v'].astype(int)\n",
|
||||
"#df = df_old.append(df_new, ignore_index=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 删除重复行\n",
|
||||
"df.drop_duplicates(inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 确保日期列按升序排序\n",
|
||||
"df.sort_values(by='datetime', inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 查看数据的头部和尾部:head()、tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.reset_index(drop=True, inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查看dataframe的基本情况\n",
|
||||
"df.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 等比复权,先不考虑\n",
|
||||
"# df['复权因子'] = df['卖一价'].shift() / df['买一价']\n",
|
||||
"df['复权因子'] = np.where(df['合约代码'] != df['合约代码'].shift(), df['卖一价'].shift() / df['买一价'], 1)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(1)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['买一价_adj'] = df['买一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['卖一价_adj'] = df['卖一价'] * df['复权因子'].cumprod()\n",
|
||||
"df['最新_adj'] = df['最新'] * df['复权因子'].cumprod()\n",
|
||||
"# df['low_adj'] = df['low'] * adjust.cumprod()\n",
|
||||
"# df['high_adj'] = df['high'] * adjust.cumprod()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 等差复权\n",
|
||||
"df['复权因子'] = np.where(df['symbol'] != df['symbol'].shift(), df['ask_p'].shift() - df['bid_p'], 0)\n",
|
||||
"df['复权因子'] = df['复权因子'].fillna(0)\n",
|
||||
"# df['复权因子'].loc[0] = 1\n",
|
||||
"df['bid_p_adj'] = df['bid_p'] + df['复权因子'].cumsum()\n",
|
||||
"df['ask_p_adj'] = df['ask_p'] + df['复权因子'].cumsum()\n",
|
||||
"df['lastprice_adj'] = df['lastprice'] + df['复权因子'].cumsum()\n",
|
||||
"# df['low_adj'] = df['low'] + df['复权因子'].cumsum()\n",
|
||||
"# df['high_adj'] = df['high'] + df['复权因子'].cumsum()\n",
|
||||
"# df_new =pd.DataFrame({'main_contract':df_new['统一代码'],'symbol':df_new['合约代码'],'datetime':df_new['datetime'],'lastprice':df_new['最新价'],'volume':df_new['volume'],\n",
|
||||
"# 'bid_p':df_new['申买价一'],'ask_p':df_new['申卖量一'],'bid_v':df_new['申买量一'],'ask_v':df_new['申卖量一']})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(df['复权因子'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"contains_null = df.isnull().values.any()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(contains_null)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查找换期需要复权的索引\n",
|
||||
"non_zero_indices = df[df['复权因子'] != 0].index\n",
|
||||
"print(non_zero_indices)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查看未调整买价、卖价和最新价的数据\n",
|
||||
"df.loc[non_zero_indices[0]-5:non_zero_indices[0]+5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 将调整后的数值替换原来的值\n",
|
||||
"df['bid_p'] = df['bid_p_adj']\n",
|
||||
"df['ask_p'] = df['ask_p_adj']\n",
|
||||
"df['lastprice'] = df['lastprice_adj']\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 查看调整买价、卖价和最新价的数据\n",
|
||||
"df.loc[non_zero_indices[0]-5:non_zero_indices[0]+5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 删除多余的值\n",
|
||||
"del df['复权因子']\n",
|
||||
"del df['bid_p_adj']\n",
|
||||
"del df['ask_p_adj']\n",
|
||||
"del df['lastprice_adj']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.loc[non_zero_indices[0]-5:non_zero_indices[0]+5]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.to_csv('./ru888.csv', index=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"del df"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"import os\n",
|
||||
"import datetime as datetime\n",
|
||||
"import pyarrow as pa\n",
|
||||
"import pyarrow.feather as feather"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# feature 测试\n",
|
||||
"df = pd.read_csv('E:/data/ru/ru888.csv',encoding='UTF-8',parse_dates=['datetime'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"feather.write_feather(df, 'df_feather.feather')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = feather.read_feather('df_feather.feather')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>main_contract</th>\n",
|
||||
" <th>symbol</th>\n",
|
||||
" <th>datetime</th>\n",
|
||||
" <th>lastprice</th>\n",
|
||||
" <th>volume</th>\n",
|
||||
" <th>bid_p</th>\n",
|
||||
" <th>ask_p</th>\n",
|
||||
" <th>bid_v</th>\n",
|
||||
" <th>ask_v</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>44287432</th>\n",
|
||||
" <td>ru888</td>\n",
|
||||
" <td>ru2405</td>\n",
|
||||
" <td>2023-12-29 14:59:58.500</td>\n",
|
||||
" <td>6755.0</td>\n",
|
||||
" <td>27</td>\n",
|
||||
" <td>6750.0</td>\n",
|
||||
" <td>6755.0</td>\n",
|
||||
" <td>128</td>\n",
|
||||
" <td>15</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>44287433</th>\n",
|
||||
" <td>ru888</td>\n",
|
||||
" <td>ru2405</td>\n",
|
||||
" <td>2023-12-29 14:59:59.000</td>\n",
|
||||
" <td>6760.0</td>\n",
|
||||
" <td>27</td>\n",
|
||||
" <td>6755.0</td>\n",
|
||||
" <td>6760.0</td>\n",
|
||||
" <td>2</td>\n",
|
||||
" <td>14</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>44287434</th>\n",
|
||||
" <td>ru888</td>\n",
|
||||
" <td>ru2405</td>\n",
|
||||
" <td>2023-12-29 14:59:59.500</td>\n",
|
||||
" <td>6760.0</td>\n",
|
||||
" <td>17</td>\n",
|
||||
" <td>6760.0</td>\n",
|
||||
" <td>6765.0</td>\n",
|
||||
" <td>35</td>\n",
|
||||
" <td>33</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>44287435</th>\n",
|
||||
" <td>ru888</td>\n",
|
||||
" <td>ru2405</td>\n",
|
||||
" <td>2023-12-29 15:00:00.000</td>\n",
|
||||
" <td>6760.0</td>\n",
|
||||
" <td>6</td>\n",
|
||||
" <td>6760.0</td>\n",
|
||||
" <td>6765.0</td>\n",
|
||||
" <td>45</td>\n",
|
||||
" <td>42</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>44287436</th>\n",
|
||||
" <td>ru888</td>\n",
|
||||
" <td>ru2405</td>\n",
|
||||
" <td>2023-12-29 15:00:00.500</td>\n",
|
||||
" <td>6760.0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>6760.0</td>\n",
|
||||
" <td>6765.0</td>\n",
|
||||
" <td>45</td>\n",
|
||||
" <td>42</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" main_contract symbol datetime lastprice volume \\\n",
|
||||
"44287432 ru888 ru2405 2023-12-29 14:59:58.500 6755.0 27 \n",
|
||||
"44287433 ru888 ru2405 2023-12-29 14:59:59.000 6760.0 27 \n",
|
||||
"44287434 ru888 ru2405 2023-12-29 14:59:59.500 6760.0 17 \n",
|
||||
"44287435 ru888 ru2405 2023-12-29 15:00:00.000 6760.0 6 \n",
|
||||
"44287436 ru888 ru2405 2023-12-29 15:00:00.500 6760.0 0 \n",
|
||||
"\n",
|
||||
" bid_p ask_p bid_v ask_v \n",
|
||||
"44287432 6750.0 6755.0 128 15 \n",
|
||||
"44287433 6755.0 6760.0 2 14 \n",
|
||||
"44287434 6760.0 6765.0 35 33 \n",
|
||||
"44287435 6760.0 6765.0 45 42 \n",
|
||||
"44287436 6760.0 6765.0 45 42 "
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.tail()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
for /f "tokens=2 delims=," %%a in ('tasklist /v /fo csv ^| findstr /i "订单流横截面_日内模型.py"') do taskkill /pid %%~a
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,983 @@
|
||||
'''
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
该代码的主要目的是处理Tick数据并生成交易信号。代码中定义了一个tickcome函数,它接收到Tick数据后会进行一系列的处理,包括构建Tick字典、更新上一个Tick的成交量、保存Tick数据、生成K线数据等。其中涉及到的一些函数有:
|
||||
|
||||
on_tick(tick): 处理单个Tick数据,根据Tick数据生成K线数据。
|
||||
tickdata(df, symbol): 处理Tick数据,生成K线数据。
|
||||
orderflow_df_new(df_tick, df_min, symbol): 处理Tick和K线数据,生成订单流数据。
|
||||
GetOrderFlow_dj(kData): 计算订单流的信号指标。
|
||||
除此之外,代码中还定义了一个MyTrader类,继承自TraderApiBase,用于实现交易相关的功能。
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
'''
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from multiprocessing import Process, Queue
|
||||
import queue
|
||||
import threading
|
||||
from AlgoPlus.CTP.MdApi import run_tick_engine
|
||||
from AlgoPlus.CTP.FutureAccount import get_simulate_account
|
||||
from AlgoPlus.CTP.FutureAccount import FutureAccount
|
||||
from AlgoPlus.CTP.TraderApiBase import TraderApiBase
|
||||
from AlgoPlus.ta.time_bar import tick_to_bar
|
||||
import pandas as pd
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import time as s_time
|
||||
import operator
|
||||
import time
|
||||
import numpy as np
|
||||
import os
|
||||
import csv
|
||||
import re
|
||||
|
||||
|
||||
tickdatadict = {} # 存储Tick数据的字典
|
||||
quotedict = {} # 存储行情数据的字典
|
||||
ofdatadict = {} # 存储K线数据的字典
|
||||
trade_dfs = {} #pd.DataFrame({}) # 存储交易数据的DataFrame对象
|
||||
previous_volume = {} # 上一个Tick的成交量
|
||||
tsymbollist={} #过渡tick
|
||||
|
||||
截面数据_资金流向={}
|
||||
top_two_symbols=[]
|
||||
|
||||
合约信息={
|
||||
"A": {"合约单位": 10, "保证金": 0.12},
|
||||
"AG": {"合约单位": 15, "保证金": 0.12},
|
||||
"AL": {"合约单位": 5, "保证金": 0.12},
|
||||
"AO": {"合约单位": 20, "保证金": 0.09},
|
||||
"AP": {"合约单位": 10, "保证金": 0.1},
|
||||
"AU": {"合约单位": 1000, "保证金": 0.1},
|
||||
"B": {"合约单位": 10, "保证金": 0.09},
|
||||
"BC": {"合约单位": 5, "保证金": 0.12},
|
||||
"BR": {"合约单位": 5, "保证金": 0.12},
|
||||
"BU": {"合约单位": 10, "保证金": 0.15},
|
||||
"C": {"合约单位": 10, "保证金": 0.12},
|
||||
"CF": {"合约单位": 5, "保证金": 0.07},
|
||||
"CJ": {"合约单位": 5, "保证金": 0.12},
|
||||
"CS": {"合约单位": 10, "保证金": 0.09},
|
||||
"CU": {"合约单位": 5, "保证金": 0.12},
|
||||
"CY": {"合约单位": 5, "保证金": 0.07},
|
||||
"EB": {"合约单位": 5, "保证金": 0.12},
|
||||
"EC": {"合约单位": 50, "保证金": 0.12},
|
||||
"EG": {"合约单位": 10, "保证金": 0.12},
|
||||
"FB": {"合约单位": 10, "保证金": 0.1},
|
||||
"FG": {"合约单位": 20, "保证金": 0.09},
|
||||
"FU": {"合约单位": 10, "保证金": 0.15},
|
||||
"HC": {"合约单位": 10, "保证金": 0.13},
|
||||
"I": {"合约单位": 100, "保证金": 0.13},
|
||||
"IC": {"合约单位": 1, "保证金": 0.14},
|
||||
"IF": {"合约单位": 1, "保证金": 0.12},
|
||||
"IH": {"合约单位": 1, "保证金": 0.12},
|
||||
"IM": {"合约单位": 1, "保证金": 0.15},
|
||||
"J": {"合约单位": 100, "保证金": 0.2},
|
||||
"JD": {"合约单位": 10, "保证金": 0.09},
|
||||
"JM": {"合约单位": 60, "保证金": 0.2},
|
||||
"L": {"合约单位": 5, "保证金": 0.11},
|
||||
"LC": {"合约单位": 1, "保证金": 0.09},
|
||||
"LH": {"合约单位": 16, "保证金": 0.15},
|
||||
"LU": {"合约单位": 10, "保证金": 0.15},
|
||||
|
||||
"M": {"合约单位": 10, "保证金": 0.1},
|
||||
"MA": {"合约单位": 10, "保证金": 0.08},
|
||||
"NI": {"合约单位": 1, "保证金": 0.19},
|
||||
"NR": {"合约单位": 10, "保证金": 0.1},
|
||||
"OI": {"合约单位": 10, "保证金": 0.09},
|
||||
"P": {"合约单位": 10, "保证金": 0.12},
|
||||
"PB": {"合约单位": 5, "保证金": 0.14},
|
||||
"PF": {"合约单位": 5, "保证金": 0.08},
|
||||
"PG": {"合约单位": 20, "保证金": 0.13},
|
||||
"PK": {"合约单位": 5, "保证金": 0.08},
|
||||
"PP": {"合约单位": 5, "保证金": 0.11},
|
||||
"PX": {"合约单位": 5, "保证金": 0.12},
|
||||
"RB": {"合约单位": 10, "保证金": 0.13},
|
||||
"RM": {"合约单位": 10, "保证金": 0.09},
|
||||
"RR": {"合约单位": 10, "保证金": 0.06},
|
||||
"RU": {"合约单位": 10, "保证金": 0.1},
|
||||
"SA": {"合约单位": 20, "保证金": 0.09},
|
||||
"SC": {"合约单位": 1000, "保证金": 0.15},
|
||||
"SF": {"合约单位": 5, "保证金": 0.12},
|
||||
"SH": {"合约单位": 30, "保证金": 0.09},
|
||||
"SI": {"合约单位": 5, "保证金": 0.1},
|
||||
"SM": {"合约单位": 5, "保证金": 0.12},
|
||||
"SN": {"合约单位": 1, "保证金": 0.14},
|
||||
"SP": {"合约单位": 10, "保证金": 0.15},
|
||||
"SR": {"合约单位": 10, "保证金": 0.07},
|
||||
"SS": {"合约单位": 5, "保证金": 0.14},
|
||||
"T": {"合约单位": 10000, "保证金": 0.02},
|
||||
"TA": {"合约单位": 5, "保证金": 0.07},
|
||||
"TF": {"合约单位": 10000, "保证金": 0.012},
|
||||
"TL": {"合约单位": 10000, "保证金": 0.035},
|
||||
"TS": {"合约单位": 20000, "保证金": 0.005},
|
||||
"UR": {"合约单位": 20, "保证金": 0.08},
|
||||
"V": {"合约单位": 5, "保证金": 0.11},
|
||||
"Y": {"合约单位": 10, "保证金": 0.09},
|
||||
"ZN": {"合约单位": 5, "保证金": 0.14},
|
||||
|
||||
}
|
||||
|
||||
|
||||
clearing_time_dict = {'sc': s_time(2,30), 'bc': s_time(1,0), 'lu': s_time(23,0), 'nr': s_time(23,0),'au': s_time(2,30), 'ag': s_time(2,30),
|
||||
'ss': s_time(1,0), 'sn': s_time(1,0), 'ni': s_time(1,0), 'pb': s_time(1,0),'zn': s_time(1,0), 'al': s_time(1,0), 'cu': s_time(1,0),
|
||||
'ru': s_time(23,0), 'rb': s_time(23,0), 'hc': s_time(23,0), 'fu': s_time(23,0), 'bu': s_time(23,0), 'sp': s_time(23,0),
|
||||
'PF': s_time(23,0), 'SR': s_time(23,0), 'CF': s_time(23,0), 'CY': s_time(23,0), 'RM': s_time(23,0), 'MA': s_time(23,0),
|
||||
'TA': s_time(23,0), 'ZC': s_time(23,0), 'FG': s_time(23,0), 'OI': s_time(23,0), 'SA': s_time(23,0),
|
||||
'p': s_time(23,0), 'j': s_time(23,0), 'jm': s_time(23,0), 'i': s_time(23,0), 'l': s_time(23,0), 'v': s_time(23,0),
|
||||
'pp': s_time(23,0), 'eg': s_time(23,0), 'c': s_time(23,0), 'cs': s_time(23,0), 'y': s_time(23,0), 'm': s_time(23,0),
|
||||
'a': s_time(23,0), 'b': s_time(23,0), 'rr': s_time(23,0), 'eb': s_time(23,0), 'pg': s_time(23,0)}
|
||||
|
||||
|
||||
#交易程序---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
class ParamObj:
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
symbol = None #合约名称
|
||||
Lots = None #下单手数
|
||||
py = None #设置委托价格的偏移,更加容易促成成交
|
||||
trailing_stop_percent = None #跟踪出场参数
|
||||
fixed_stop_loss_percent = None #固定出场参数
|
||||
dj_X = None #开仓的堆积参数
|
||||
delta = None #开仓的delta参数
|
||||
sum_delta = None #开仓的delta累积参数
|
||||
失衡=None
|
||||
堆积=None
|
||||
周期=None
|
||||
|
||||
# 策略需要用到的变量
|
||||
cont_df = 0
|
||||
pos = 0
|
||||
clearing_executed = False
|
||||
kgdata = True
|
||||
|
||||
多头止损价格 = 0
|
||||
空头止损价格 = 0
|
||||
|
||||
多头成本价格 = 0
|
||||
空头成本价格 = 0
|
||||
|
||||
多头开仓历时=0
|
||||
空头开仓历时=0
|
||||
|
||||
平_多时间=4
|
||||
平_空时间=4
|
||||
|
||||
def __init__(self, symbol, Lots, py,dj_X, delta, sum_delta,失衡,堆积,周期,平_多时间,平_空时间):
|
||||
self.symbol = symbol
|
||||
self.Lots = Lots
|
||||
self.py = py
|
||||
self.dj_X = dj_X
|
||||
self.delta = delta
|
||||
self.sum_delta = sum_delta
|
||||
self.失衡=失衡
|
||||
self.堆积=堆积
|
||||
self.周期=周期
|
||||
self.平_多时间=平_多时间
|
||||
self.平_空时间=平_空时间
|
||||
|
||||
|
||||
class MyTrader(TraderApiBase):
|
||||
def __init__(self, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
self.param_dict = {}
|
||||
self.queue_dict = {}
|
||||
self.品种=' '
|
||||
|
||||
|
||||
def tickcome(self,md_queue):
|
||||
global previous_volume
|
||||
data=md_queue
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
ActionDay = data['ActionDay'].decode() # 交易日日期
|
||||
update_time = data['UpdateTime'].decode() # 更新时间
|
||||
|
||||
update_millisec = str(data['UpdateMillisec']) # 更新毫秒数
|
||||
created_at = ActionDay[:4] + '-' + ActionDay[4:6] + '-' + ActionDay[6:] + ' ' + update_time + '.' + update_millisec #创建时间
|
||||
# 构建tick字典
|
||||
tick = {
|
||||
'symbol': instrument_id, # 品种代码和交易所ID
|
||||
'created_at':datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S.%f"),
|
||||
#'created_at': created_at, # 创建时间
|
||||
'price': float(data['LastPrice']), # 最新价
|
||||
'last_volume': int(data['Volume']) - previous_volume.get(instrument_id, 0) if previous_volume.get(instrument_id, 0) != 0 else 0, # 瞬时成交量
|
||||
'bid_p': float(data['BidPrice1']), # 买价
|
||||
'bid_v': int(data['BidVolume1']), # 买量
|
||||
'ask_p': float(data['AskPrice1']), # 卖价
|
||||
'ask_v': int(data['AskVolume1']), # 卖量
|
||||
'UpperLimitPrice': float(data['UpperLimitPrice']), # 涨停价
|
||||
'LowerLimitPrice': float(data['LowerLimitPrice']), # 跌停价
|
||||
'TradingDay': data['TradingDay'].decode(), # 交易日日期
|
||||
'cum_volume': int(data['Volume']), # 最新总成交量
|
||||
'cum_amount': float(data['Turnover']), # 最新总成交额
|
||||
'cum_position': int(data['OpenInterest']), # 合约持仓量
|
||||
}
|
||||
# print('&&&&&&&&',instrument_id, tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 更新上一个Tick的成交量
|
||||
previous_volume[instrument_id] = int(data['Volume'])
|
||||
if tick['last_volume']>0:
|
||||
#print(tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 处理Tick数据
|
||||
self.on_tick(tick)
|
||||
|
||||
def can_time(self,hour, minute):
|
||||
hour = str(hour)
|
||||
minute = str(minute)
|
||||
if len(minute) == 1:
|
||||
minute = "0" + minute
|
||||
return int(hour + minute)
|
||||
|
||||
def on_tick(self,tick):
|
||||
|
||||
tm=self.can_time(tick['created_at'].hour,tick['created_at'].minute)
|
||||
#print(tick['symbol'])
|
||||
#print(1)
|
||||
#if tm>1500 and tm<2100 :
|
||||
# return
|
||||
if tick['last_volume']==0:
|
||||
return
|
||||
quotes = tick
|
||||
timetick=str(tick['created_at']).replace('+08:00', '')
|
||||
tsymbol=tick['symbol']
|
||||
if tsymbol not in tsymbollist.keys():
|
||||
# 获取tick的买卖价和买卖量
|
||||
|
||||
tsymbollist[tsymbol]=tick
|
||||
bid_p=quotes['bid_p']
|
||||
ask_p=quotes['ask_p']
|
||||
bid_v=quotes['bid_v']
|
||||
ask_v=quotes['ask_v']
|
||||
else:
|
||||
# 获取上一个tick的买卖价和买卖量
|
||||
rquotes =tsymbollist[tsymbol]
|
||||
bid_p=rquotes['bid_p']
|
||||
ask_p=rquotes['ask_p']
|
||||
bid_v=rquotes['bid_v']
|
||||
ask_v=rquotes['ask_v']
|
||||
tsymbollist[tsymbol]=tick
|
||||
tick_dt=pd.DataFrame({'datetime':timetick,'symbol':tick['symbol'],'mainsym':tick['symbol'].rstrip('0123456789').upper(),'lastprice':tick['price'],
|
||||
'vol':tick['last_volume'],
|
||||
'bid_p':bid_p,'ask_p':ask_p,'bid_v':bid_v,'ask_v':ask_v},index=[0])
|
||||
sym = tick_dt['symbol'][0]
|
||||
#print(tick_dt)
|
||||
self.tickdata(tick_dt,sym)
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def data_of(self,symbol, df):
|
||||
global trade_dfs
|
||||
# 将df数据合并到trader_df中
|
||||
# if symbol not in trade_dfs.keys():
|
||||
# trade_df = pd.DataFrame({})
|
||||
# else:
|
||||
# trade_df = trade_dfs[symbol]
|
||||
trade_dfs[symbol] = pd.concat([trade_dfs[symbol], df], ignore_index=True)
|
||||
# print('!!!!!!!!!!!trader_df: ', symbol, df['datetime'].iloc[-1])
|
||||
#print(trader_df)
|
||||
|
||||
def process(self,bidDict, askDict, symbol):
|
||||
try:
|
||||
# 尝试从quotedict中获取对应品种的报价数据
|
||||
dic = quotedict[symbol]
|
||||
bidDictResult = dic['bidDictResult']
|
||||
askDictResult = dic['askDictResult']
|
||||
except:
|
||||
# 如果获取失败,则初始化bidDictResult和askDictResult为空字典
|
||||
bidDictResult, askDictResult = {}, {}
|
||||
|
||||
# 将所有买盘字典和卖盘字典的key合并,并按升序排序
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
|
||||
# 遍历所有的key,将相同key的值进行累加
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
if s in bidDictResult:
|
||||
bidDictResult[s] = int(bidDict[s]) + bidDictResult[s]
|
||||
else:
|
||||
bidDictResult[s] = int(bidDict[s])
|
||||
if s not in askDictResult:
|
||||
askDictResult[s] = 0
|
||||
else:
|
||||
if s in askDictResult:
|
||||
askDictResult[s] = int(askDict[s]) + askDictResult[s]
|
||||
else:
|
||||
askDictResult[s] = int(askDict[s])
|
||||
if s not in bidDictResult:
|
||||
bidDictResult[s] = 0
|
||||
|
||||
# 构建包含bidDictResult和askDictResult的字典,并存入quotedict中
|
||||
df = {'bidDictResult': bidDictResult, 'askDictResult': askDictResult}
|
||||
quotedict[symbol] = df
|
||||
|
||||
return bidDictResult, askDictResult
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
|
||||
def tickdata(self,df,symbol):
|
||||
tickdata =pd.DataFrame({'datetime':df['datetime'],'symbol':df['symbol'],'lastprice':df['lastprice'],
|
||||
'volume':df['vol'],'bid_p':df['bid_p'],'bid_v':df['bid_v'],'ask_p':df['ask_p'],'ask_v':df['ask_v']})
|
||||
try:
|
||||
if symbol in tickdatadict.keys():
|
||||
rdf=tickdatadict[symbol]
|
||||
rdftm=pd.to_datetime(rdf['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
now=str(tickdata['datetime'][0])
|
||||
if now>rdftm:
|
||||
try:
|
||||
oo=ofdatadict[symbol]
|
||||
self.data_of(symbol, oo)
|
||||
#print('oo',oo)
|
||||
if symbol in quotedict.keys():
|
||||
quotedict.pop(symbol)
|
||||
if symbol in tickdatadict.keys():
|
||||
tickdatadict.pop(symbol)
|
||||
if symbol in ofdatadict.keys():
|
||||
ofdatadict.pop(symbol)
|
||||
except IOError as e:
|
||||
print('rdftm捕获到异常',e)
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
else:
|
||||
tickdata['bartime'] = rdf['bartime']
|
||||
tickdata['open'] = rdf['open']
|
||||
tickdata['high'] = max(tickdata['lastprice'].values,rdf['high'].values)
|
||||
tickdata['low'] = min(tickdata['lastprice'].values,rdf['low'].values)
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['volume']=df['vol']+rdf['volume'].values
|
||||
tickdata['starttime'] = rdf['starttime']
|
||||
else :
|
||||
print('新bar的第一个tick进入')
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
except IOError as e:
|
||||
print('捕获到异常',e)
|
||||
|
||||
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['bartime'])
|
||||
param = self.param_dict[self.品种]
|
||||
bardata = tickdata.resample(on = 'bartime',rule = param.周期,label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
bardata['bartime'] = pd.to_datetime(bardata['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
tickdatadict[symbol]=bardata
|
||||
tickdata['volume']=df['vol'].values
|
||||
#print(bardata['symbol'].values,bardata['bartime'].values)
|
||||
self.orderflow_df_new(tickdata,bardata,symbol)
|
||||
# time.sleep(0.5)
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def orderflow_df_new(self,df_tick,df_min,symbol):
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
#endArray = pd.to_datetime(df_min['bartime']).values
|
||||
endArray = df_min['bartime'].values
|
||||
#print(endArray)
|
||||
deltaArray = np.zeros((len(endArray),))
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
dt=endArray[index]
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
# for indexTick in range(indexFinal,len(df_tick)):
|
||||
# if tTickArray[indexTick] >= tEnd:
|
||||
# break
|
||||
# elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] < tEnd):
|
||||
Bp = round(bp1TickArray[0],4)
|
||||
Ap = round(ap1TickArray[0],4)
|
||||
LastPrice = round(lastTickArray[0],4)
|
||||
Volume = volumeTickArray[0]
|
||||
if LastPrice >= Ap:
|
||||
if str(LastPrice) in askDict.keys():
|
||||
askDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
askDict[str(LastPrice)] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if str(LastPrice) in bidDict.keys():
|
||||
bidDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
bidDict[str(LastPrice)] = Volume
|
||||
# indexFinal = indexTick
|
||||
bidDictResult,askDictResult = self.process(bidDict,askDict,symbol)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
#print(prinslist,asklist,bidlist)
|
||||
#print(len(prinslist),len(bidDictResult),len(askDictResult))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
#df=pd.DataFrame({'price':pd.Series(bidDictResult.keys()),'Ask':pd.Series(askDictResult.values()),'Bid':pd.Series(bidDictResult.values())})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
#df['ticktime']=tTickArray[0]
|
||||
df['dj'] = self.GetOrderFlow_dj(df)
|
||||
ofdatadict[symbol]=df
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def GetOrderFlow_dj(self,kData):
|
||||
param = self.param_dict[self.品种]
|
||||
Config = {
|
||||
'Value1': param.失衡,
|
||||
'Value2': param.堆积,
|
||||
'Value4': True,
|
||||
}
|
||||
aryData = kData
|
||||
djcout = 0
|
||||
|
||||
# 遍历kData中的每一行,计算djcout指标
|
||||
for index, row in aryData.iterrows():
|
||||
kItem = aryData.iloc[index]
|
||||
high = kItem['high']
|
||||
low = kItem['low']
|
||||
close = kItem['close']
|
||||
open = kItem['open']
|
||||
dtime = kItem['datetime']
|
||||
price_s = kItem['price']
|
||||
Ask_s = kItem['Ask']
|
||||
Bid_s = kItem['Bid']
|
||||
delta = kItem['delta']
|
||||
|
||||
price_s = price_s
|
||||
Ask_s = Ask_s
|
||||
Bid_s = Bid_s
|
||||
|
||||
gj = 0
|
||||
xq = 0
|
||||
gxx = 0
|
||||
xxx = 0
|
||||
|
||||
# 遍历price_s中的每一个元素,计算相关指标
|
||||
for i in np.arange(0, len(price_s), 1):
|
||||
duiji = {
|
||||
'price': 0,
|
||||
'time': 0,
|
||||
'longshort': 0,
|
||||
}
|
||||
|
||||
if i == 0:
|
||||
delta = delta
|
||||
|
||||
order= {
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
#空头堆积
|
||||
if i >= 0 and i < len(price_s) - 1:
|
||||
if (order["Bid"]["Value"] > Ask_s[i + 1] * int(Config['Value1'])):
|
||||
gxx += 1
|
||||
gj += 1
|
||||
if gj >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = -1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += -1
|
||||
else:
|
||||
gj = 0
|
||||
#多头堆积
|
||||
if i >= 1 and i <= len(price_s) - 1:
|
||||
if (order["Ask"]["Value"] > Bid_s[i - 1] * int(Config['Value1'])):
|
||||
xq += 1
|
||||
xxx += 1
|
||||
if xq >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = 1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += 1
|
||||
else:
|
||||
xq = 0
|
||||
|
||||
# 返回计算得到的djcout值
|
||||
return djcout
|
||||
|
||||
def OnRtnTrade(self, pTrade):
|
||||
print("||成交回报||", pTrade)
|
||||
|
||||
def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast):
|
||||
print("||OnRspOrderInsert||", pInputOrder, pRspInfo, nRequestID, bIsLast)
|
||||
|
||||
#订单状态通知
|
||||
def OnRtnOrder(self, pOrder):
|
||||
print("||订单回报||", pOrder)
|
||||
|
||||
#保存OF数据
|
||||
def save_trade_data(self,df,instrument_id):
|
||||
# 定义文件路径
|
||||
csv_file_path = f"ofdata/{instrument_id}_ofdata.csv"
|
||||
directory = os.path.dirname(csv_file_path)
|
||||
|
||||
# 检查目录是否存在,如果不存在则创建它
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
# 如果文件夹存在,则追加数据;否则,创建新文件并保存整个 DataFrame
|
||||
if os.path.exists(csv_file_path):
|
||||
# 仅保存最后一行数据
|
||||
df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
else:
|
||||
# 创建新文件并保存整个 DataFrame
|
||||
df.to_csv(csv_file_path, index=False)
|
||||
|
||||
def w_log(self,symbol,log_message):
|
||||
|
||||
# 创建文件夹(如果不存在)
|
||||
log_dir = 'tradelogs'
|
||||
if not os.path.exists(log_dir):
|
||||
os.makedirs(log_dir)
|
||||
|
||||
# 写入日志到 CSV 文件
|
||||
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
log_file = os.path.join(log_dir, f'{symbol}log.csv')
|
||||
# 打印日志到控制台
|
||||
print(f'{now}: {log_message}')
|
||||
with open(log_file, 'a', encoding='utf-8',newline='') as csvfile:
|
||||
writer = csv.writer(csvfile)
|
||||
# 如果文件为空,写入表头
|
||||
if csvfile.tell() == 0:
|
||||
writer.writerow(['time', 'logs'])
|
||||
writer.writerow([now, log_message])
|
||||
|
||||
# 计算单品种资金流向数据
|
||||
def 资金流向计算(self,df):
|
||||
# 将 'delta' 和 'close' 转换为数值类型,强制转换错误
|
||||
df['volume'] = pd.to_numeric(df['volume'], errors='coerce')
|
||||
df['close'] = pd.to_numeric(df['close'], errors='coerce')
|
||||
|
||||
# 删除 'delta' 或 'close' 中的 NaN 值
|
||||
df = df.dropna(subset=['volume', 'close'])
|
||||
symbol=df['symbol'].iloc[-1]
|
||||
symbol = ''.join(filter(str.isalpha, symbol)).upper()
|
||||
资金净流向 = abs(sum(df['volume']*df['close']))*合约信息[symbol]['合约单位']*合约信息[symbol]['保证金']
|
||||
更新状态=True
|
||||
# 将结果放入 DataFrame
|
||||
result_df = pd.DataFrame({
|
||||
'资金净流向': [资金净流向],
|
||||
'更新状态': [更新状态]
|
||||
})
|
||||
|
||||
return result_df
|
||||
|
||||
# 收盘清仓
|
||||
def 收盘清仓(self,symbol,data):
|
||||
param = self.param_dict[symbol]
|
||||
# 获取当前时间
|
||||
current_time = datetime.now().time()
|
||||
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(22, 55)
|
||||
clearing_time2_end = s_time(23, 0)
|
||||
now = datetime.now()
|
||||
# 创建一个标志变量,用于记录是否已经执行过清仓操作
|
||||
#param.clearing_executed = False
|
||||
|
||||
# 检查当前时间是否在第一个清仓操作的时间范围内,并且清仓操作未执行过
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not param.clearing_executed :
|
||||
#trade_dfs.drop(trade_dfs.index,inplace=True)#清除当天的行情数据
|
||||
if param.pos>0:
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
self.w_log(symbol,f"{symbol}多头清仓操作")
|
||||
pass
|
||||
elif param.pos<0:
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
self.w_log(symbol,f"{symbol}空头清仓操作")
|
||||
pass
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
|
||||
# 检查当前时间是否在第二个清仓操作的时间范围内,并且清仓操作未执行过
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not param.clearing_executed :
|
||||
#trade_dfs.drop(trade_dfs.index,inplace=True) #清除当天的行情数据
|
||||
if param.pos>0:
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
self.w_log(symbol,f"{symbol}多头清仓操作")
|
||||
pass
|
||||
elif param.pos<0:
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
self.w_log(symbol,f"{symbol}空头清仓操作")
|
||||
pass
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
# 如果不在任何清仓操作的时间范围内,可以执行其他操作或不执行任何操作
|
||||
else:
|
||||
param.clearing_executed = False
|
||||
pass
|
||||
#print("不在清仓操作时间范围内")
|
||||
|
||||
return param.clearing_executed
|
||||
|
||||
def cal_sig(self, symbol_queue):
|
||||
while True:
|
||||
try:
|
||||
now=datetime.now()
|
||||
data = symbol_queue.get(block=True, timeout=5) # 如果5秒没收到新的tick行情,则抛出异常
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
size = symbol_queue.qsize()
|
||||
if size > 1:
|
||||
print(f'当前{instrument_id}共享队列长度为{size}, 有点阻塞!!!!!')
|
||||
param = self.param_dict[instrument_id]
|
||||
self.品种=instrument_id
|
||||
#OF计算数据开始
|
||||
self.tickcome(data)
|
||||
trade_df = trade_dfs[instrument_id]
|
||||
#清仓开关
|
||||
run_kg=self.收盘清仓(instrument_id,data)
|
||||
最新价=data['LastPrice']
|
||||
sympc=data['InstrumentID'].decode()
|
||||
# #多头时间出场
|
||||
if param.pos>0 and param.多头开仓历时>param.平_多时间 :
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
param.多头止损价格=0
|
||||
param.多头开仓历时=0
|
||||
param.多头成本价格=0
|
||||
self.w_log(sympc,f'历时{param.平_多时间}***多头***{sympc}时间出场价格{最新价}')
|
||||
|
||||
#多头价格止损
|
||||
if param.pos>0 and 最新价<param.多头止损价格 :
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
param.多头止损价格=0
|
||||
param.多头开仓历时=0
|
||||
param.多头成本价格=0
|
||||
self.w_log(sympc,f'多头止损触发: {最新价},多头止损价格:{param.多头止损价格} ***{sympc}多头止损***')
|
||||
|
||||
# #多头跟踪止盈-----------------------暂时用不到------------------------
|
||||
# elif param.pos>0 and len(trade_df)>1 and 最新价<trade_df['10_MA'].iloc[-1] and 最新价>param.多头成本价格 :
|
||||
# #平多
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
# param.pos=0
|
||||
# param.多头止损价格=0
|
||||
# param.多头开仓历时=0
|
||||
# param.多头成本价格=0
|
||||
# self.w_log(sympc,f'多头跟踪止盈触发: {最新价} ***{sympc}多头止盈***')
|
||||
|
||||
# # #空头时间出场
|
||||
if param.pos<0 and param.空头开仓历时>param.平_空时间 :
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
param.空头止损价格=0
|
||||
param.空头开仓历时=0
|
||||
param.空头成本价格=0
|
||||
self.w_log(sympc,f'历时{param.平_空时间}***空头***{sympc}时间出场价格{最新价}')
|
||||
|
||||
#空头价格止损
|
||||
if param.pos<0 and 最新价>param.空头止损价格 :
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
param.空头止损价格=0
|
||||
param.空头开仓历时=0
|
||||
param.空头成本价格=0
|
||||
self.w_log(sympc,f'空头止损触发: {最新价},空头止损价格:{param.空头止损价格} ***{sympc}空头止损***')
|
||||
|
||||
# #空头跟踪止盈-----------------------暂时用不到------------------------
|
||||
# elif param.pos<0 and len(trade_df)>1 and 最新价>trade_df['10_MA'].iloc[-1] and 最新价<param.空头成本价格 :
|
||||
# #平空
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
# param.pos=0
|
||||
# param.空头止损价格=0
|
||||
# param.空头开仓历时=0
|
||||
# param.空头成本价格=0
|
||||
# self.w_log(sympc,f'空头跟踪止盈触发: {最新价},***{sympc}空头止盈***')
|
||||
|
||||
#交易程序开始
|
||||
if len(trade_df)>param.cont_df and run_kg==False:
|
||||
#开仓历时更新:
|
||||
if param.pos>0:
|
||||
param.多头开仓历时+=1
|
||||
elif param.pos<0:
|
||||
param.空头开仓历时+=1
|
||||
|
||||
#计算截面数据
|
||||
截面数据_资金流向[instrument_id]=self.资金流向计算(trade_df)
|
||||
|
||||
#日均线
|
||||
trade_df['dayma']=trade_df['close'].mean()
|
||||
|
||||
# 计算5日均线和10日均线,即使数据不足5日或10日
|
||||
trade_df['5_MA'] = trade_df['close'].rolling(window=5, min_periods=1).mean()
|
||||
trade_df['10_MA'] = trade_df['close'].rolling(window=10, min_periods=1).mean()
|
||||
|
||||
# 计算累积的delta值
|
||||
trade_df['delta'] = trade_df['delta'].astype(float)
|
||||
trade_df['delta累计'] = trade_df['delta'].cumsum()
|
||||
|
||||
#大于日均线
|
||||
开多1=trade_df['dayma'].iloc[-1] > 0 and trade_df['close'].iloc[-1] > trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量大于X
|
||||
开多4=trade_df['delta累计'].iloc[-1] > param.sum_delta and trade_df['delta'].iloc[-1] > param.delta
|
||||
|
||||
#小于日均线
|
||||
开空1=trade_df['dayma'].iloc[-1]>0 and trade_df['close'].iloc[-1] < trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量小于X
|
||||
开空4=trade_df['delta累计'].iloc[-1] < -param.sum_delta and trade_df['delta'].iloc[-1] < -param.delta
|
||||
|
||||
开多组合= 开多1 and 开多4 and trade_df['dj'].iloc[-1]>param.dj_X and trade_df['5_MA'].iloc[-1] > trade_df['10_MA'].iloc[-1]
|
||||
开空条件= 开空1 and 开空4 and trade_df['dj'].iloc[-1]<-param.dj_X and trade_df['5_MA'].iloc[-1] < trade_df['10_MA'].iloc[-1]
|
||||
symm=data['InstrumentID'].decode()
|
||||
#开平仓
|
||||
#换仓平多
|
||||
# if param.pos>0 and symm not in top_two_symbols:
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
# param.pos=0
|
||||
# param.多头止损价格=0
|
||||
# param.多头开仓历时=0
|
||||
# param.多头成本价格=0
|
||||
# self.w_log(symm,f'当前截面品种{top_two_symbols},{symm}不在范围,***多平仓***')
|
||||
#多头开仓
|
||||
if param.pos==0 and 开多组合 and symm in top_two_symbols :
|
||||
#开多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'0')
|
||||
param.pos=1
|
||||
param.多头止损价格=trade_df['low'].iloc[-2]
|
||||
param.多头成本价格=data['AskPrice1']
|
||||
param.多头开仓历时=1
|
||||
self.w_log(symm,f'品种:{symm},委托价格: {param.多头成本价格}***开多***')
|
||||
|
||||
#换仓平空
|
||||
# if param.pos<0 and symm not in top_two_symbols :
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
# param.pos=0
|
||||
# param.空头止损价格=0
|
||||
# param.空头开仓历时=0
|
||||
# param.空头成本价格=0
|
||||
# self.w_log(symm,f'当前截面品种{top_two_symbols},{symm}不在范围,***空平仓***')
|
||||
#空头开仓
|
||||
if param.pos==0 and 开空条件 and symm in top_two_symbols :
|
||||
#开空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'0')
|
||||
param.pos=-1
|
||||
param.空头止损价格=trade_df['high'].iloc[-2]
|
||||
param.空头成本价格=data['BidPrice1']
|
||||
param.空头开仓历时=1
|
||||
self.w_log(symm,f'品种:{symm},委托价格: {param.空头成本价格}***开空***')
|
||||
#print(trade_df)
|
||||
#保存OF数据
|
||||
self.save_trade_data(trade_df,symm)
|
||||
#保存bar计数
|
||||
param.cont_df=len(trade_df)
|
||||
except queue.Empty:
|
||||
# print(f"当前合约队列为空,等待新数据插入。")
|
||||
pass
|
||||
|
||||
# 将CTP推送的行情数据分发给对应线程队列去执行
|
||||
def distribute_tick(self):
|
||||
while True:
|
||||
if self.status == 0:
|
||||
data = None
|
||||
while not self.md_queue.empty():
|
||||
data = self.md_queue.get(block=False)
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
try:
|
||||
self.queue_dict[instrument_id].put(data, block=False) # 往对应合约队列中插入行情
|
||||
# print(f"{instrument_id}合约数据插入。")
|
||||
except queue.Full:
|
||||
# 当某个线程阻塞导致对应队列容量超限时抛出异常,不会影响其他合约的信号计算
|
||||
print(f"{instrument_id}合约信号计算阻塞导致对应队列已满,请检查对应代码逻辑后重启。")
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
def start(self, param_dict):
|
||||
threads = []
|
||||
self.param_dict = param_dict
|
||||
thread1 = threading.Thread(target=横截面计算)
|
||||
for symbol in param_dict.keys():
|
||||
trade_dfs[symbol] = pd.DataFrame({})
|
||||
self.queue_dict[symbol] = queue.Queue(10) #为每个合约创建一个限制数为10的队列,当计算发生阻塞导致队列达到限制数时会抛出异常
|
||||
t = threading.Thread(target=self.cal_sig, args=(self.queue_dict[symbol],)) # 为每个合约单独创建一个线程计算开仓逻辑
|
||||
threads.append(t)
|
||||
t.start()
|
||||
thread1.start()
|
||||
self.distribute_tick()
|
||||
for t in threads:
|
||||
t.join()
|
||||
thread1.join()
|
||||
|
||||
# 定义横截面计算函数
|
||||
def 横截面计算():
|
||||
global top_two_symbols
|
||||
while True:
|
||||
if len(截面数据_资金流向)>5:
|
||||
goss=1
|
||||
# 检查是否有任何品种的更新状态为 False,如果有则直接返回
|
||||
for symbol, data in 截面数据_资金流向.items():
|
||||
if not data['更新状态'].iloc[-1]:
|
||||
#print(f"品种 {symbol} 的更新状态为 False,跳过计算。")
|
||||
goss=0
|
||||
break
|
||||
if goss==1:
|
||||
# 继续计算资金净流向
|
||||
sorted_items = sorted(截面数据_资金流向.items(), key=lambda item: item[1]['资金净流向'].iloc[-1], reverse=True)
|
||||
max_symbol = sorted_items[0][0]
|
||||
two_max_symbol = sorted_items[1][0]
|
||||
three_max_symbol = sorted_items[2][0]
|
||||
four_max_symbol = sorted_items[3][0]
|
||||
five_max_symbol = sorted_items[4][0]
|
||||
top_two_symbols = [max_symbol, two_max_symbol,three_max_symbol,four_max_symbol,five_max_symbol]
|
||||
|
||||
print(f'选出的活跃品种: {top_two_symbols}')
|
||||
print(f'截面数据_资金流向: {截面数据_资金流向}')
|
||||
# 将所有品种的更新状态设置为 False
|
||||
for symbol in 截面数据_资金流向:
|
||||
截面数据_资金流向[symbol]['更新状态'] = False
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def run_trader(param_dict, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
my_trader = MyTrader(broker_id, td_server, investor_id, password, app_id, auth_code, md_queue, page_dir, private_resume_type, public_resume_type)
|
||||
my_trader.start(param_dict)
|
||||
|
||||
if __name__ == '__main__':
|
||||
#global symbol
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
#注意:运行前请先安装好algoplus,
|
||||
# pip install AlgoPlus
|
||||
#http://www.algo.plus/ctp/python/0103001.html
|
||||
|
||||
|
||||
# 实盘参数字典,需要实盘交易的合约,新建对应的参数对象即可,以下参数仅供测试使用,不作为实盘参考!!!!
|
||||
历时平仓=4
|
||||
|
||||
param_dict = {}
|
||||
param_dict['SR409'] = ParamObj(symbol='SR409', Lots=1, py=6,dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['eb2408'] = ParamObj(symbol='eb2408', Lots=2, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['SA409'] = ParamObj(symbol='SA409', Lots=1, py=6,dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['pp409'] = ParamObj(symbol='pp409', Lots=2, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['OI409'] = ParamObj(symbol='OI409', Lots=1, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['a2409'] = ParamObj(symbol='a2409', Lots=1, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['p2409'] = ParamObj(symbol='p2409', Lots=1, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['RM409'] = ParamObj(symbol='RM409', Lots=2, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['sp2409'] = ParamObj(symbol='sp2409', Lots=1, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
|
||||
|
||||
#用simnow模拟,不要忘记屏蔽下方实盘的future_account字典
|
||||
future_account = get_simulate_account(
|
||||
investor_id='', # simnow账户,注意是登录账户的ID,SIMNOW个人首页查看
|
||||
password='', # simnow密码
|
||||
server_name='电信1', # 电信1、电信2、移动、TEST、N视界
|
||||
subscribe_list=list(param_dict.keys()), # 合约列表
|
||||
)
|
||||
|
||||
# #实盘用这个,不要忘记屏蔽上方simnow的future_account字典
|
||||
# future_account = FutureAccount(
|
||||
# broker_id='', # 期货公司BrokerID
|
||||
# server_dict={'TDServer': "ip:port", 'MDServer': 'ip:port'}, # TDServer为交易服务器,MDServer为行情服务器。服务器地址格式为"ip:port。"
|
||||
# reserve_server_dict={}, # 备用服务器地址
|
||||
# investor_id='', # 账户
|
||||
# password='', # 密码
|
||||
# app_id='simnow_client_test', # 认证使用AppID
|
||||
# auth_code='0000000000000000', # 认证使用授权码
|
||||
# subscribe_list=list(param_dict.keys()), # 订阅合约列表
|
||||
# md_flow_path='./log', # MdApi流文件存储地址,默认MD_LOCATION
|
||||
# td_flow_path='./log', # TraderApi流文件存储地址,默认TD_LOCATION
|
||||
# )
|
||||
|
||||
|
||||
print('开始',len(future_account.subscribe_list))
|
||||
# 共享队列
|
||||
share_queue = Queue(maxsize=200)
|
||||
|
||||
# 行情进程
|
||||
md_process = Process(target=run_tick_engine, args=(future_account, [share_queue]))
|
||||
|
||||
|
||||
# 交易进程
|
||||
trader_process = Process(target=run_trader, args=(
|
||||
param_dict,
|
||||
future_account.broker_id,
|
||||
future_account.server_dict['TDServer'],
|
||||
future_account.investor_id,
|
||||
future_account.password,
|
||||
future_account.app_id,
|
||||
future_account.auth_code,
|
||||
share_queue, # 队列
|
||||
future_account.td_flow_path
|
||||
))
|
||||
|
||||
md_process.start()
|
||||
trader_process.start()
|
||||
|
||||
md_process.join()
|
||||
trader_process.join()
|
||||
|
||||
|
||||
@@ -0,0 +1,982 @@
|
||||
'''
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
该代码的主要目的是处理Tick数据并生成交易信号。代码中定义了一个tickcome函数,它接收到Tick数据后会进行一系列的处理,包括构建Tick字典、更新上一个Tick的成交量、保存Tick数据、生成K线数据等。其中涉及到的一些函数有:
|
||||
|
||||
on_tick(tick): 处理单个Tick数据,根据Tick数据生成K线数据。
|
||||
tickdata(df, symbol): 处理Tick数据,生成K线数据。
|
||||
orderflow_df_new(df_tick, df_min, symbol): 处理Tick和K线数据,生成订单流数据。
|
||||
GetOrderFlow_dj(kData): 计算订单流的信号指标。
|
||||
除此之外,代码中还定义了一个MyTrader类,继承自TraderApiBase,用于实现交易相关的功能。
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
'''
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from multiprocessing import Process, Queue
|
||||
import queue
|
||||
import threading
|
||||
from AlgoPlus.CTP.MdApi import run_tick_engine
|
||||
from AlgoPlus.CTP.FutureAccount import get_simulate_account
|
||||
from AlgoPlus.CTP.FutureAccount import FutureAccount
|
||||
from AlgoPlus.CTP.TraderApiBase import TraderApiBase
|
||||
from AlgoPlus.ta.time_bar import tick_to_bar
|
||||
import pandas as pd
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import time as s_time
|
||||
import operator
|
||||
import time
|
||||
import numpy as np
|
||||
import os
|
||||
import csv
|
||||
import re
|
||||
|
||||
|
||||
tickdatadict = {} # 存储Tick数据的字典
|
||||
quotedict = {} # 存储行情数据的字典
|
||||
ofdatadict = {} # 存储K线数据的字典
|
||||
trade_dfs = {} #pd.DataFrame({}) # 存储交易数据的DataFrame对象
|
||||
previous_volume = {} # 上一个Tick的成交量
|
||||
tsymbollist={} #过渡tick
|
||||
|
||||
截面数据_资金流向={}
|
||||
top_two_symbols=[]
|
||||
|
||||
合约信息={
|
||||
"A": {"合约单位": 10, "保证金": 0.12},
|
||||
"AG": {"合约单位": 15, "保证金": 0.12},
|
||||
"AL": {"合约单位": 5, "保证金": 0.12},
|
||||
"AO": {"合约单位": 20, "保证金": 0.09},
|
||||
"AP": {"合约单位": 10, "保证金": 0.1},
|
||||
"AU": {"合约单位": 1000, "保证金": 0.1},
|
||||
"B": {"合约单位": 10, "保证金": 0.09},
|
||||
"BC": {"合约单位": 5, "保证金": 0.12},
|
||||
"BR": {"合约单位": 5, "保证金": 0.12},
|
||||
"BU": {"合约单位": 10, "保证金": 0.15},
|
||||
"C": {"合约单位": 10, "保证金": 0.12},
|
||||
"CF": {"合约单位": 5, "保证金": 0.07},
|
||||
"CJ": {"合约单位": 5, "保证金": 0.12},
|
||||
"CS": {"合约单位": 10, "保证金": 0.09},
|
||||
"CU": {"合约单位": 5, "保证金": 0.12},
|
||||
"CY": {"合约单位": 5, "保证金": 0.07},
|
||||
"EB": {"合约单位": 5, "保证金": 0.12},
|
||||
"EC": {"合约单位": 50, "保证金": 0.12},
|
||||
"EG": {"合约单位": 10, "保证金": 0.12},
|
||||
"FB": {"合约单位": 10, "保证金": 0.1},
|
||||
"FG": {"合约单位": 20, "保证金": 0.09},
|
||||
"FU": {"合约单位": 10, "保证金": 0.15},
|
||||
"HC": {"合约单位": 10, "保证金": 0.13},
|
||||
"I": {"合约单位": 100, "保证金": 0.13},
|
||||
"IC": {"合约单位": 1, "保证金": 0.14},
|
||||
"IF": {"合约单位": 1, "保证金": 0.12},
|
||||
"IH": {"合约单位": 1, "保证金": 0.12},
|
||||
"IM": {"合约单位": 1, "保证金": 0.15},
|
||||
"J": {"合约单位": 100, "保证金": 0.2},
|
||||
"JD": {"合约单位": 10, "保证金": 0.09},
|
||||
"JM": {"合约单位": 60, "保证金": 0.2},
|
||||
"L": {"合约单位": 5, "保证金": 0.11},
|
||||
"LC": {"合约单位": 1, "保证金": 0.09},
|
||||
"LH": {"合约单位": 16, "保证金": 0.15},
|
||||
"LU": {"合约单位": 10, "保证金": 0.15},
|
||||
|
||||
"M": {"合约单位": 10, "保证金": 0.1},
|
||||
"MA": {"合约单位": 10, "保证金": 0.08},
|
||||
"NI": {"合约单位": 1, "保证金": 0.19},
|
||||
"NR": {"合约单位": 10, "保证金": 0.1},
|
||||
"OI": {"合约单位": 10, "保证金": 0.09},
|
||||
"P": {"合约单位": 10, "保证金": 0.12},
|
||||
"PB": {"合约单位": 5, "保证金": 0.14},
|
||||
"PF": {"合约单位": 5, "保证金": 0.08},
|
||||
"PG": {"合约单位": 20, "保证金": 0.13},
|
||||
"PK": {"合约单位": 5, "保证金": 0.08},
|
||||
"PP": {"合约单位": 5, "保证金": 0.11},
|
||||
"PX": {"合约单位": 5, "保证金": 0.12},
|
||||
"RB": {"合约单位": 10, "保证金": 0.13},
|
||||
"RM": {"合约单位": 10, "保证金": 0.09},
|
||||
"RR": {"合约单位": 10, "保证金": 0.06},
|
||||
"RU": {"合约单位": 10, "保证金": 0.1},
|
||||
"SA": {"合约单位": 20, "保证金": 0.09},
|
||||
"SC": {"合约单位": 1000, "保证金": 0.15},
|
||||
"SF": {"合约单位": 5, "保证金": 0.12},
|
||||
"SH": {"合约单位": 30, "保证金": 0.09},
|
||||
"SI": {"合约单位": 5, "保证金": 0.1},
|
||||
"SM": {"合约单位": 5, "保证金": 0.12},
|
||||
"SN": {"合约单位": 1, "保证金": 0.14},
|
||||
"SP": {"合约单位": 10, "保证金": 0.15},
|
||||
"SR": {"合约单位": 10, "保证金": 0.07},
|
||||
"SS": {"合约单位": 5, "保证金": 0.14},
|
||||
"T": {"合约单位": 10000, "保证金": 0.02},
|
||||
"TA": {"合约单位": 5, "保证金": 0.07},
|
||||
"TF": {"合约单位": 10000, "保证金": 0.012},
|
||||
"TL": {"合约单位": 10000, "保证金": 0.035},
|
||||
"TS": {"合约单位": 20000, "保证金": 0.005},
|
||||
"UR": {"合约单位": 20, "保证金": 0.08},
|
||||
"V": {"合约单位": 5, "保证金": 0.11},
|
||||
"Y": {"合约单位": 10, "保证金": 0.09},
|
||||
"ZN": {"合约单位": 5, "保证金": 0.14},
|
||||
|
||||
}
|
||||
|
||||
|
||||
clearing_time_dict = {'sc': s_time(2,30), 'bc': s_time(1,0), 'lu': s_time(23,0), 'nr': s_time(23,0),'au': s_time(2,30), 'ag': s_time(2,30),
|
||||
'ss': s_time(1,0), 'sn': s_time(1,0), 'ni': s_time(1,0), 'pb': s_time(1,0),'zn': s_time(1,0), 'al': s_time(1,0), 'cu': s_time(1,0),
|
||||
'ru': s_time(23,0), 'rb': s_time(23,0), 'hc': s_time(23,0), 'fu': s_time(23,0), 'bu': s_time(23,0), 'sp': s_time(23,0),
|
||||
'PF': s_time(23,0), 'SR': s_time(23,0), 'CF': s_time(23,0), 'CY': s_time(23,0), 'RM': s_time(23,0), 'MA': s_time(23,0),
|
||||
'TA': s_time(23,0), 'ZC': s_time(23,0), 'FG': s_time(23,0), 'OI': s_time(23,0), 'SA': s_time(23,0),
|
||||
'p': s_time(23,0), 'j': s_time(23,0), 'jm': s_time(23,0), 'i': s_time(23,0), 'l': s_time(23,0), 'v': s_time(23,0),
|
||||
'pp': s_time(23,0), 'eg': s_time(23,0), 'c': s_time(23,0), 'cs': s_time(23,0), 'y': s_time(23,0), 'm': s_time(23,0),
|
||||
'a': s_time(23,0), 'b': s_time(23,0), 'rr': s_time(23,0), 'eb': s_time(23,0), 'pg': s_time(23,0)}
|
||||
|
||||
|
||||
#交易程序---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
class ParamObj:
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
# 策略需要用到的参数,在新建合约对象的时候传入!!
|
||||
symbol = None #合约名称
|
||||
Lots = None #下单手数
|
||||
py = None #设置委托价格的偏移,更加容易促成成交
|
||||
trailing_stop_percent = None #跟踪出场参数
|
||||
fixed_stop_loss_percent = None #固定出场参数
|
||||
dj_X = None #开仓的堆积参数
|
||||
delta = None #开仓的delta参数
|
||||
sum_delta = None #开仓的delta累积参数
|
||||
失衡=None
|
||||
堆积=None
|
||||
周期=None
|
||||
|
||||
# 策略需要用到的变量
|
||||
cont_df = 0
|
||||
pos = 0
|
||||
clearing_executed = False
|
||||
kgdata = True
|
||||
|
||||
多头止损价格 = 0
|
||||
空头止损价格 = 0
|
||||
|
||||
多头成本价格 = 0
|
||||
空头成本价格 = 0
|
||||
|
||||
多头开仓历时=0
|
||||
空头开仓历时=0
|
||||
|
||||
平_多时间=4
|
||||
平_空时间=4
|
||||
|
||||
def __init__(self, symbol, Lots, py,dj_X, delta, sum_delta,失衡,堆积,周期,平_多时间,平_空时间):
|
||||
self.symbol = symbol
|
||||
self.Lots = Lots
|
||||
self.py = py
|
||||
self.dj_X = dj_X
|
||||
self.delta = delta
|
||||
self.sum_delta = sum_delta
|
||||
self.失衡=失衡
|
||||
self.堆积=堆积
|
||||
self.周期=周期
|
||||
self.平_多时间=平_多时间
|
||||
self.平_空时间=平_空时间
|
||||
|
||||
|
||||
class MyTrader(TraderApiBase):
|
||||
def __init__(self, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
self.param_dict = {}
|
||||
self.queue_dict = {}
|
||||
self.品种=' '
|
||||
|
||||
|
||||
def tickcome(self,md_queue):
|
||||
global previous_volume
|
||||
data=md_queue
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
ActionDay = data['ActionDay'].decode() # 交易日日期
|
||||
update_time = data['UpdateTime'].decode() # 更新时间
|
||||
|
||||
update_millisec = str(data['UpdateMillisec']) # 更新毫秒数
|
||||
created_at = ActionDay[:4] + '-' + ActionDay[4:6] + '-' + ActionDay[6:] + ' ' + update_time + '.' + update_millisec #创建时间
|
||||
# 构建tick字典
|
||||
tick = {
|
||||
'symbol': instrument_id, # 品种代码和交易所ID
|
||||
'created_at':datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S.%f"),
|
||||
#'created_at': created_at, # 创建时间
|
||||
'price': float(data['LastPrice']), # 最新价
|
||||
'last_volume': int(data['Volume']) - previous_volume.get(instrument_id, 0) if previous_volume.get(instrument_id, 0) != 0 else 0, # 瞬时成交量
|
||||
'bid_p': float(data['BidPrice1']), # 买价
|
||||
'bid_v': int(data['BidVolume1']), # 买量
|
||||
'ask_p': float(data['AskPrice1']), # 卖价
|
||||
'ask_v': int(data['AskVolume1']), # 卖量
|
||||
'UpperLimitPrice': float(data['UpperLimitPrice']), # 涨停价
|
||||
'LowerLimitPrice': float(data['LowerLimitPrice']), # 跌停价
|
||||
'TradingDay': data['TradingDay'].decode(), # 交易日日期
|
||||
'cum_volume': int(data['Volume']), # 最新总成交量
|
||||
'cum_amount': float(data['Turnover']), # 最新总成交额
|
||||
'cum_position': int(data['OpenInterest']), # 合约持仓量
|
||||
}
|
||||
# print('&&&&&&&&',instrument_id, tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 更新上一个Tick的成交量
|
||||
previous_volume[instrument_id] = int(data['Volume'])
|
||||
if tick['last_volume']>0:
|
||||
#print(tick['created_at'],'vol:',tick['last_volume'])
|
||||
# 处理Tick数据
|
||||
self.on_tick(tick)
|
||||
|
||||
def can_time(self,hour, minute):
|
||||
hour = str(hour)
|
||||
minute = str(minute)
|
||||
if len(minute) == 1:
|
||||
minute = "0" + minute
|
||||
return int(hour + minute)
|
||||
|
||||
def on_tick(self,tick):
|
||||
|
||||
tm=self.can_time(tick['created_at'].hour,tick['created_at'].minute)
|
||||
#print(tick['symbol'])
|
||||
#print(1)
|
||||
#if tm>1500 and tm<2100 :
|
||||
# return
|
||||
if tick['last_volume']==0:
|
||||
return
|
||||
quotes = tick
|
||||
timetick=str(tick['created_at']).replace('+08:00', '')
|
||||
tsymbol=tick['symbol']
|
||||
if tsymbol not in tsymbollist.keys():
|
||||
# 获取tick的买卖价和买卖量
|
||||
|
||||
tsymbollist[tsymbol]=tick
|
||||
bid_p=quotes['bid_p']
|
||||
ask_p=quotes['ask_p']
|
||||
bid_v=quotes['bid_v']
|
||||
ask_v=quotes['ask_v']
|
||||
else:
|
||||
# 获取上一个tick的买卖价和买卖量
|
||||
rquotes =tsymbollist[tsymbol]
|
||||
bid_p=rquotes['bid_p']
|
||||
ask_p=rquotes['ask_p']
|
||||
bid_v=rquotes['bid_v']
|
||||
ask_v=rquotes['ask_v']
|
||||
tsymbollist[tsymbol]=tick
|
||||
tick_dt=pd.DataFrame({'datetime':timetick,'symbol':tick['symbol'],'mainsym':tick['symbol'].rstrip('0123456789').upper(),'lastprice':tick['price'],
|
||||
'vol':tick['last_volume'],
|
||||
'bid_p':bid_p,'ask_p':ask_p,'bid_v':bid_v,'ask_v':ask_v},index=[0])
|
||||
sym = tick_dt['symbol'][0]
|
||||
#print(tick_dt)
|
||||
self.tickdata(tick_dt,sym)
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def data_of(self,symbol, df):
|
||||
global trade_dfs
|
||||
# 将df数据合并到trader_df中
|
||||
# if symbol not in trade_dfs.keys():
|
||||
# trade_df = pd.DataFrame({})
|
||||
# else:
|
||||
# trade_df = trade_dfs[symbol]
|
||||
trade_dfs[symbol] = pd.concat([trade_dfs[symbol], df], ignore_index=True)
|
||||
# print('!!!!!!!!!!!trader_df: ', symbol, df['datetime'].iloc[-1])
|
||||
#print(trader_df)
|
||||
|
||||
def process(self,bidDict, askDict, symbol):
|
||||
try:
|
||||
# 尝试从quotedict中获取对应品种的报价数据
|
||||
dic = quotedict[symbol]
|
||||
bidDictResult = dic['bidDictResult']
|
||||
askDictResult = dic['askDictResult']
|
||||
except:
|
||||
# 如果获取失败,则初始化bidDictResult和askDictResult为空字典
|
||||
bidDictResult, askDictResult = {}, {}
|
||||
|
||||
# 将所有买盘字典和卖盘字典的key合并,并按升序排序
|
||||
sList = sorted(set(list(bidDict.keys()) + list(askDict.keys())))
|
||||
|
||||
# 遍历所有的key,将相同key的值进行累加
|
||||
for s in sList:
|
||||
if s in bidDict:
|
||||
if s in bidDictResult:
|
||||
bidDictResult[s] = int(bidDict[s]) + bidDictResult[s]
|
||||
else:
|
||||
bidDictResult[s] = int(bidDict[s])
|
||||
if s not in askDictResult:
|
||||
askDictResult[s] = 0
|
||||
else:
|
||||
if s in askDictResult:
|
||||
askDictResult[s] = int(askDict[s]) + askDictResult[s]
|
||||
else:
|
||||
askDictResult[s] = int(askDict[s])
|
||||
if s not in bidDictResult:
|
||||
bidDictResult[s] = 0
|
||||
|
||||
# 构建包含bidDictResult和askDictResult的字典,并存入quotedict中
|
||||
df = {'bidDictResult': bidDictResult, 'askDictResult': askDictResult}
|
||||
quotedict[symbol] = df
|
||||
|
||||
return bidDictResult, askDictResult
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
|
||||
def tickdata(self,df,symbol):
|
||||
tickdata =pd.DataFrame({'datetime':df['datetime'],'symbol':df['symbol'],'lastprice':df['lastprice'],
|
||||
'volume':df['vol'],'bid_p':df['bid_p'],'bid_v':df['bid_v'],'ask_p':df['ask_p'],'ask_v':df['ask_v']})
|
||||
try:
|
||||
if symbol in tickdatadict.keys():
|
||||
rdf=tickdatadict[symbol]
|
||||
rdftm=pd.to_datetime(rdf['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
now=str(tickdata['datetime'][0])
|
||||
if now>rdftm:
|
||||
try:
|
||||
oo=ofdatadict[symbol]
|
||||
self.data_of(symbol, oo)
|
||||
#print('oo',oo)
|
||||
if symbol in quotedict.keys():
|
||||
quotedict.pop(symbol)
|
||||
if symbol in tickdatadict.keys():
|
||||
tickdatadict.pop(symbol)
|
||||
if symbol in ofdatadict.keys():
|
||||
ofdatadict.pop(symbol)
|
||||
except IOError as e:
|
||||
print('rdftm捕获到异常',e)
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
else:
|
||||
tickdata['bartime'] = rdf['bartime']
|
||||
tickdata['open'] = rdf['open']
|
||||
tickdata['high'] = max(tickdata['lastprice'].values,rdf['high'].values)
|
||||
tickdata['low'] = min(tickdata['lastprice'].values,rdf['low'].values)
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['volume']=df['vol']+rdf['volume'].values
|
||||
tickdata['starttime'] = rdf['starttime']
|
||||
else :
|
||||
print('新bar的第一个tick进入')
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['datetime'])
|
||||
tickdata['open'] = tickdata['lastprice']
|
||||
tickdata['high'] = tickdata['lastprice']
|
||||
tickdata['low'] = tickdata['lastprice']
|
||||
tickdata['close'] = tickdata['lastprice']
|
||||
tickdata['starttime'] = tickdata['datetime']
|
||||
except IOError as e:
|
||||
print('捕获到异常',e)
|
||||
|
||||
|
||||
tickdata['bartime'] = pd.to_datetime(tickdata['bartime'])
|
||||
param = self.param_dict[self.品种]
|
||||
bardata = tickdata.resample(on = 'bartime',rule = param.周期,label = 'right',closed = 'right').agg({'starttime':'first','symbol':'last','open':'first','high':'max','low':'min','close':'last','volume':'sum'}).reset_index(drop = False)
|
||||
bardata =bardata.dropna().reset_index(drop = True)
|
||||
bardata['bartime'] = pd.to_datetime(bardata['bartime'][0]).strftime('%Y-%m-%d %H:%M:%S')
|
||||
tickdatadict[symbol]=bardata
|
||||
tickdata['volume']=df['vol'].values
|
||||
#print(bardata['symbol'].values,bardata['bartime'].values)
|
||||
self.orderflow_df_new(tickdata,bardata,symbol)
|
||||
# time.sleep(0.5)
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def orderflow_df_new(self,df_tick,df_min,symbol):
|
||||
startArray = pd.to_datetime(df_min['starttime']).values
|
||||
voluememin= df_min['volume'].values
|
||||
highs=df_min['high'].values
|
||||
lows=df_min['low'].values
|
||||
opens=df_min['open'].values
|
||||
closes=df_min['close'].values
|
||||
#endArray = pd.to_datetime(df_min['bartime']).values
|
||||
endArray = df_min['bartime'].values
|
||||
#print(endArray)
|
||||
deltaArray = np.zeros((len(endArray),))
|
||||
tTickArray = pd.to_datetime(df_tick['datetime']).values
|
||||
bp1TickArray = df_tick['bid_p'].values
|
||||
ap1TickArray = df_tick['ask_p'].values
|
||||
lastTickArray = df_tick['lastprice'].values
|
||||
volumeTickArray = df_tick['volume'].values
|
||||
symbolarray = df_tick['symbol'].values
|
||||
indexFinal = 0
|
||||
for index,tEnd in enumerate(endArray):
|
||||
dt=endArray[index]
|
||||
start = startArray[index]
|
||||
bidDict = {}
|
||||
askDict = {}
|
||||
bar_vol=voluememin[index]
|
||||
bar_close=closes[index]
|
||||
bar_open=opens[index]
|
||||
bar_low=lows[index]
|
||||
bar_high=highs[index]
|
||||
bar_symbol=symbolarray[index]
|
||||
# for indexTick in range(indexFinal,len(df_tick)):
|
||||
# if tTickArray[indexTick] >= tEnd:
|
||||
# break
|
||||
# elif (tTickArray[indexTick] >= start) & (tTickArray[indexTick] < tEnd):
|
||||
Bp = round(bp1TickArray[0],4)
|
||||
Ap = round(ap1TickArray[0],4)
|
||||
LastPrice = round(lastTickArray[0],4)
|
||||
Volume = volumeTickArray[0]
|
||||
if LastPrice >= Ap:
|
||||
if str(LastPrice) in askDict.keys():
|
||||
askDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
askDict[str(LastPrice)] = Volume
|
||||
if LastPrice <= Bp:
|
||||
if str(LastPrice) in bidDict.keys():
|
||||
bidDict[str(LastPrice)] += Volume
|
||||
else:
|
||||
bidDict[str(LastPrice)] = Volume
|
||||
# indexFinal = indexTick
|
||||
bidDictResult,askDictResult = self.process(bidDict,askDict,symbol)
|
||||
bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))
|
||||
askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))
|
||||
prinslist=list(bidDictResult.keys())
|
||||
asklist=list(askDictResult.values())
|
||||
bidlist=list(bidDictResult.values())
|
||||
delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))
|
||||
#print(prinslist,asklist,bidlist)
|
||||
#print(len(prinslist),len(bidDictResult),len(askDictResult))
|
||||
df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})
|
||||
#df=pd.DataFrame({'price':pd.Series(bidDictResult.keys()),'Ask':pd.Series(askDictResult.values()),'Bid':pd.Series(bidDictResult.values())})
|
||||
df['symbol']=bar_symbol
|
||||
df['datetime']=dt
|
||||
df['delta']=str(delta)
|
||||
df['close']=bar_close
|
||||
df['open']=bar_open
|
||||
df['high']=bar_high
|
||||
df['low']=bar_low
|
||||
df['volume']=bar_vol
|
||||
#df['ticktime']=tTickArray[0]
|
||||
df['dj'] = self.GetOrderFlow_dj(df)
|
||||
ofdatadict[symbol]=df
|
||||
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
def GetOrderFlow_dj(self,kData):
|
||||
param = self.param_dict[self.品种]
|
||||
Config = {
|
||||
'Value1': param.失衡,
|
||||
'Value2': param.堆积,
|
||||
'Value4': True,
|
||||
}
|
||||
aryData = kData
|
||||
djcout = 0
|
||||
|
||||
# 遍历kData中的每一行,计算djcout指标
|
||||
for index, row in aryData.iterrows():
|
||||
kItem = aryData.iloc[index]
|
||||
high = kItem['high']
|
||||
low = kItem['low']
|
||||
close = kItem['close']
|
||||
open = kItem['open']
|
||||
dtime = kItem['datetime']
|
||||
price_s = kItem['price']
|
||||
Ask_s = kItem['Ask']
|
||||
Bid_s = kItem['Bid']
|
||||
delta = kItem['delta']
|
||||
|
||||
price_s = price_s
|
||||
Ask_s = Ask_s
|
||||
Bid_s = Bid_s
|
||||
|
||||
gj = 0
|
||||
xq = 0
|
||||
gxx = 0
|
||||
xxx = 0
|
||||
|
||||
# 遍历price_s中的每一个元素,计算相关指标
|
||||
for i in np.arange(0, len(price_s), 1):
|
||||
duiji = {
|
||||
'price': 0,
|
||||
'time': 0,
|
||||
'longshort': 0,
|
||||
}
|
||||
|
||||
if i == 0:
|
||||
delta = delta
|
||||
|
||||
order= {
|
||||
"Price":price_s[i],
|
||||
"Bid":{ "Value":Bid_s[i]},
|
||||
"Ask":{ "Value":Ask_s[i]}
|
||||
}
|
||||
#空头堆积
|
||||
if i >= 0 and i < len(price_s) - 1:
|
||||
if (order["Bid"]["Value"] > Ask_s[i + 1] * int(Config['Value1'])):
|
||||
gxx += 1
|
||||
gj += 1
|
||||
if gj >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = -1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += -1
|
||||
else:
|
||||
gj = 0
|
||||
#多头堆积
|
||||
if i >= 1 and i <= len(price_s) - 1:
|
||||
if (order["Ask"]["Value"] > Bid_s[i - 1] * int(Config['Value1'])):
|
||||
xq += 1
|
||||
xxx += 1
|
||||
if xq >= int(Config['Value2']) and Config['Value4'] == True:
|
||||
duiji['price'] = price_s[i]
|
||||
duiji['time'] = dtime
|
||||
duiji['longshort'] = 1
|
||||
if float(duiji['price']) > 0:
|
||||
djcout += 1
|
||||
else:
|
||||
xq = 0
|
||||
|
||||
# 返回计算得到的djcout值
|
||||
return djcout
|
||||
|
||||
def OnRtnTrade(self, pTrade):
|
||||
print("||成交回报||", pTrade)
|
||||
|
||||
def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast):
|
||||
print("||OnRspOrderInsert||", pInputOrder, pRspInfo, nRequestID, bIsLast)
|
||||
|
||||
# 订单状态通知
|
||||
def OnRtnOrder(self, pOrder):
|
||||
print("||订单回报||", pOrder)
|
||||
|
||||
#保存OF数据
|
||||
def save_trade_data(self,df,instrument_id):
|
||||
# 定义文件路径
|
||||
csv_file_path = f"ofdata/{instrument_id}_ofdata.csv"
|
||||
directory = os.path.dirname(csv_file_path)
|
||||
|
||||
# 检查目录是否存在,如果不存在则创建它
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
# 如果文件夹存在,则追加数据;否则,创建新文件并保存整个 DataFrame
|
||||
if os.path.exists(csv_file_path):
|
||||
# 仅保存最后一行数据
|
||||
df.tail(1).to_csv(csv_file_path, mode='a', header=False, index=False)
|
||||
else:
|
||||
# 创建新文件并保存整个 DataFrame
|
||||
df.to_csv(csv_file_path, index=False)
|
||||
|
||||
def w_log(self,symbol,log_message):
|
||||
|
||||
# 创建文件夹(如果不存在)
|
||||
log_dir = 'tradelogs'
|
||||
if not os.path.exists(log_dir):
|
||||
os.makedirs(log_dir)
|
||||
|
||||
# 写入日志到 CSV 文件
|
||||
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
log_file = os.path.join(log_dir, f'{symbol}log.csv')
|
||||
# 打印日志到控制台
|
||||
print(f'{now}: {log_message}')
|
||||
with open(log_file, 'a', encoding='utf-8',newline='') as csvfile:
|
||||
writer = csv.writer(csvfile)
|
||||
# 如果文件为空,写入表头
|
||||
if csvfile.tell() == 0:
|
||||
writer.writerow(['time', 'logs'])
|
||||
writer.writerow([now, log_message])
|
||||
|
||||
# 计算单品种资金流向数据
|
||||
def 资金流向计算(self,df):
|
||||
# 将 'delta' 和 'close' 转换为数值类型,强制转换错误
|
||||
df['volume'] = pd.to_numeric(df['volume'], errors='coerce')
|
||||
df['close'] = pd.to_numeric(df['close'], errors='coerce')
|
||||
|
||||
# 删除 'delta' 或 'close' 中的 NaN 值
|
||||
df = df.dropna(subset=['volume', 'close'])
|
||||
symbol=df['symbol'].iloc[-1]
|
||||
symbol = ''.join(filter(str.isalpha, symbol)).upper()
|
||||
资金净流向 = abs(sum(df['volume']*df['close']))*合约信息[symbol]['合约单位']*合约信息[symbol]['保证金']
|
||||
更新状态=True
|
||||
# 将结果放入 DataFrame
|
||||
result_df = pd.DataFrame({
|
||||
'资金净流向': [资金净流向],
|
||||
'更新状态': [更新状态]
|
||||
})
|
||||
|
||||
return result_df
|
||||
|
||||
# 收盘清仓
|
||||
def 收盘清仓(self,symbol,data):
|
||||
param = self.param_dict[symbol]
|
||||
# 获取当前时间
|
||||
current_time = datetime.now().time()
|
||||
|
||||
# 设置清仓操作的时间范围1:14:55到15:00
|
||||
clearing_time1_start = s_time(14, 55)
|
||||
clearing_time1_end = s_time(15, 0)
|
||||
|
||||
# 设置清仓操作的时间范围2:00:55到01:00
|
||||
clearing_time2_start = s_time(22, 55)
|
||||
clearing_time2_end = s_time(23, 0)
|
||||
now = datetime.now()
|
||||
# 创建一个标志变量,用于记录是否已经执行过清仓操作
|
||||
#param.clearing_executed = False
|
||||
|
||||
# 检查当前时间是否在第一个清仓操作的时间范围内,并且清仓操作未执行过
|
||||
if clearing_time1_start <= current_time <= clearing_time1_end and not param.clearing_executed :
|
||||
#trade_dfs.drop(trade_dfs.index,inplace=True)#清除当天的行情数据
|
||||
if param.pos>0:
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
self.w_log(symbol,f"{symbol}多头清仓操作")
|
||||
pass
|
||||
elif param.pos<0:
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
self.w_log(symbol,f"{symbol}空头清仓操作")
|
||||
pass
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
|
||||
# 检查当前时间是否在第二个清仓操作的时间范围内,并且清仓操作未执行过
|
||||
elif clearing_time2_start <= current_time <= clearing_time2_end and not param.clearing_executed :
|
||||
#trade_dfs.drop(trade_dfs.index,inplace=True) #清除当天的行情数据
|
||||
if param.pos>0:
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
self.w_log(symbol,f"{symbol}多头清仓操作")
|
||||
pass
|
||||
elif param.pos<0:
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
self.w_log(symbol,f"{symbol}空头清仓操作")
|
||||
pass
|
||||
param.clearing_executed = True # 设置标志变量为已执行
|
||||
# 如果不在任何清仓操作的时间范围内,可以执行其他操作或不执行任何操作
|
||||
else:
|
||||
param.clearing_executed = False
|
||||
pass
|
||||
#print("不在清仓操作时间范围内")
|
||||
|
||||
return param.clearing_executed
|
||||
|
||||
def cal_sig(self, symbol_queue):
|
||||
while True:
|
||||
try:
|
||||
now=datetime.now()
|
||||
data = symbol_queue.get(block=True, timeout=5) # 如果5秒没收到新的tick行情,则抛出异常
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
size = symbol_queue.qsize()
|
||||
if size > 1:
|
||||
print(f'当前{instrument_id}共享队列长度为{size}, 有点阻塞!!!!!')
|
||||
param = self.param_dict[instrument_id]
|
||||
self.品种=instrument_id
|
||||
#OF计算数据开始
|
||||
self.tickcome(data)
|
||||
trade_df = trade_dfs[instrument_id]
|
||||
#清仓开关
|
||||
run_kg=self.收盘清仓(instrument_id,data)
|
||||
最新价=data['LastPrice']
|
||||
sympc=data['InstrumentID'].decode()
|
||||
# #多头时间出场-----------------------暂时用不到------------------------
|
||||
# if param.pos>0 and param.多头开仓历时>param.平_多时间 :
|
||||
# #平多
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
# param.pos=0
|
||||
# param.多头止损价格=0
|
||||
# param.多头开仓历时=0
|
||||
# param.多头成本价格=0
|
||||
# self.w_log(sympc,f'历时{param.平_多时间}***多头***{sympc}时间出场价格{最新价}')
|
||||
|
||||
#多头价格止损
|
||||
if param.pos>0 and 最新价<param.多头止损价格 :
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
param.多头止损价格=0
|
||||
param.多头开仓历时=0
|
||||
param.多头成本价格=0
|
||||
self.w_log(sympc,f'多头止损触发: {最新价},多头止损价格:{param.多头止损价格} ***{sympc}多头止损***')
|
||||
|
||||
# #多头跟踪止盈
|
||||
elif param.pos>0 and len(trade_df)>1 and 最新价<trade_df['10_MA'].iloc[-1] and 最新价>param.多头成本价格 :
|
||||
#平多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
param.pos=0
|
||||
param.多头止损价格=0
|
||||
param.多头开仓历时=0
|
||||
param.多头成本价格=0
|
||||
self.w_log(sympc,f'多头跟踪止盈触发: {最新价} ***{sympc}多头止盈***')
|
||||
|
||||
# # #空头时间出场-----------------------暂时用不到------------------------
|
||||
# if param.pos<0 and param.空头开仓历时>param.平_空时间 :
|
||||
# #平空
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
# param.pos=0
|
||||
# param.空头止损价格=0
|
||||
# param.空头开仓历时=0
|
||||
# param.空头成本价格=0
|
||||
# self.w_log(sympc,f'历时{param.平_空时间}***空头***{sympc}时间出场价格{最新价}')
|
||||
|
||||
#空头价格止损
|
||||
if param.pos<0 and 最新价>param.空头止损价格 :
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
param.空头止损价格=0
|
||||
param.空头开仓历时=0
|
||||
param.空头成本价格=0
|
||||
self.w_log(sympc,f'空头止损触发: {最新价},空头止损价格:{param.空头止损价格} ***{sympc}空头止损***')
|
||||
|
||||
# #空头跟踪止盈
|
||||
elif param.pos<0 and len(trade_df)>1 and 最新价>trade_df['10_MA'].iloc[-1] and 最新价<param.空头成本价格 :
|
||||
#平空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
param.pos=0
|
||||
param.空头止损价格=0
|
||||
param.空头开仓历时=0
|
||||
param.空头成本价格=0
|
||||
self.w_log(sympc,f'空头跟踪止盈触发: {最新价},***{sympc}空头止盈***')
|
||||
|
||||
#交易程序开始
|
||||
if len(trade_df)>param.cont_df and run_kg==False:
|
||||
#开仓历时更新:
|
||||
if param.pos>0:
|
||||
param.多头开仓历时+=1
|
||||
elif param.pos<0:
|
||||
param.空头开仓历时+=1
|
||||
|
||||
#计算截面数据
|
||||
截面数据_资金流向[instrument_id]=self.资金流向计算(trade_df)
|
||||
|
||||
#日均线
|
||||
trade_df['dayma']=trade_df['close'].mean()
|
||||
|
||||
# 计算5日均线和10日均线,即使数据不足5日或10日
|
||||
trade_df['5_MA'] = trade_df['close'].rolling(window=5, min_periods=1).mean()
|
||||
trade_df['10_MA'] = trade_df['close'].rolling(window=10, min_periods=1).mean()
|
||||
|
||||
# 计算累积的delta值
|
||||
trade_df['delta'] = trade_df['delta'].astype(float)
|
||||
trade_df['delta累计'] = trade_df['delta'].cumsum()
|
||||
|
||||
#大于日均线
|
||||
开多1=trade_df['dayma'].iloc[-1] > 0 and trade_df['close'].iloc[-1] > trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量大于X
|
||||
开多4=trade_df['delta累计'].iloc[-1] > param.sum_delta and trade_df['delta'].iloc[-1] > param.delta
|
||||
|
||||
#小于日均线
|
||||
开空1=trade_df['dayma'].iloc[-1]>0 and trade_df['close'].iloc[-1] < trade_df['dayma'].iloc[-1]
|
||||
|
||||
#累计多空净量小于X
|
||||
开空4=trade_df['delta累计'].iloc[-1] < -param.sum_delta and trade_df['delta'].iloc[-1] < -param.delta
|
||||
|
||||
开多组合= 开多1 and 开多4 and trade_df['dj'].iloc[-1]>param.dj_X and trade_df['5_MA'].iloc[-1] > trade_df['10_MA'].iloc[-1]
|
||||
开空条件= 开空1 and 开空4 and trade_df['dj'].iloc[-1]<-param.dj_X and trade_df['5_MA'].iloc[-1] < trade_df['10_MA'].iloc[-1]
|
||||
symm=data['InstrumentID'].decode()
|
||||
#开平仓
|
||||
#换仓平多
|
||||
# if param.pos>0 and symm not in top_two_symbols:
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'1')
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'3')
|
||||
# param.pos=0
|
||||
# param.多头止损价格=0
|
||||
# param.多头开仓历时=0
|
||||
# param.多头成本价格=0
|
||||
# self.w_log(symm,f'当前截面品种{top_two_symbols},{symm}不在范围,***多平仓***')
|
||||
#多头开仓
|
||||
if param.pos==0 and 开多组合 and symm in top_two_symbols :
|
||||
#开多
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'0')
|
||||
param.pos=1
|
||||
param.多头止损价格=trade_df['low'].iloc[-2]
|
||||
param.多头成本价格=data['AskPrice1']
|
||||
param.多头开仓历时=1
|
||||
self.w_log(symm,f'品种:{symm},委托价格: {param.多头成本价格}***开多***')
|
||||
|
||||
#换仓平空
|
||||
# if param.pos<0 and symm not in top_two_symbols :
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'1')
|
||||
# self.insert_order(data['ExchangeID'], data['InstrumentID'], data['AskPrice1']+param.py,param.Lots,b'0',b'3')
|
||||
# param.pos=0
|
||||
# param.空头止损价格=0
|
||||
# param.空头开仓历时=0
|
||||
# param.空头成本价格=0
|
||||
# self.w_log(symm,f'当前截面品种{top_two_symbols},{symm}不在范围,***空平仓***')
|
||||
#空头开仓
|
||||
if param.pos==0 and 开空条件 and symm in top_two_symbols :
|
||||
#开空
|
||||
self.insert_order(data['ExchangeID'], data['InstrumentID'], data['BidPrice1']-param.py,param.Lots,b'1',b'0')
|
||||
param.pos=-1
|
||||
param.空头止损价格=trade_df['high'].iloc[-2]
|
||||
param.空头成本价格=data['BidPrice1']
|
||||
param.空头开仓历时=1
|
||||
self.w_log(symm,f'品种:{symm},委托价格: {param.空头成本价格}***开空***')
|
||||
#print(trade_df)
|
||||
#保存OF数据
|
||||
self.save_trade_data(trade_df,symm)
|
||||
#保存bar计数
|
||||
param.cont_df=len(trade_df)
|
||||
except queue.Empty:
|
||||
# print(f"当前合约队列为空,等待新数据插入。")
|
||||
pass
|
||||
|
||||
# 将CTP推送的行情数据分发给对应线程队列去执行
|
||||
def distribute_tick(self):
|
||||
while True:
|
||||
if self.status == 0:
|
||||
data = None
|
||||
while not self.md_queue.empty():
|
||||
data = self.md_queue.get(block=False)
|
||||
instrument_id = data['InstrumentID'].decode() # 品种代码
|
||||
try:
|
||||
self.queue_dict[instrument_id].put(data, block=False) # 往对应合约队列中插入行情
|
||||
# print(f"{instrument_id}合约数据插入。")
|
||||
except queue.Full:
|
||||
# 当某个线程阻塞导致对应队列容量超限时抛出异常,不会影响其他合约的信号计算
|
||||
print(f"{instrument_id}合约信号计算阻塞导致对应队列已满,请检查对应代码逻辑后重启。")
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
def start(self, param_dict):
|
||||
threads = []
|
||||
self.param_dict = param_dict
|
||||
thread1 = threading.Thread(target=横截面计算)
|
||||
for symbol in param_dict.keys():
|
||||
trade_dfs[symbol] = pd.DataFrame({})
|
||||
self.queue_dict[symbol] = queue.Queue(10) #为每个合约创建一个限制数为10的队列,当计算发生阻塞导致队列达到限制数时会抛出异常
|
||||
t = threading.Thread(target=self.cal_sig, args=(self.queue_dict[symbol],)) # 为每个合约单独创建一个线程计算开仓逻辑
|
||||
threads.append(t)
|
||||
t.start()
|
||||
thread1.start()
|
||||
self.distribute_tick()
|
||||
for t in threads:
|
||||
t.join()
|
||||
thread1.join()
|
||||
|
||||
# 定义横截面计算函数
|
||||
def 横截面计算():
|
||||
global top_two_symbols
|
||||
while True:
|
||||
if len(截面数据_资金流向)>5:
|
||||
goss=1
|
||||
# 检查是否有任何品种的更新状态为 False,如果有则直接返回
|
||||
for symbol, data in 截面数据_资金流向.items():
|
||||
if not data['更新状态'].iloc[-1]:
|
||||
#print(f"品种 {symbol} 的更新状态为 False,跳过计算。")
|
||||
goss=0
|
||||
break
|
||||
if goss==1:
|
||||
# 继续计算资金净流向
|
||||
sorted_items = sorted(截面数据_资金流向.items(), key=lambda item: item[1]['资金净流向'].iloc[-1], reverse=True)
|
||||
max_symbol = sorted_items[0][0]
|
||||
two_max_symbol = sorted_items[1][0]
|
||||
three_max_symbol = sorted_items[2][0]
|
||||
four_max_symbol = sorted_items[3][0]
|
||||
five_max_symbol = sorted_items[4][0]
|
||||
top_two_symbols = [max_symbol, two_max_symbol,three_max_symbol,four_max_symbol,five_max_symbol]
|
||||
|
||||
print(f'选出的活跃品种: {top_two_symbols}')
|
||||
print(f'截面数据_资金流向: {截面数据_资金流向}')
|
||||
# 将所有品种的更新状态设置为 False
|
||||
for symbol in 截面数据_资金流向:
|
||||
截面数据_资金流向[symbol]['更新状态'] = False
|
||||
time.sleep(1)
|
||||
|
||||
def run_trader(param_dict, broker_id, td_server, investor_id, password, app_id, auth_code, md_queue=None, page_dir='', private_resume_type=2, public_resume_type=2):
|
||||
my_trader = MyTrader(broker_id, td_server, investor_id, password, app_id, auth_code, md_queue, page_dir, private_resume_type, public_resume_type)
|
||||
my_trader.start(param_dict)
|
||||
|
||||
if __name__ == '__main__':
|
||||
#global symbol
|
||||
#公众号:松鼠Quant
|
||||
#主页:www.quant789.com
|
||||
#本策略仅作学习交流使用,实盘交易盈亏投资者个人负责!!!
|
||||
#版权归松鼠Quant所有,禁止转发、转卖源码违者必究。
|
||||
|
||||
#注意:运行前请先安装好algoplus,
|
||||
# pip install AlgoPlus
|
||||
#http://www.algo.plus/ctp/python/0103001.html
|
||||
|
||||
|
||||
# 实盘参数字典,需要实盘交易的合约,新建对应的参数对象即可,以下参数仅供测试使用,不作为实盘参考!!!!
|
||||
历时平仓=4
|
||||
|
||||
param_dict = {}
|
||||
param_dict['SR409'] = ParamObj(symbol='SR409', Lots=1, py=6,dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['eb2408'] = ParamObj(symbol='eb2408', Lots=2, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['SA409'] = ParamObj(symbol='SA409', Lots=1, py=6,dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['pp409'] = ParamObj(symbol='pp409', Lots=2, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['OI409'] = ParamObj(symbol='OI409', Lots=1, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['a2409'] = ParamObj(symbol='a2409', Lots=1, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['p2409'] = ParamObj(symbol='p2409', Lots=1, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['RM409'] = ParamObj(symbol='RM409', Lots=2, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
param_dict['sp2409'] = ParamObj(symbol='sp2409', Lots=1, py=6, dj_X=0,delta=0,sum_delta=0,失衡=3,堆积=3,周期='1T',平_多时间=历时平仓,平_空时间=历时平仓)
|
||||
|
||||
|
||||
#用simnow模拟,不要忘记屏蔽下方实盘的future_account字典
|
||||
future_account = get_simulate_account(
|
||||
investor_id='', # simnow账户,注意是登录账户的ID,SIMNOW个人首页查看
|
||||
password='', # simnow密码
|
||||
server_name='电信1', # 电信1、电信2、移动、TEST、N视界
|
||||
subscribe_list=list(param_dict.keys()), # 合约列表
|
||||
)
|
||||
|
||||
# #实盘用这个,不要忘记屏蔽上方simnow的future_account字典
|
||||
# future_account = FutureAccount(
|
||||
# broker_id='', # 期货公司BrokerID
|
||||
# server_dict={'TDServer': "ip:port", 'MDServer': 'ip:port'}, # TDServer为交易服务器,MDServer为行情服务器。服务器地址格式为"ip:port。"
|
||||
# reserve_server_dict={}, # 备用服务器地址
|
||||
# investor_id='', # 账户
|
||||
# password='', # 密码
|
||||
# app_id='simnow_client_test', # 认证使用AppID
|
||||
# auth_code='0000000000000000', # 认证使用授权码
|
||||
# subscribe_list=list(param_dict.keys()), # 订阅合约列表
|
||||
# md_flow_path='./log', # MdApi流文件存储地址,默认MD_LOCATION
|
||||
# td_flow_path='./log', # TraderApi流文件存储地址,默认TD_LOCATION
|
||||
# )
|
||||
|
||||
|
||||
print('开始',len(future_account.subscribe_list))
|
||||
# 共享队列
|
||||
share_queue = Queue(maxsize=200)
|
||||
|
||||
# 行情进程
|
||||
md_process = Process(target=run_tick_engine, args=(future_account, [share_queue]))
|
||||
|
||||
|
||||
# 交易进程
|
||||
trader_process = Process(target=run_trader, args=(
|
||||
param_dict,
|
||||
future_account.broker_id,
|
||||
future_account.server_dict['TDServer'],
|
||||
future_account.investor_id,
|
||||
future_account.password,
|
||||
future_account.app_id,
|
||||
future_account.auth_code,
|
||||
share_queue, # 队列
|
||||
future_account.td_flow_path
|
||||
))
|
||||
|
||||
md_process.start()
|
||||
trader_process.start()
|
||||
|
||||
md_process.join()
|
||||
trader_process.join()
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
,主连代码_今日,品种代码,主连代码_昨日,主连代码_相等
|
||||
0,a2409,a,a2409,True
|
||||
1,ag2408,ag,ag2408,True
|
||||
2,al2408,al,al2408,True
|
||||
3,ao2408,ao,ao2408,True
|
||||
4,AP410,AP,AP410,True
|
||||
5,au2410,au,au2410,True
|
||||
6,b2409,b,b2409,True
|
||||
7,bb2501,bb,bb2501,True
|
||||
8,bc2408,bc,bc2408,True
|
||||
9,br2408,br,br2408,True
|
||||
10,bu2409,bu,bu2409,True
|
||||
11,c2409,c,c2409,True
|
||||
12,CF409,CF,CF409,True
|
||||
13,CJ409,CJ,CJ409,True
|
||||
14,cs2409,cs,cs2409,True
|
||||
15,cu2408,cu,cu2408,True
|
||||
16,CY409,CY,CY409,True
|
||||
17,eb2408,eb,eb2408,True
|
||||
18,ec2410,ec,ec2410,True
|
||||
19,eg2409,eg,eg2409,True
|
||||
20,fb2409,fb,fb2409,True
|
||||
21,FG409,FG,FG409,True
|
||||
22,fu2409,fu,fu2409,True
|
||||
23,hc2410,hc,hc2410,True
|
||||
24,i2409,i,i2409,True
|
||||
25,IC2407,IC,IC2407,True
|
||||
26,IF2407,IF,IF2407,True
|
||||
27,IH2407,IH,IH2407,True
|
||||
28,IM2407,IM,IM2407,True
|
||||
29,j2409,j,j2409,True
|
||||
30,jd2409,jd,jd2409,True
|
||||
31,jm2409,jm,jm2409,True
|
||||
32,l2409,l,l2409,True
|
||||
33,lc2411,lc,lc2411,True
|
||||
34,lh2409,lh,lh2409,True
|
||||
35,lu2409,lu,lu2409,True
|
||||
36,m2409,m,m2409,True
|
||||
37,MA409,MA,MA409,True
|
||||
38,ni2409,ni,ni2409,True
|
||||
39,nr2409,nr,nr2409,True
|
||||
40,OI409,OI,OI409,True
|
||||
41,p2409,p,p2409,True
|
||||
42,pb2408,pb,pb2408,True
|
||||
43,PF409,PF,PF409,True
|
||||
44,pg2409,pg,pg2409,True
|
||||
45,PK410,PK,PK410,True
|
||||
46,pp2409,pp,pp2409,True
|
||||
47,PX409,PX,PX409,True
|
||||
48,rb2410,rb,rb2410,True
|
||||
49,RM409,RM,RM409,True
|
||||
50,rr2409,rr,rr2409,True
|
||||
51,RS411,RS,RS411,True
|
||||
52,ru2409,ru,ru2409,True
|
||||
53,SA409,SA,SA409,True
|
||||
54,sc2408,sc,sc2408,True
|
||||
55,SF409,SF,SF409,True
|
||||
56,SH409,SH,SH409,True
|
||||
57,si2409,si,si2409,True
|
||||
58,SM501,SM,SM501,True
|
||||
59,sn2408,sn,sn2408,True
|
||||
60,sp2409,sp,sp2409,True
|
||||
61,SR409,SR,SR409,True
|
||||
62,ss2409,ss,ss2409,True
|
||||
63,T2409,T,T2409,True
|
||||
64,TA409,TA,TA409,True
|
||||
65,TF2409,TF,TF2409,True
|
||||
66,TL2409,TL,TL2409,True
|
||||
67,TS2409,TS,TS2409,True
|
||||
68,UR409,UR,UR409,True
|
||||
69,v2409,v,v2409,True
|
||||
70,wr2409,wr,wr2409,True
|
||||
71,y2409,y,y2409,True
|
||||
72,zn2408,zn,zn2408,True
|
||||
|
@@ -0,0 +1,770 @@
|
||||
交易所,合约代码,合约名称,品种代码,品种名称,合约乘数,最小跳动,开仓费率(按金额),开仓费用(按手),平仓费率(按金额),平仓费用(按手),平今费率(按金额),平今费用(按手),做多保证金率(按金额),做多保证金(按手),做空保证金率(按金额),做空保证金(按手),上日结算价,上日收盘价,最新价,成交量,持仓量,1手开仓费用,1手平仓费用,1手平今费用,做多1手保证金,做空1手保证金,1手市值,1Tick平仓盈亏,1Tick平仓净利,2Tick平仓净利,1Tick平仓收益率%,2Tick平仓收益率%,1Tick平今净利,2Tick平今净利,1Tick平今收益率%,2Tick平今收益率%,交割月份
|
||||
CZCE,AP410,苹果10月,AP,苹果,10,1.0,0.0,5.01,0.0,5.01,0.0,20.01,0.15,0,0.15,0,6896.0,6926.0,6926.0,0,167339,5.01,5.01,20.01,10389.0,10389.0,69260.0,10.0,-0.03,9.97,-0.0,0.096,-15.03,-5.03,-0.145,-0.048,410
|
||||
CZCE,AP411,苹果11月,AP,苹果,10,1.0,0.0,5.01,0.0,5.01,0.0,20.01,0.15,0,0.15,0,6610.0,6632.0,6632.0,0,16009,5.01,5.01,20.01,9948.0,9948.0,66320.0,10.0,-0.03,9.97,-0.0,0.1,-15.03,-5.03,-0.151,-0.051,411
|
||||
CZCE,AP412,苹果12月,AP,苹果,10,1.0,0.0,5.01,0.0,5.01,0.0,20.01,0.15,0,0.15,0,6738.0,6749.0,6749.0,0,878,5.01,5.01,20.01,10123.5,10123.5,67490.0,10.0,-0.03,9.97,-0.0,0.099,-15.03,-5.03,-0.148,-0.05,412
|
||||
CZCE,AP501,苹果1月,AP,苹果,10,1.0,0.0,5.01,0.0,5.01,0.0,20.01,0.15,0,0.15,0,6828.0,6850.0,6850.0,0,37560,5.01,5.01,20.01,10275.0,10275.0,68500.0,10.0,-0.03,9.97,-0.0,0.097,-15.03,-5.03,-0.146,-0.049,501
|
||||
CZCE,AP503,苹果3月,AP,苹果,10,1.0,0.0,5.01,0.0,5.01,0.0,20.01,0.15,0,0.15,0,6861.0,6878.0,6878.0,0,751,5.01,5.01,20.01,10317.0,10317.0,68780.0,10.0,-0.03,9.97,-0.0,0.097,-15.03,-5.03,-0.146,-0.049,503
|
||||
CZCE,AP504,苹果4月,AP,苹果,10,1.0,0.0,5.01,0.0,5.01,0.0,20.01,0.15,0,0.15,0,6936.0,6940.0,6940.0,0,192,5.01,5.01,20.01,10410.0,10410.0,69400.0,10.0,-0.03,9.97,-0.0,0.096,-15.03,-5.03,-0.144,-0.048,504
|
||||
CZCE,AP505,苹果5月,AP,苹果,10,1.0,0.0,5.01,0.0,5.01,0.0,20.01,0.15,0,0.15,0,6976.0,7000.0,7000.0,0,1271,5.01,5.01,20.01,10500.0,10500.0,70000.0,10.0,-0.03,9.97,-0.0,0.095,-15.03,-5.03,-0.143,-0.048,505
|
||||
CZCE,CF407,棉花7月,CF,一号棉花,5,5.0,0.0,4.31,0.0,4.31,0.0,0.0,0.25,0,0.25,0,14185.0,14090.0,14260.0,692,7156,4.31,4.31,0.0,17825.0,17825.0,71300.0,25.0,16.37,41.37,0.092,0.232,20.68,45.68,0.116,0.256,407
|
||||
CZCE,CF409,棉花9月,CF,一号棉花,5,5.0,0.0,4.31,0.0,4.31,0.0,0.0,0.12,0,0.12,0,14470.0,14405.0,14540.0,112968,518388,4.31,4.31,0.0,8724.0,8724.0,72700.0,25.0,16.37,41.37,0.188,0.474,20.68,45.68,0.237,0.524,409
|
||||
CZCE,CF411,棉花11月,CF,一号棉花,5,5.0,0.0,4.31,0.0,4.31,0.0,0.0,0.12,0,0.12,0,14540.0,14500.0,14610.0,9642,9218,4.31,4.31,0.0,8766.0,8766.0,73050.0,25.0,16.37,41.37,0.187,0.472,20.68,45.68,0.236,0.521,411
|
||||
CZCE,CF501,棉花1月,CF,一号棉花,5,5.0,0.0,4.31,0.0,4.31,0.0,0.0,0.12,0,0.12,0,14515.0,14475.0,14570.0,23952,161744,4.31,4.31,0.0,8742.0,8742.0,72850.0,25.0,16.37,41.37,0.187,0.473,20.68,45.68,0.237,0.523,501
|
||||
CZCE,CF503,棉花3月,CF,一号棉花,5,5.0,0.0,4.31,0.0,4.31,0.0,0.0,0.12,0,0.12,0,14530.0,14515.0,14605.0,71,4740,4.31,4.31,0.0,8763.0,8763.0,73025.0,25.0,16.37,41.37,0.187,0.472,20.68,45.68,0.236,0.521,503
|
||||
CZCE,CF505,棉花5月,CF,一号棉花,5,5.0,0.0,4.31,0.0,4.31,0.0,0.0,0.12,0,0.12,0,14550.0,14530.0,14615.0,436,5352,4.31,4.31,0.0,8769.0,8769.0,73075.0,25.0,16.37,41.37,0.187,0.472,20.68,45.68,0.236,0.521,505
|
||||
CZCE,CJ407,红枣7月,CJ,红枣,5,5.0,0.0,10.01,0.0,10.01,0.0,10.01,0.25,0,0.25,0,10270.0,10300.0,10300.0,0,10,10.01,10.01,10.01,12875.0,12875.0,51500.0,25.0,4.97,29.97,0.039,0.233,4.97,29.97,0.039,0.233,407
|
||||
CZCE,CJ409,红枣9月,CJ,红枣,5,5.0,0.0,10.01,0.0,10.01,0.0,10.01,0.2,0,0.2,0,10325.0,10420.0,10420.0,0,59460,10.01,10.01,10.01,10420.0,10420.0,52100.0,25.0,4.97,29.97,0.048,0.288,4.97,29.97,0.048,0.288,409
|
||||
CZCE,CJ412,红枣12月,CJ,红枣,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,10885.0,10970.0,10970.0,0,1220,3.01,3.01,3.01,9324.5,9324.5,54850.0,25.0,18.97,43.97,0.203,0.472,18.97,43.97,0.203,0.472,412
|
||||
CZCE,CJ501,红枣1月,CJ,红枣,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,10920.0,11015.0,11015.0,0,44096,3.01,3.01,3.01,9362.75,9362.75,55075.0,25.0,18.97,43.97,0.203,0.47,18.97,43.97,0.203,0.47,501
|
||||
CZCE,CJ503,红枣3月,CJ,红枣,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,10930.0,11005.0,11005.0,0,1476,3.01,3.01,3.01,9354.25,9354.25,55025.0,25.0,18.97,43.97,0.203,0.47,18.97,43.97,0.203,0.47,503
|
||||
CZCE,CJ505,红枣5月,CJ,红枣,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,11005.0,11105.0,11105.0,0,3477,3.01,3.01,3.01,9439.25,9439.25,55525.0,25.0,18.97,43.97,0.201,0.466,18.97,43.97,0.201,0.466,505
|
||||
CZCE,CY407,棉纱7月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.3,0,0.3,0,19515.0,19515.0,19515.0,0,4,4.02,4.02,0.01,29272.5,29272.5,97575.0,25.0,16.97,41.97,0.058,0.143,20.98,45.98,0.072,0.157,407
|
||||
CZCE,CY408,棉纱8月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,20300.0,20300.0,20300.0,0,0,4.02,4.02,0.01,17255.0,17255.0,101500.0,25.0,16.97,41.97,0.098,0.243,20.98,45.98,0.122,0.266,408
|
||||
CZCE,CY409,棉纱9月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,20125.0,20020.0,20140.0,669,4999,4.02,4.02,0.01,17119.0,17119.0,100700.0,25.0,16.97,41.97,0.099,0.245,20.98,45.98,0.123,0.269,409
|
||||
CZCE,CY410,棉纱10月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,20100.0,19970.0,19970.0,0,0,4.02,4.02,0.01,16974.5,16974.5,99850.0,25.0,16.97,41.97,0.1,0.247,20.98,45.98,0.124,0.271,410
|
||||
CZCE,CY411,棉纱11月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,20495.0,20495.0,20535.0,1,1,4.02,4.02,0.01,17454.75,17454.75,102675.0,25.0,16.97,41.97,0.097,0.24,20.98,45.98,0.12,0.263,411
|
||||
CZCE,CY412,棉纱12月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,20775.0,20775.0,20775.0,0,1,4.02,4.02,0.01,17658.75,17658.75,103875.0,25.0,16.97,41.97,0.096,0.238,20.98,45.98,0.119,0.26,412
|
||||
CZCE,CY501,棉纱1月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,20430.0,20290.0,20435.0,32,523,4.02,4.02,0.01,17369.75,17369.75,102175.0,25.0,16.97,41.97,0.098,0.242,20.98,45.98,0.121,0.265,501
|
||||
CZCE,CY502,棉纱2月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,20725.0,20725.0,20725.0,0,1,4.02,4.02,0.01,17616.25,17616.25,103625.0,25.0,16.97,41.97,0.096,0.238,20.98,45.98,0.119,0.261,502
|
||||
CZCE,CY503,棉纱3月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,21245.0,21245.0,21245.0,0,4,4.02,4.02,0.01,18058.25,18058.25,106225.0,25.0,16.97,41.97,0.094,0.232,20.98,45.98,0.116,0.255,503
|
||||
CZCE,CY504,棉纱4月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,21015.0,21015.0,21015.0,0,1,4.02,4.02,0.01,17862.75,17862.75,105075.0,25.0,16.97,41.97,0.095,0.235,20.98,45.98,0.117,0.257,504
|
||||
CZCE,CY505,棉纱5月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,21050.0,21025.0,21070.0,5,76,4.02,4.02,0.01,17909.5,17909.5,105350.0,25.0,16.97,41.97,0.095,0.234,20.98,45.98,0.117,0.257,505
|
||||
CZCE,CY506,棉纱6月,CY,棉纱,5,5.0,0.0,4.01,0.0,4.01,0.0,0.0,0.17,0,0.17,0,21185.0,21185.0,21185.0,0,0,4.02,4.02,0.01,18007.25,18007.25,105925.0,25.0,16.97,41.97,0.094,0.233,20.98,45.98,0.116,0.255,506
|
||||
CZCE,FG407,玻璃7月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.25,0,0.25,0,1353.0,1351.0,1351.0,0,981,6.01,6.01,6.01,6755.0,6755.0,27020.0,20.0,7.98,27.98,0.118,0.414,7.98,27.98,0.118,0.414,407
|
||||
CZCE,FG408,玻璃8月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1463.0,1454.0,1467.0,70,5250,6.01,6.01,6.01,4987.8,4987.8,29340.0,20.0,7.98,27.98,0.16,0.561,7.98,27.98,0.16,0.561,408
|
||||
CZCE,FG409,玻璃9月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1477.0,1464.0,1474.0,149466,697642,6.01,6.01,6.01,5011.6,5011.6,29480.0,20.0,7.98,27.98,0.159,0.558,7.98,27.98,0.159,0.558,409
|
||||
CZCE,FG410,玻璃10月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1508.0,1507.0,1515.0,427,6538,6.01,6.01,6.01,5151.0,5151.0,30300.0,20.0,7.98,27.98,0.155,0.543,7.98,27.98,0.155,0.543,410
|
||||
CZCE,FG411,玻璃11月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1505.0,1502.0,1515.0,111,4510,6.01,6.01,6.01,5151.0,5151.0,30300.0,20.0,7.98,27.98,0.155,0.543,7.98,27.98,0.155,0.543,411
|
||||
CZCE,FG412,玻璃12月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1516.0,1510.0,1521.0,68,8375,6.01,6.01,6.01,5171.4,5171.4,30420.0,20.0,7.98,27.98,0.154,0.541,7.98,27.98,0.154,0.541,412
|
||||
CZCE,FG501,玻璃1月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1505.0,1490.0,1497.0,9884,229236,6.01,6.01,6.01,5089.8,5089.8,29940.0,20.0,7.98,27.98,0.157,0.55,7.98,27.98,0.157,0.55,501
|
||||
CZCE,FG502,玻璃2月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1534.0,1516.0,1526.0,72,10162,6.01,6.01,6.01,5188.4,5188.4,30520.0,20.0,7.98,27.98,0.154,0.539,7.98,27.98,0.154,0.539,502
|
||||
CZCE,FG503,玻璃3月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1530.0,1515.0,1526.0,32,10178,6.01,6.01,6.01,5188.4,5188.4,30520.0,20.0,7.98,27.98,0.154,0.539,7.98,27.98,0.154,0.539,503
|
||||
CZCE,FG504,玻璃4月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1558.0,1540.0,1550.0,17,5469,6.01,6.01,6.01,5270.0,5270.0,31000.0,20.0,7.98,27.98,0.151,0.531,7.98,27.98,0.151,0.531,504
|
||||
CZCE,FG505,玻璃5月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1546.0,1535.0,1543.0,158,12183,6.01,6.01,6.01,5246.2,5246.2,30860.0,20.0,7.98,27.98,0.152,0.533,7.98,27.98,0.152,0.533,505
|
||||
CZCE,FG506,玻璃6月,FG,玻璃,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.17,0,0.17,0,1571.0,1562.0,1567.0,9,108,6.01,6.01,6.01,5327.8,5327.8,31340.0,20.0,7.98,27.98,0.15,0.525,7.98,27.98,0.15,0.525,506
|
||||
CFFEX,IC2407,中证500期货2407,IC,中证500指数,200,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,4838.2,4831.4,0.0,0,73064,22.29,22.29,222.31,144942.0,144942.0,966280.0,40.0,-4.58,35.42,-0.003,0.024,-204.6,-164.6,-0.141,-0.114,2407
|
||||
CFFEX,IC2408,中证500期货2408,IC,中证500指数,200,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,4812.8,4806.4,0.0,0,9915,22.18,22.18,221.16,144192.0,144192.0,961280.0,40.0,-4.35,35.65,-0.003,0.025,-203.34,-163.34,-0.141,-0.113,2408
|
||||
CFFEX,IC2409,中证500期货2409,IC,中证500指数,200,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,4791.2,4785.0,0.0,0,97149,22.08,22.08,220.18,143550.0,143550.0,957000.0,40.0,-4.16,35.84,-0.003,0.025,-202.26,-162.26,-0.141,-0.113,2409
|
||||
CFFEX,IC2412,中证500期货2412,IC,中证500指数,200,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,4746.2,4740.8,0.0,0,65446,21.87,21.87,218.14,142224.0,142224.0,948160.0,40.0,-3.75,36.25,-0.003,0.025,-200.02,-160.02,-0.141,-0.113,2412
|
||||
CFFEX,IF2407,股指2407,IF,沪深300指数,300,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,3413.8,3412.4,0.0,0,75866,23.62,23.62,235.53,153558.0,153558.0,1023720.0,60.0,12.77,72.77,0.008,0.047,-199.14,-139.14,-0.13,-0.091,2407
|
||||
CFFEX,IF2408,股指2408,IF,沪深300指数,300,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,3402.0,3401.4,0.0,0,7424,23.54,23.54,234.77,153063.0,153063.0,1020420.0,60.0,12.92,72.92,0.008,0.048,-198.31,-138.31,-0.13,-0.09,2408
|
||||
CFFEX,IF2409,股指2409,IF,沪深300指数,300,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,3397.8,3396.2,0.0,0,106387,23.5,23.5,234.41,152829.0,152829.0,1018860.0,60.0,12.99,72.99,0.008,0.048,-197.91,-137.91,-0.13,-0.09,2409
|
||||
CFFEX,IF2412,股指2412,IF,沪深300指数,300,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,3395.4,3394.4,0.0,0,42931,23.49,23.49,234.28,152748.0,152748.0,1018320.0,60.0,13.02,73.02,0.009,0.048,-197.78,-137.78,-0.129,-0.09,2412
|
||||
CFFEX,IH2407,上证50期货2407,IH,上证50指数,300,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,2364.4,2364.4,0.0,0,36666,16.37,16.37,163.2,106398.0,106398.0,709320.0,60.0,27.27,87.27,0.026,0.082,-119.56,-59.56,-0.112,-0.056,2407
|
||||
CFFEX,IH2408,上证50期货2408,IH,上证50指数,300,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,2358.4,2357.6,0.0,0,5019,16.32,16.32,162.73,106092.0,106092.0,707280.0,60.0,27.36,87.36,0.026,0.082,-119.05,-59.05,-0.112,-0.056,2408
|
||||
CFFEX,IH2409,上证50期货2409,IH,上证50指数,300,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,2358.2,2357.0,0.0,0,48213,16.32,16.32,162.69,106065.0,106065.0,707100.0,60.0,27.37,87.37,0.026,0.082,-119.0,-59.0,-0.112,-0.056,2409
|
||||
CFFEX,IH2412,上证50期货2412,IH,上证50指数,300,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,2362.2,2361.6,0.0,0,13680,16.35,16.35,163.0,106272.0,106272.0,708480.0,60.0,27.3,87.3,0.026,0.082,-119.35,-59.35,-0.112,-0.056,2412
|
||||
CFFEX,IM2407,中证1000股指期货2407,IM,中证1000指数,200,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,4764.8,4758.0,0.0,0,90954,21.95,21.95,218.94,142740.0,142740.0,951600.0,40.0,-3.91,36.09,-0.003,0.025,-200.89,-160.89,-0.141,-0.113,2407
|
||||
CFFEX,IM2408,中证1000股指期货2408,IM,中证1000指数,200,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,4722.0,4718.2,0.0,0,12870,21.77,21.77,217.1,141546.0,141546.0,943640.0,40.0,-3.54,36.46,-0.003,0.026,-198.87,-158.87,-0.141,-0.112,2408
|
||||
CFFEX,IM2409,中证1000股指期货2409,IM,中证1000指数,200,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,4682.2,4675.0,0.0,0,103557,21.57,21.57,215.12,140250.0,140250.0,935000.0,40.0,-3.14,36.86,-0.002,0.026,-196.69,-156.69,-0.14,-0.112,2409
|
||||
CFFEX,IM2412,中证1000股指期货2412,IM,中证1000指数,200,0.2,2.3e-05,0.01,2.3e-05,0.01,0.00023,0.01,0.15,0,0.15,0,4593.2,4585.0,0.0,0,63896,21.16,21.16,210.98,137550.0,137550.0,917000.0,40.0,-2.31,37.69,-0.002,0.027,-192.13,-152.13,-0.14,-0.111,2412
|
||||
CZCE,JR407,粳稻7月,JR,粳稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.3,0,0.3,0,2662.0,2662.0,2662.0,0,0,3.01,3.01,3.01,15972.0,15972.0,53240.0,20.0,13.97,33.97,0.087,0.213,13.97,33.97,0.087,0.213,407
|
||||
CZCE,JR409,粳稻9月,JR,粳稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2662.0,2662.0,2662.0,0,0,3.01,3.01,3.01,13310.0,13310.0,53240.0,20.0,13.97,33.97,0.105,0.255,13.97,33.97,0.105,0.255,409
|
||||
CZCE,JR411,粳稻11月,JR,粳稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2662.0,2662.0,2662.0,0,0,3.01,3.01,3.01,13310.0,13310.0,53240.0,20.0,13.97,33.97,0.105,0.255,13.97,33.97,0.105,0.255,411
|
||||
CZCE,JR501,粳稻1月,JR,粳稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2662.0,2662.0,2662.0,0,0,3.01,3.01,3.01,13310.0,13310.0,53240.0,20.0,13.97,33.97,0.105,0.255,13.97,33.97,0.105,0.255,501
|
||||
CZCE,JR503,粳稻3月,JR,粳稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2662.0,2662.0,2662.0,0,0,3.01,3.01,3.01,13310.0,13310.0,53240.0,20.0,13.97,33.97,0.105,0.255,13.97,33.97,0.105,0.255,503
|
||||
CZCE,JR505,粳稻5月,JR,粳稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2662.0,2662.0,2662.0,0,0,3.01,3.01,3.01,13310.0,13310.0,53240.0,20.0,13.97,33.97,0.105,0.255,13.97,33.97,0.105,0.255,505
|
||||
CZCE,LR407,晚籼7月,LR,晚籼稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.3,0,0.3,0,2360.0,2360.0,2360.0,0,0,3.01,3.01,3.01,14160.0,14160.0,47200.0,20.0,13.97,33.97,0.099,0.24,13.97,33.97,0.099,0.24,407
|
||||
CZCE,LR409,晚籼9月,LR,晚籼稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2360.0,2360.0,2360.0,0,0,3.01,3.01,3.01,11800.0,11800.0,47200.0,20.0,13.97,33.97,0.118,0.288,13.97,33.97,0.118,0.288,409
|
||||
CZCE,LR411,晚籼11月,LR,晚籼稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2360.0,2360.0,2360.0,0,0,3.01,3.01,3.01,11800.0,11800.0,47200.0,20.0,13.97,33.97,0.118,0.288,13.97,33.97,0.118,0.288,411
|
||||
CZCE,LR501,晚籼1月,LR,晚籼稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2360.0,2360.0,2360.0,0,0,3.01,3.01,3.01,11800.0,11800.0,47200.0,20.0,13.97,33.97,0.118,0.288,13.97,33.97,0.118,0.288,501
|
||||
CZCE,LR503,晚籼3月,LR,晚籼稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2360.0,2360.0,2360.0,0,0,3.01,3.01,3.01,11800.0,11800.0,47200.0,20.0,13.97,33.97,0.118,0.288,13.97,33.97,0.118,0.288,503
|
||||
CZCE,LR505,晚籼5月,LR,晚籼稻,20,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,2360.0,2360.0,2360.0,0,0,3.01,3.01,3.01,11800.0,11800.0,47200.0,20.0,13.97,33.97,0.118,0.288,13.97,33.97,0.118,0.288,505
|
||||
CZCE,MA407,甲醇7月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.26,0,0.26,0,2497.0,2497.0,2515.0,2,1654,2.53,2.53,2.53,6539.0,6539.0,25150.0,10.0,4.95,14.95,0.076,0.229,4.95,14.95,0.076,0.229,407
|
||||
CZCE,MA408,甲醇8月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2507.0,2503.0,2539.0,1410,7341,2.55,2.55,2.55,3554.6,3554.6,25390.0,10.0,4.9,14.9,0.138,0.419,4.9,14.9,0.138,0.419,408
|
||||
CZCE,MA409,甲醇9月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2538.0,2537.0,2567.0,361891,752071,2.58,2.58,2.58,3593.8,3593.8,25670.0,10.0,4.84,14.84,0.135,0.413,4.84,14.84,0.135,0.413,409
|
||||
CZCE,MA410,甲醇10月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2568.0,2569.0,2597.0,3922,7204,2.61,2.61,2.61,3635.8,3635.8,25970.0,10.0,4.78,14.78,0.132,0.407,4.78,14.78,0.132,0.407,410
|
||||
CZCE,MA411,甲醇11月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2580.0,2581.0,2609.0,161,6437,2.62,2.62,2.62,3652.6,3652.6,26090.0,10.0,4.76,14.76,0.13,0.404,4.76,14.76,0.13,0.404,411
|
||||
CZCE,MA412,甲醇12月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2608.0,2608.0,2635.0,84,2808,2.65,2.65,2.65,3689.0,3689.0,26350.0,10.0,4.71,14.71,0.128,0.399,4.71,14.71,0.128,0.399,412
|
||||
CZCE,MA501,甲醇1月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2619.0,2615.0,2644.0,33498,209746,2.66,2.66,2.66,3701.6,3701.6,26440.0,10.0,4.69,14.69,0.127,0.397,4.69,14.69,0.127,0.397,501
|
||||
CZCE,MA502,甲醇2月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2589.0,2586.0,2613.0,208,6134,2.62,2.62,2.62,3658.2,3658.2,26130.0,10.0,4.75,14.75,0.13,0.403,4.75,14.75,0.13,0.403,502
|
||||
CZCE,MA503,甲醇3月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2569.0,2565.0,2591.0,9,2138,2.6,2.6,2.6,3627.4,3627.4,25910.0,10.0,4.79,14.79,0.132,0.408,4.79,14.79,0.132,0.408,503
|
||||
CZCE,MA504,甲醇4月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2550.0,2548.0,2574.0,5,726,2.59,2.59,2.59,3603.6,3603.6,25740.0,10.0,4.83,14.83,0.134,0.412,4.83,14.83,0.134,0.412,504
|
||||
CZCE,MA505,甲醇5月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2511.0,2510.0,2536.0,523,6134,2.55,2.55,2.55,3550.4,3550.4,25360.0,10.0,4.9,14.9,0.138,0.42,4.9,14.9,0.138,0.42,505
|
||||
CZCE,MA506,甲醇6月,MA,甲醇N,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,2522.0,2510.0,2541.0,6,38,2.55,2.55,2.55,3557.4,3557.4,25410.0,10.0,4.89,14.89,0.138,0.419,4.89,14.89,0.138,0.419,506
|
||||
CZCE,OI407,菜油7月,OI,菜籽油,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.26,0,0.26,0,8275.0,8275.0,8275.0,0,2859,2.01,2.01,2.01,21515.0,21515.0,82750.0,10.0,5.97,15.97,0.028,0.074,5.97,15.97,0.028,0.074,407
|
||||
CZCE,OI409,菜油9月,OI,菜籽油,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.13,0,0.13,0,8377.0,8305.0,8316.0,187254,287680,2.01,2.01,2.01,10810.8,10810.8,83160.0,10.0,5.97,15.97,0.055,0.148,5.97,15.97,0.055,0.148,409
|
||||
CZCE,OI411,菜油11月,OI,菜籽油,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.13,0,0.13,0,8445.0,8382.0,8392.0,5108,29406,2.02,2.02,2.02,10909.6,10909.6,83920.0,10.0,5.97,15.97,0.055,0.146,5.97,15.97,0.055,0.146,411
|
||||
CZCE,OI501,菜油1月,OI,菜籽油,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.13,0,0.13,0,8493.0,8437.0,8451.0,28089,120009,2.02,2.02,2.02,10986.3,10986.3,84510.0,10.0,5.97,15.97,0.054,0.145,5.97,15.97,0.054,0.145,501
|
||||
CZCE,OI503,菜油3月,OI,菜籽油,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.13,0,0.13,0,8537.0,8475.0,8486.0,143,4141,2.02,2.02,2.02,11031.8,11031.8,84860.0,10.0,5.97,15.97,0.054,0.145,5.97,15.97,0.054,0.145,503
|
||||
CZCE,OI505,菜油5月,OI,菜籽油,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.13,0,0.13,0,8566.0,8511.0,8524.0,1822,18830,2.02,2.02,2.02,11081.2,11081.2,85240.0,10.0,5.97,15.97,0.054,0.144,5.97,15.97,0.054,0.144,505
|
||||
CZCE,PF407,短纤7月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.26,0,0.26,0,7544.0,7536.0,7536.0,0,2504,3.01,3.01,3.01,9796.8,9796.8,37680.0,10.0,3.98,13.98,0.041,0.143,3.98,13.98,0.041,0.143,407
|
||||
CZCE,PF408,短纤8月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7576.0,7564.0,7594.0,3491,36888,3.01,3.01,3.01,5315.8,5315.8,37970.0,10.0,3.98,13.98,0.075,0.263,3.98,13.98,0.075,0.263,408
|
||||
CZCE,PF409,短纤9月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7572.0,7560.0,7584.0,26457,140577,3.01,3.01,3.01,5308.8,5308.8,37920.0,10.0,3.98,13.98,0.075,0.263,3.98,13.98,0.075,0.263,409
|
||||
CZCE,PF410,短纤10月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7616.0,7604.0,7624.0,18345,122162,3.01,3.01,3.01,5336.8,5336.8,38120.0,10.0,3.98,13.98,0.074,0.262,3.98,13.98,0.074,0.262,410
|
||||
CZCE,PF411,短纤11月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7586.0,7578.0,7592.0,12772,33969,3.01,3.01,3.01,5314.4,5314.4,37960.0,10.0,3.98,13.98,0.075,0.263,3.98,13.98,0.075,0.263,411
|
||||
CZCE,PF412,短纤12月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7566.0,7556.0,7556.0,0,46,3.01,3.01,3.01,5289.2,5289.2,37780.0,10.0,3.98,13.98,0.075,0.264,3.98,13.98,0.075,0.264,412
|
||||
CZCE,PF501,短纤1月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7550.0,7536.0,7566.0,4,392,3.01,3.01,3.01,5296.2,5296.2,37830.0,10.0,3.98,13.98,0.075,0.264,3.98,13.98,0.075,0.264,501
|
||||
CZCE,PF502,短纤2月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7594.0,7588.0,7594.0,2,11,3.01,3.01,3.01,5315.8,5315.8,37970.0,10.0,3.98,13.98,0.075,0.263,3.98,13.98,0.075,0.263,502
|
||||
CZCE,PF503,短纤3月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7574.0,7574.0,7586.0,2,14,3.01,3.01,3.01,5310.2,5310.2,37930.0,10.0,3.98,13.98,0.075,0.263,3.98,13.98,0.075,0.263,503
|
||||
CZCE,PF504,短纤4月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7568.0,7568.0,7576.0,2,8,3.01,3.01,3.01,5303.2,5303.2,37880.0,10.0,3.98,13.98,0.075,0.264,3.98,13.98,0.075,0.264,504
|
||||
CZCE,PF505,短纤5月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7552.0,7544.0,7574.0,2,24,3.01,3.01,3.01,5301.8,5301.8,37870.0,10.0,3.98,13.98,0.075,0.264,3.98,13.98,0.075,0.264,505
|
||||
CZCE,PF506,短纤6月,PF,短纤,5,2.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,7628.0,7628.0,7628.0,0,9,3.01,3.01,3.01,5339.6,5339.6,38140.0,10.0,3.98,13.98,0.074,0.262,3.98,13.98,0.074,0.262,506
|
||||
CZCE,PK410,花生10月,PK,花生仁,5,2.0,0.0,4.01,0.0,4.01,0.0,4.01,0.14,0,0.14,0,8676.0,8670.0,8670.0,0,133417,4.01,4.01,4.01,6069.0,6069.0,43350.0,10.0,1.97,11.97,0.033,0.197,1.97,11.97,0.033,0.197,410
|
||||
CZCE,PK411,花生11月,PK,花生仁,5,2.0,0.0,4.01,0.0,4.01,0.0,4.01,0.14,0,0.14,0,8534.0,8538.0,8538.0,0,62683,4.01,4.01,4.01,5976.6,5976.6,42690.0,10.0,1.97,11.97,0.033,0.2,1.97,11.97,0.033,0.2,411
|
||||
CZCE,PK412,花生12月,PK,花生仁,5,2.0,0.0,4.01,0.0,4.01,0.0,4.01,0.14,0,0.14,0,8554.0,8570.0,8570.0,0,653,4.01,4.01,4.01,5999.0,5999.0,42850.0,10.0,1.97,11.97,0.033,0.2,1.97,11.97,0.033,0.2,412
|
||||
CZCE,PK501,花生1月,PK,花生仁,5,2.0,0.0,4.01,0.0,4.01,0.0,4.01,0.14,0,0.14,0,8570.0,8564.0,8564.0,0,10324,4.01,4.01,4.01,5994.8,5994.8,42820.0,10.0,1.97,11.97,0.033,0.2,1.97,11.97,0.033,0.2,501
|
||||
CZCE,PK503,花生3月,PK,花生仁,5,2.0,0.0,4.01,0.0,4.01,0.0,4.01,0.14,0,0.14,0,8662.0,8660.0,8660.0,0,717,4.01,4.01,4.01,6062.0,6062.0,43300.0,10.0,1.97,11.97,0.033,0.198,1.97,11.97,0.033,0.198,503
|
||||
CZCE,PK504,花生4月,PK,花生仁,5,2.0,0.0,4.01,0.0,4.01,0.0,4.01,0.14,0,0.14,0,8668.0,8666.0,8666.0,0,853,4.01,4.01,4.01,6066.2,6066.2,43330.0,10.0,1.97,11.97,0.033,0.197,1.97,11.97,0.033,0.197,504
|
||||
CZCE,PK505,花生5月,PK,花生仁,5,2.0,0.0,4.01,0.0,4.01,0.0,4.01,0.14,0,0.14,0,8680.0,8666.0,8666.0,0,330,4.01,4.01,4.01,6066.2,6066.2,43330.0,10.0,1.97,11.97,0.033,0.197,1.97,11.97,0.033,0.197,505
|
||||
CZCE,PM407,普麦7月,PM,普通小麦,50,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.45,0,0.45,0,3122.0,3122.0,3122.0,0,0,30.02,30.02,30.02,70245.0,70245.0,156100.0,50.0,-10.04,39.96,-0.014,0.057,-10.04,39.96,-0.014,0.057,407
|
||||
CZCE,PM409,普麦9月,PM,普通小麦,50,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3122.0,3122.0,3122.0,0,0,30.02,30.02,30.02,62440.0,62440.0,156100.0,50.0,-10.04,39.96,-0.016,0.064,-10.04,39.96,-0.016,0.064,409
|
||||
CZCE,PM411,普麦11月,PM,普通小麦,50,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3122.0,3122.0,3122.0,0,0,30.02,30.02,30.02,62440.0,62440.0,156100.0,50.0,-10.04,39.96,-0.016,0.064,-10.04,39.96,-0.016,0.064,411
|
||||
CZCE,PM501,普麦1月,PM,普通小麦,50,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3122.0,3122.0,3122.0,0,0,30.02,30.02,30.02,62440.0,62440.0,156100.0,50.0,-10.04,39.96,-0.016,0.064,-10.04,39.96,-0.016,0.064,501
|
||||
CZCE,PM503,普麦3月,PM,普通小麦,50,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3122.0,3122.0,3122.0,0,0,30.02,30.02,30.02,62440.0,62440.0,156100.0,50.0,-10.04,39.96,-0.016,0.064,-10.04,39.96,-0.016,0.064,503
|
||||
CZCE,PM505,普麦5月,PM,普通小麦,50,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3122.0,3122.0,3122.0,0,0,30.02,30.02,30.02,62440.0,62440.0,156100.0,50.0,-10.04,39.96,-0.016,0.064,-10.04,39.96,-0.016,0.064,505
|
||||
CZCE,PX407,对二甲苯7月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.26,0,0.26,0,7674.0,7674.0,7674.0,0,0,3.85,3.85,0.0,9976.2,9976.2,38370.0,10.0,2.3,12.3,0.023,0.123,6.15,16.15,0.062,0.162,407
|
||||
CZCE,PX408,对二甲苯8月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,8546.0,8546.0,8546.0,0,21,4.29,4.29,0.0,6836.8,6836.8,42730.0,10.0,1.43,11.43,0.021,0.167,5.71,15.71,0.084,0.23,408
|
||||
CZCE,PX409,对二甲苯9月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8500.0,8482.0,8510.0,9610,73567,4.27,4.27,0.0,5957.0,5957.0,42550.0,10.0,1.46,11.46,0.025,0.192,5.73,15.73,0.096,0.264,409
|
||||
CZCE,PX410,对二甲苯10月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8520.0,8506.0,8530.0,1044,31273,4.28,4.28,0.0,5971.0,5971.0,42650.0,10.0,1.44,11.44,0.024,0.192,5.72,15.72,0.096,0.263,410
|
||||
CZCE,PX411,对二甲苯11月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8532.0,8532.0,8532.0,0,1,4.28,4.28,0.0,5972.4,5972.4,42660.0,10.0,1.44,11.44,0.024,0.192,5.72,15.72,0.096,0.263,411
|
||||
CZCE,PX412,对二甲苯12月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8540.0,8540.0,8540.0,0,6,4.28,4.28,0.0,5978.0,5978.0,42700.0,10.0,1.43,11.43,0.024,0.191,5.71,15.71,0.096,0.263,412
|
||||
CZCE,PX501,对二甲苯1月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8508.0,8488.0,8516.0,351,27433,4.27,4.27,0.0,5961.2,5961.2,42580.0,10.0,1.46,11.46,0.024,0.192,5.73,15.73,0.096,0.264,501
|
||||
CZCE,PX502,对二甲苯2月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8540.0,8540.0,8540.0,0,4,4.28,4.28,0.0,5978.0,5978.0,42700.0,10.0,1.43,11.43,0.024,0.191,5.71,15.71,0.096,0.263,502
|
||||
CZCE,PX503,对二甲苯3月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8582.0,8582.0,8582.0,0,3,4.3,4.3,0.0,6007.4,6007.4,42910.0,10.0,1.39,11.39,0.023,0.19,5.69,15.69,0.095,0.261,503
|
||||
CZCE,PX504,对二甲苯4月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8548.0,8548.0,8548.0,0,2,4.29,4.29,0.0,5983.6,5983.6,42740.0,10.0,1.43,11.43,0.024,0.191,5.71,15.71,0.095,0.263,504
|
||||
CZCE,PX505,对二甲苯5月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8518.0,8510.0,8530.0,1,47,4.28,4.28,0.0,5971.0,5971.0,42650.0,10.0,1.44,11.44,0.024,0.192,5.72,15.72,0.096,0.263,505
|
||||
CZCE,PX506,对二甲苯6月,PX,对二甲苯,5,2.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,8540.0,8540.0,8540.0,0,3,4.28,4.28,0.0,5978.0,5978.0,42700.0,10.0,1.43,11.43,0.024,0.191,5.71,15.71,0.096,0.263,506
|
||||
CZCE,RI407,早籼7月,RI,早籼稻,20,1.0,0.0,2.51,0.0,2.51,0.0,2.51,0.3,0,0.3,0,2479.0,2479.0,2479.0,0,0,2.51,2.51,2.51,14874.0,14874.0,49580.0,20.0,14.97,34.97,0.101,0.235,14.97,34.97,0.101,0.235,407
|
||||
CZCE,RI409,早籼9月,RI,早籼稻,20,1.0,0.0,2.51,0.0,2.51,0.0,2.51,0.25,0,0.25,0,2479.0,2479.0,2479.0,0,0,2.51,2.51,2.51,12395.0,12395.0,49580.0,20.0,14.97,34.97,0.121,0.282,14.97,34.97,0.121,0.282,409
|
||||
CZCE,RI411,早籼11月,RI,早籼稻,20,1.0,0.0,2.51,0.0,2.51,0.0,2.51,0.25,0,0.25,0,2479.0,2479.0,2479.0,0,0,2.51,2.51,2.51,12395.0,12395.0,49580.0,20.0,14.97,34.97,0.121,0.282,14.97,34.97,0.121,0.282,411
|
||||
CZCE,RI501,早籼1月,RI,早籼稻,20,1.0,0.0,2.51,0.0,2.51,0.0,2.51,0.25,0,0.25,0,2479.0,2479.0,2479.0,0,0,2.51,2.51,2.51,12395.0,12395.0,49580.0,20.0,14.97,34.97,0.121,0.282,14.97,34.97,0.121,0.282,501
|
||||
CZCE,RI503,早籼3月,RI,早籼稻,20,1.0,0.0,2.51,0.0,2.51,0.0,2.51,0.25,0,0.25,0,2479.0,2479.0,2479.0,0,0,2.51,2.51,2.51,12395.0,12395.0,49580.0,20.0,14.97,34.97,0.121,0.282,14.97,34.97,0.121,0.282,503
|
||||
CZCE,RI505,早籼5月,RI,早籼稻,20,1.0,0.0,2.51,0.0,2.51,0.0,2.51,0.25,0,0.25,0,2479.0,2479.0,2479.0,0,0,2.51,2.51,2.51,12395.0,12395.0,49580.0,20.0,14.97,34.97,0.121,0.282,14.97,34.97,0.121,0.282,505
|
||||
CZCE,RM407,菜粕7月,RM,菜籽粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.26,0,0.26,0,2420.0,2401.0,2401.0,0,940,1.51,1.51,1.51,6242.6,6242.6,24010.0,10.0,6.98,16.98,0.112,0.272,6.98,16.98,0.112,0.272,407
|
||||
CZCE,RM408,菜粕8月,RM,菜籽粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,2511.0,2497.0,2495.0,958,16376,1.51,1.51,1.51,3243.5,3243.5,24950.0,10.0,6.98,16.98,0.215,0.523,6.98,16.98,0.215,0.523,408
|
||||
CZCE,RM409,菜粕9月,RM,菜籽粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,2520.0,2514.0,2512.0,240835,1012764,1.51,1.51,1.51,3265.6,3265.6,25120.0,10.0,6.98,16.98,0.214,0.52,6.98,16.98,0.214,0.52,409
|
||||
CZCE,RM411,菜粕11月,RM,菜籽粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,2453.0,2444.0,2449.0,18761,137511,1.51,1.51,1.51,3183.7,3183.7,24490.0,10.0,6.98,16.98,0.219,0.533,6.98,16.98,0.219,0.533,411
|
||||
CZCE,RM501,菜粕1月,RM,菜籽粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,2505.0,2500.0,2499.0,58240,450609,1.51,1.51,1.51,3248.7,3248.7,24990.0,10.0,6.98,16.98,0.215,0.523,6.98,16.98,0.215,0.523,501
|
||||
CZCE,RM503,菜粕3月,RM,菜籽粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,2492.0,2492.0,2500.0,2778,11743,1.51,1.51,1.51,3250.0,3250.0,25000.0,10.0,6.98,16.98,0.215,0.522,6.98,16.98,0.215,0.522,503
|
||||
CZCE,RM505,菜粕5月,RM,菜籽粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,2550.0,2537.0,2547.0,1695,36855,1.51,1.51,1.51,3311.1,3311.1,25470.0,10.0,6.98,16.98,0.211,0.513,6.98,16.98,0.211,0.513,505
|
||||
CZCE,RS407,菜籽7月,RS,油菜籽,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.4,0,0.4,0,4886.0,4886.0,4886.0,0,5,2.01,2.01,2.01,19544.0,19544.0,48860.0,10.0,5.97,15.97,0.031,0.082,5.97,15.97,0.031,0.082,407
|
||||
CZCE,RS408,菜籽8月,RS,油菜籽,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.4,0,0.4,0,5015.0,5015.0,5015.0,0,7,2.01,2.01,2.01,20060.0,20060.0,50150.0,10.0,5.97,15.97,0.03,0.08,5.97,15.97,0.03,0.08,408
|
||||
CZCE,RS409,菜籽9月,RS,油菜籽,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.4,0,0.4,0,5086.0,5051.0,5051.0,0,19,2.01,2.01,2.01,20204.0,20204.0,50510.0,10.0,5.97,15.97,0.03,0.079,5.97,15.97,0.03,0.079,409
|
||||
CZCE,RS411,菜籽11月,RS,油菜籽,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.4,0,0.4,0,5216.0,5146.0,5146.0,0,155,2.01,2.01,2.01,20584.0,20584.0,51460.0,10.0,5.97,15.97,0.029,0.078,5.97,15.97,0.029,0.078,411
|
||||
CZCE,SA407,纯碱7月,SA,纯碱,20,1.0,0.0004,0.01,0.0004,0.01,0.0004,0.01,0.25,0,0.25,0,1933.0,1901.0,1870.0,55,2698,14.97,14.97,14.97,9350.0,9350.0,37400.0,20.0,-9.94,10.06,-0.106,0.108,-9.94,10.06,-0.106,0.108,407
|
||||
CZCE,SA408,纯碱8月,SA,纯碱,20,1.0,0.0004,0.01,0.0004,0.01,0.0004,0.01,0.17,0,0.17,0,1980.0,1938.0,1941.0,1861,23066,15.54,15.54,15.54,6599.4,6599.4,38820.0,20.0,-11.08,8.92,-0.168,0.135,-11.08,8.92,-0.168,0.135,408
|
||||
CZCE,SA409,纯碱9月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,2003.0,1952.0,1954.0,285964,819230,7.83,7.83,7.83,6643.6,6643.6,39080.0,20.0,4.34,24.34,0.065,0.366,4.34,24.34,0.065,0.366,409
|
||||
CZCE,SA410,纯碱10月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,2010.0,1967.0,1970.0,672,10089,7.89,7.89,7.89,6698.0,6698.0,39400.0,20.0,4.22,24.22,0.063,0.362,4.22,24.22,0.063,0.362,410
|
||||
CZCE,SA411,纯碱11月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,1987.0,1942.0,1955.0,367,9577,7.83,7.83,7.83,6647.0,6647.0,39100.0,20.0,4.34,24.34,0.065,0.366,4.34,24.34,0.065,0.366,411
|
||||
CZCE,SA412,纯碱12月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,1979.0,1941.0,1948.0,194,8634,7.8,7.8,7.8,6623.2,6623.2,38960.0,20.0,4.39,24.39,0.066,0.368,4.39,24.39,0.066,0.368,412
|
||||
CZCE,SA501,纯碱1月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,1960.0,1920.0,1931.0,20526,306756,7.74,7.74,7.74,6565.4,6565.4,38620.0,20.0,4.53,24.53,0.069,0.374,4.53,24.53,0.069,0.374,501
|
||||
CZCE,SA502,纯碱2月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,1968.0,1940.0,1952.0,31,8115,7.82,7.82,7.82,6636.8,6636.8,39040.0,20.0,4.36,24.36,0.066,0.367,4.36,24.36,0.066,0.367,502
|
||||
CZCE,SA503,纯碱3月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,1954.0,1928.0,1939.0,72,9221,7.77,7.77,7.77,6592.6,6592.6,38780.0,20.0,4.46,24.46,0.068,0.371,4.46,24.46,0.068,0.371,503
|
||||
CZCE,SA504,纯碱4月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,1980.0,1961.0,1961.0,38,5061,7.86,7.86,7.86,6667.4,6667.4,39220.0,20.0,4.29,24.29,0.064,0.364,4.29,24.29,0.064,0.364,504
|
||||
CZCE,SA505,纯碱5月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,1962.0,1927.0,1938.0,1281,19899,7.76,7.76,7.76,6589.2,6589.2,38760.0,20.0,4.47,24.47,0.068,0.371,4.47,24.47,0.068,0.371,505
|
||||
CZCE,SA506,纯碱6月,SA,纯碱,20,1.0,0.0002,0.01,0.0002,0.01,0.0002,0.01,0.17,0,0.17,0,1973.0,1962.0,1961.0,23,560,7.86,7.86,7.86,6667.4,6667.4,39220.0,20.0,4.29,24.29,0.064,0.364,4.29,24.29,0.064,0.364,506
|
||||
CZCE,SF407,硅铁7月,SF,硅铁,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.27,0,0.27,0,6700.0,6686.0,6686.0,0,7775,12.01,12.01,12.01,9026.1,9026.1,33430.0,10.0,-14.02,-4.02,-0.155,-0.045,-14.02,-4.02,-0.155,-0.045,407
|
||||
CZCE,SF408,硅铁8月,SF,硅铁,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.16,0,0.16,0,6672.0,6654.0,6654.0,0,5411,12.01,12.01,12.01,5323.2,5323.2,33270.0,10.0,-14.02,-4.02,-0.263,-0.076,-14.02,-4.02,-0.263,-0.076,408
|
||||
CZCE,SF409,硅铁9月,SF,硅铁,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.16,0,0.16,0,6696.0,6672.0,6672.0,0,163656,12.01,12.01,12.01,5337.6,5337.6,33360.0,10.0,-14.02,-4.02,-0.263,-0.075,-14.02,-4.02,-0.263,-0.075,409
|
||||
CZCE,SF410,硅铁10月,SF,硅铁,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.16,0,0.16,0,6644.0,6632.0,6632.0,0,77803,12.01,12.01,12.01,5305.6,5305.6,33160.0,10.0,-14.02,-4.02,-0.264,-0.076,-14.02,-4.02,-0.264,-0.076,410
|
||||
CZCE,SF411,硅铁11月,SF,硅铁,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.16,0,0.16,0,6802.0,6790.0,6790.0,0,21139,12.01,12.01,12.01,5432.0,5432.0,33950.0,10.0,-14.02,-4.02,-0.258,-0.074,-14.02,-4.02,-0.258,-0.074,411
|
||||
CZCE,SF412,硅铁12月,SF,硅铁,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.16,0,0.16,0,6826.0,6804.0,6804.0,0,1189,12.01,12.01,12.01,5443.2,5443.2,34020.0,10.0,-14.02,-4.02,-0.258,-0.074,-14.02,-4.02,-0.258,-0.074,412
|
||||
CZCE,SF501,硅铁1月,SF,硅铁,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.16,0,0.16,0,6770.0,6758.0,6758.0,0,29304,12.01,12.01,12.01,5406.4,5406.4,33790.0,10.0,-14.02,-4.02,-0.259,-0.074,-14.02,-4.02,-0.259,-0.074,501
|
||||
CZCE,SF502,硅铁2月,SF,硅铁,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,6746.0,6716.0,6716.0,0,981,3.01,3.01,0.0,5372.8,5372.8,33580.0,10.0,3.98,13.98,0.074,0.26,6.99,16.99,0.13,0.316,502
|
||||
CZCE,SF503,硅铁3月,SF,硅铁,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,6866.0,6840.0,6840.0,0,1673,3.01,3.01,0.0,5472.0,5472.0,34200.0,10.0,3.98,13.98,0.073,0.255,6.99,16.99,0.128,0.31,503
|
||||
CZCE,SF504,硅铁4月,SF,硅铁,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,6836.0,6824.0,6824.0,0,266,3.01,3.01,0.0,5459.2,5459.2,34120.0,10.0,3.98,13.98,0.073,0.256,6.99,16.99,0.128,0.311,504
|
||||
CZCE,SF505,硅铁5月,SF,硅铁,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,6828.0,6802.0,6802.0,0,1632,3.01,3.01,0.0,5441.6,5441.6,34010.0,10.0,3.98,13.98,0.073,0.257,6.99,16.99,0.128,0.312,505
|
||||
CZCE,SF506,硅铁6月,SF,硅铁,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,6788.0,6782.0,6782.0,0,77,3.01,3.01,0.0,5425.6,5425.6,33910.0,10.0,3.98,13.98,0.073,0.258,6.99,16.99,0.129,0.313,506
|
||||
CZCE,SH407,烧碱7月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.26,0,0.26,0,2243.0,2243.0,2243.0,0,44,6.74,6.74,0.0,17495.4,17495.4,67290.0,30.0,16.51,46.51,0.094,0.266,23.25,53.25,0.133,0.304,407
|
||||
CZCE,SH408,烧碱8月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2499.0,2504.0,2504.0,0,386,7.53,7.53,0.0,10516.8,10516.8,75120.0,30.0,14.95,44.95,0.142,0.427,22.47,52.47,0.214,0.499,408
|
||||
CZCE,SH409,烧碱9月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2582.0,2574.0,2572.0,13871,56210,7.73,7.73,0.0,10802.4,10802.4,77160.0,30.0,14.54,44.54,0.135,0.412,22.26,52.26,0.206,0.484,409
|
||||
CZCE,SH410,烧碱10月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2658.0,2655.0,2648.0,348,17371,7.96,7.96,0.0,11121.6,11121.6,79440.0,30.0,14.08,44.08,0.127,0.396,22.04,52.04,0.198,0.468,410
|
||||
CZCE,SH411,烧碱11月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2669.0,2654.0,2657.0,4,94,7.99,7.99,0.0,11159.4,11159.4,79710.0,30.0,14.03,44.03,0.126,0.395,22.01,52.01,0.197,0.466,411
|
||||
CZCE,SH412,烧碱12月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2701.0,2704.0,2704.0,0,59,8.13,8.13,0.0,11356.8,11356.8,81120.0,30.0,13.75,43.75,0.121,0.385,21.87,51.87,0.193,0.457,412
|
||||
CZCE,SH501,烧碱1月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2700.0,2698.0,2680.0,1172,13570,8.05,8.05,0.0,11256.0,11256.0,80400.0,30.0,13.89,43.89,0.123,0.39,21.94,51.94,0.195,0.461,501
|
||||
CZCE,SH502,烧碱2月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2736.0,2720.0,2720.0,0,87,8.17,8.17,0.0,11424.0,11424.0,81600.0,30.0,13.65,43.65,0.119,0.382,21.82,51.82,0.191,0.454,502
|
||||
CZCE,SH503,烧碱3月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2756.0,2744.0,2744.0,0,3,8.25,8.25,0.0,11524.8,11524.8,82320.0,30.0,13.51,43.51,0.117,0.378,21.75,51.75,0.189,0.449,503
|
||||
CZCE,SH504,烧碱4月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2765.0,2761.0,2761.0,0,36,8.3,8.3,0.0,11596.2,11596.2,82830.0,30.0,13.4,43.4,0.116,0.374,21.7,51.7,0.187,0.446,504
|
||||
CZCE,SH505,烧碱5月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2782.0,2774.0,2761.0,12,841,8.3,8.3,0.0,11596.2,11596.2,82830.0,30.0,13.4,43.4,0.116,0.374,21.7,51.7,0.187,0.446,505
|
||||
CZCE,SH506,烧碱6月,SH,烧碱,30,1.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.14,0,0.14,0,2804.0,2804.0,2804.0,0,4,8.43,8.43,0.01,11776.8,11776.8,84120.0,30.0,13.15,43.15,0.112,0.366,21.57,51.57,0.183,0.438,506
|
||||
CZCE,SM407,锰硅7月,SM,锰硅,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.27,0,0.27,0,7116.0,7008.0,7008.0,0,27684,12.01,12.01,12.01,9460.8,9460.8,35040.0,10.0,-14.02,-4.02,-0.148,-0.043,-14.02,-4.02,-0.148,-0.043,407
|
||||
CZCE,SM408,锰硅8月,SM,锰硅,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.19,0,0.19,0,7116.0,7056.0,7056.0,0,30052,12.01,12.01,12.01,6703.2,6703.2,35280.0,10.0,-14.02,-4.02,-0.209,-0.06,-14.02,-4.02,-0.209,-0.06,408
|
||||
CZCE,SM409,锰硅9月,SM,锰硅,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.19,0,0.19,0,7192.0,7088.0,7088.0,0,263265,12.01,12.01,12.01,6733.6,6733.6,35440.0,10.0,-14.02,-4.02,-0.208,-0.06,-14.02,-4.02,-0.208,-0.06,409
|
||||
CZCE,SM410,锰硅10月,SM,锰硅,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.19,0,0.19,0,7194.0,7106.0,7106.0,0,8624,12.01,12.01,12.01,6750.7,6750.7,35530.0,10.0,-14.02,-4.02,-0.208,-0.06,-14.02,-4.02,-0.208,-0.06,410
|
||||
CZCE,SM411,锰硅11月,SM,锰硅,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.19,0,0.19,0,7478.0,7322.0,7322.0,0,21941,12.01,12.01,12.01,6955.9,6955.9,36610.0,10.0,-14.02,-4.02,-0.202,-0.058,-14.02,-4.02,-0.202,-0.058,411
|
||||
CZCE,SM412,锰硅12月,SM,锰硅,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.19,0,0.19,0,7408.0,7302.0,7302.0,0,1503,12.01,12.01,12.01,6936.9,6936.9,36510.0,10.0,-14.02,-4.02,-0.202,-0.058,-14.02,-4.02,-0.202,-0.058,412
|
||||
CZCE,SM501,锰硅1月,SM,锰硅,5,2.0,0.0,12.01,0.0,12.01,0.0,12.01,0.19,0,0.19,0,7412.0,7324.0,7324.0,0,279664,12.01,12.01,12.01,6957.8,6957.8,36620.0,10.0,-14.02,-4.02,-0.202,-0.058,-14.02,-4.02,-0.202,-0.058,501
|
||||
CZCE,SM502,锰硅2月,SM,锰硅,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,7318.0,7242.0,7242.0,0,3241,3.01,3.01,0.0,5793.6,5793.6,36210.0,10.0,3.98,13.98,0.069,0.241,6.99,16.99,0.121,0.293,502
|
||||
CZCE,SM503,锰硅3月,SM,锰硅,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,7260.0,7192.0,7192.0,0,5320,3.01,3.01,0.0,5753.6,5753.6,35960.0,10.0,3.98,13.98,0.069,0.243,6.99,16.99,0.121,0.295,503
|
||||
CZCE,SM504,锰硅4月,SM,锰硅,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,7252.0,7158.0,7158.0,0,2875,3.01,3.01,0.0,5726.4,5726.4,35790.0,10.0,3.98,13.98,0.069,0.244,6.99,16.99,0.122,0.297,504
|
||||
CZCE,SM505,锰硅5月,SM,锰硅,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,7238.0,7156.0,7156.0,0,27285,3.01,3.01,0.0,5724.8,5724.8,35780.0,10.0,3.98,13.98,0.069,0.244,6.99,16.99,0.122,0.297,505
|
||||
CZCE,SM506,锰硅6月,SM,锰硅,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.16,0,0.16,0,7220.0,7138.0,7138.0,0,201,3.01,3.01,0.0,5710.4,5710.4,35690.0,10.0,3.98,13.98,0.07,0.245,6.99,16.99,0.122,0.297,506
|
||||
CZCE,SR407,白糖7月,SR,白砂糖,10,1.0,0.0,3.01,0.0,3.01,0.0,0.0,0.25,0,0.25,0,6260.0,6260.0,6260.0,0,3257,3.01,3.01,0.0,15650.0,15650.0,62600.0,10.0,3.97,13.97,0.025,0.089,6.98,16.98,0.045,0.109,407
|
||||
CZCE,SR409,白糖9月,SR,白砂糖,10,1.0,0.0,3.01,0.0,3.01,0.0,0.0,0.12,0,0.12,0,6174.0,6150.0,6197.0,127012,312949,3.01,3.01,0.0,7436.4,7436.4,61970.0,10.0,3.97,13.97,0.053,0.188,6.98,16.98,0.094,0.228,409
|
||||
CZCE,SR411,白糖11月,SR,白砂糖,10,1.0,0.0,3.01,0.0,3.01,0.0,0.0,0.12,0,0.12,0,5996.0,5977.0,6014.0,10993,78694,3.01,3.01,0.0,7216.8,7216.8,60140.0,10.0,3.97,13.97,0.055,0.194,6.98,16.98,0.097,0.235,411
|
||||
CZCE,SR501,白糖1月,SR,白砂糖,10,1.0,0.0,3.01,0.0,3.01,0.0,0.0,0.12,0,0.12,0,5924.0,5908.0,5944.0,15996,135768,3.01,3.01,0.0,7132.8,7132.8,59440.0,10.0,3.97,13.97,0.056,0.196,6.98,16.98,0.098,0.238,501
|
||||
CZCE,SR503,白糖3月,SR,白砂糖,10,1.0,0.0,3.01,0.0,3.01,0.0,0.0,0.12,0,0.12,0,5885.0,5869.0,5908.0,101,4103,3.01,3.01,0.0,7089.6,7089.6,59080.0,10.0,3.97,13.97,0.056,0.197,6.98,16.98,0.098,0.24,503
|
||||
CZCE,SR505,白糖5月,SR,白砂糖,10,1.0,0.0,3.01,0.0,3.01,0.0,0.0,0.12,0,0.12,0,5859.0,5837.0,5869.0,389,8834,3.01,3.01,0.0,7042.8,7042.8,58690.0,10.0,3.97,13.97,0.056,0.198,6.98,16.98,0.099,0.241,505
|
||||
CFFEX,T2409,长期国债2409,T,10年期国债期货,10000,0.005,0.0,3.01,0.0,3.01,0.0,0.0,0.03,0,0.03,0,105.115,105.11,0.0,0,188590,3.07,3.07,0.06,31533.0,31533.0,1051100.0,50.0,43.85,93.85,0.139,0.298,46.86,96.86,0.149,0.307,2409
|
||||
CFFEX,T2412,长期国债2412,T,10年期国债期货,10000,0.005,0.0,3.01,0.0,3.01,0.0,0.0,0.03,0,0.03,0,104.97,104.98,0.0,0,14515,3.07,3.07,0.06,31494.0,31494.0,1049800.0,50.0,43.85,93.85,0.139,0.298,46.86,96.86,0.149,0.308,2412
|
||||
CFFEX,T2503,长期国债2503,T,10年期国债期货,10000,0.005,0.0,3.01,0.0,3.01,0.0,0.0,0.03,0,0.03,0,104.81,104.835,0.0,0,1079,3.07,3.07,0.06,31450.5,31450.5,1048350.0,50.0,43.85,93.85,0.139,0.298,46.86,96.86,0.149,0.308,2503
|
||||
CZCE,TA407,PTA7月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.27,0,0.27,0,5886.0,5894.0,5894.0,0,7979,3.01,3.01,0.0,7956.9,7956.9,29470.0,10.0,3.98,13.98,0.05,0.176,6.99,16.99,0.088,0.213,407
|
||||
CZCE,TA408,PTA8月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5896.0,5886.0,5904.0,5099,18820,3.01,3.01,0.0,4132.8,4132.8,29520.0,10.0,3.98,13.98,0.096,0.338,6.99,16.99,0.169,0.411,408
|
||||
CZCE,TA409,PTA9月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5902.0,5894.0,5908.0,115173,889263,3.01,3.01,0.0,4135.6,4135.6,29540.0,10.0,3.98,13.98,0.096,0.338,6.99,16.99,0.169,0.411,409
|
||||
CZCE,TA410,PTA10月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5918.0,5908.0,5920.0,3229,8494,3.01,3.01,0.0,4144.0,4144.0,29600.0,10.0,3.98,13.98,0.096,0.337,6.99,16.99,0.169,0.41,410
|
||||
CZCE,TA411,PTA11月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5908.0,5898.0,5916.0,3,2345,3.01,3.01,0.0,4141.2,4141.2,29580.0,10.0,3.98,13.98,0.096,0.337,6.99,16.99,0.169,0.41,411
|
||||
CZCE,TA412,PTA12月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5898.0,5896.0,5908.0,19,2232,3.01,3.01,0.0,4135.6,4135.6,29540.0,10.0,3.98,13.98,0.096,0.338,6.99,16.99,0.169,0.411,412
|
||||
CZCE,TA501,PTA1月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5906.0,5900.0,5908.0,16948,294585,3.01,3.01,0.0,4135.6,4135.6,29540.0,10.0,3.98,13.98,0.096,0.338,6.99,16.99,0.169,0.411,501
|
||||
CZCE,TA502,PTA2月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5944.0,5920.0,5912.0,6,4363,3.01,3.01,0.0,4138.4,4138.4,29560.0,10.0,3.98,13.98,0.096,0.338,6.99,16.99,0.169,0.41,502
|
||||
CZCE,TA503,PTA3月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5922.0,5892.0,5908.0,8,4135,3.01,3.01,0.0,4135.6,4135.6,29540.0,10.0,3.98,13.98,0.096,0.338,6.99,16.99,0.169,0.411,503
|
||||
CZCE,TA504,PTA4月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5910.0,5910.0,5902.0,3,274,3.01,3.01,0.0,4131.4,4131.4,29510.0,10.0,3.98,13.98,0.096,0.338,6.99,16.99,0.169,0.411,504
|
||||
CZCE,TA505,PTA5月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5902.0,5900.0,5908.0,59,2143,3.01,3.01,0.0,4135.6,4135.6,29540.0,10.0,3.98,13.98,0.096,0.338,6.99,16.99,0.169,0.411,505
|
||||
CZCE,TA506,PTA6月,TA,精对苯二甲酸,5,2.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,5900.0,5900.0,5900.0,0,11,3.01,3.01,0.0,4130.0,4130.0,29500.0,10.0,3.98,13.98,0.096,0.338,6.99,16.99,0.169,0.411,506
|
||||
CFFEX,TF2409,国债2409,TF,5年期国债期货,10000,0.005,0.0,3.01,0.0,3.01,0.0,0.0,0.022,0,0.022,0,103.87,103.865,0.0,0,116126,3.07,3.07,0.06,22850.3,22850.3,1038650.0,50.0,43.86,93.86,0.192,0.411,46.87,96.87,0.205,0.424,2409
|
||||
CFFEX,TF2412,国债2412,TF,5年期国债期货,10000,0.005,0.0,3.01,0.0,3.01,0.0,0.0,0.022,0,0.022,0,103.765,103.775,0.0,0,6521,3.07,3.07,0.06,22830.5,22830.5,1037750.0,50.0,43.86,93.86,0.192,0.411,46.87,96.87,0.205,0.424,2412
|
||||
CFFEX,TF2503,国债2503,TF,5年期国债期货,10000,0.005,0.0,3.01,0.0,3.01,0.0,0.0,0.022,0,0.022,0,103.74,103.745,0.0,0,825,3.07,3.07,0.06,22823.9,22823.9,1037450.0,50.0,43.86,93.86,0.192,0.411,46.87,96.87,0.205,0.424,2503
|
||||
CFFEX,TL2409,30年期国债期货2409,TL,30年期国债期货,10000,0.01,0.0,3.01,0.0,3.01,0.0,0.0,0.05,0,0.05,0,108.45,108.46,0.0,0,75624,3.08,3.08,0.07,54230.0,54230.0,1084600.0,100.0,93.85,193.85,0.173,0.357,96.86,196.86,0.179,0.363,2409
|
||||
CFFEX,TL2412,30年期国债期货2412,TL,30年期国债期货,10000,0.01,0.0,3.01,0.0,3.01,0.0,0.0,0.05,0,0.05,0,108.16,108.18,0.0,0,17096,3.07,3.07,0.06,54090.0,54090.0,1081800.0,100.0,93.85,193.85,0.174,0.358,96.86,196.86,0.179,0.364,2412
|
||||
CFFEX,TL2503,30年期国债期货2503,TL,30年期国债期货,10000,0.01,0.0,3.01,0.0,3.01,0.0,0.0,0.05,0,0.05,0,107.98,108.02,0.0,0,1222,3.07,3.07,0.06,54010.0,54010.0,1080200.0,100.0,93.85,193.85,0.174,0.359,96.86,196.86,0.179,0.364,2503
|
||||
CFFEX,TS2409,2年期国债期货2409,TS,2年期国债期货,20000,0.002,0.0,3.01,0.0,3.01,0.0,0.0,0.01,0,0.01,0,101.936,101.938,0.0,0,54860,3.13,3.13,0.12,20387.6,20387.6,2038760.0,40.0,33.74,73.74,0.165,0.362,36.75,76.75,0.18,0.376,2409
|
||||
CFFEX,TS2412,2年期国债期货2412,TS,2年期国债期货,20000,0.002,0.0,3.01,0.0,3.01,0.0,0.0,0.01,0,0.01,0,101.916,101.92,0.0,0,4104,3.13,3.13,0.12,20384.0,20384.0,2038400.0,40.0,33.74,73.74,0.165,0.362,36.75,76.75,0.18,0.376,2412
|
||||
CFFEX,TS2503,2年期国债期货2503,TS,2年期国债期货,20000,0.002,0.0,3.01,0.0,3.01,0.0,0.0,0.01,0,0.01,0,101.926,101.928,0.0,0,580,3.13,3.13,0.12,20385.6,20385.6,2038560.0,40.0,33.74,73.74,0.165,0.362,36.75,76.75,0.18,0.376,2503
|
||||
CZCE,UR407,尿素7月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,2153.0,2150.0,2150.0,0,752,4.31,4.31,4.31,10750.0,10750.0,43000.0,20.0,11.37,31.37,0.106,0.292,11.37,31.37,0.106,0.292,407
|
||||
CZCE,UR408,尿素8月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.15,0,0.15,0,2135.0,2136.0,2136.0,0,635,4.28,4.28,4.28,6408.0,6408.0,42720.0,20.0,11.43,31.43,0.178,0.49,11.43,31.43,0.178,0.49,408
|
||||
CZCE,UR409,尿素9月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.15,0,0.15,0,2061.0,2055.0,2055.0,0,185561,4.12,4.12,4.12,6165.0,6165.0,41100.0,20.0,11.76,31.76,0.191,0.515,11.76,31.76,0.191,0.515,409
|
||||
CZCE,UR410,尿素10月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,2033.0,2025.0,2025.0,0,1539,4.06,4.06,4.06,5265.0,5265.0,40500.0,20.0,11.88,31.88,0.226,0.605,11.88,31.88,0.226,0.605,410
|
||||
CZCE,UR411,尿素11月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,2056.0,2050.0,2050.0,0,1028,4.11,4.11,4.11,5330.0,5330.0,41000.0,20.0,11.78,31.78,0.221,0.596,11.78,31.78,0.221,0.596,411
|
||||
CZCE,UR412,尿素12月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,2029.0,2021.0,2021.0,0,364,4.05,4.05,4.05,5254.6,5254.6,40420.0,20.0,11.89,31.89,0.226,0.607,11.89,31.89,0.226,0.607,412
|
||||
CZCE,UR501,尿素1月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,2001.0,1995.0,1995.0,0,43565,4.0,4.0,4.0,5187.0,5187.0,39900.0,20.0,12.0,32.0,0.231,0.617,12.0,32.0,0.231,0.617,501
|
||||
CZCE,UR502,尿素2月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,1973.0,1972.0,1972.0,0,1214,3.96,3.96,3.96,5127.2,5127.2,39440.0,20.0,12.09,32.09,0.236,0.626,12.09,32.09,0.236,0.626,502
|
||||
CZCE,UR503,尿素3月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,2006.0,1999.0,1999.0,0,448,4.01,4.01,4.01,5197.4,5197.4,39980.0,20.0,11.98,31.98,0.23,0.615,11.98,31.98,0.23,0.615,503
|
||||
CZCE,UR504,尿素4月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,1981.0,1979.0,1979.0,0,416,3.97,3.97,3.97,5145.4,5145.4,39580.0,20.0,12.06,32.06,0.234,0.623,12.06,32.06,0.234,0.623,504
|
||||
CZCE,UR505,尿素5月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,1955.0,1950.0,1950.0,0,9381,3.91,3.91,3.91,5070.0,5070.0,39000.0,20.0,12.18,32.18,0.24,0.635,12.18,32.18,0.24,0.635,505
|
||||
CZCE,UR506,尿素6月,UR,尿素,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,1940.0,1935.0,1935.0,0,983,3.88,3.88,3.88,5031.0,5031.0,38700.0,20.0,12.24,32.24,0.243,0.641,12.24,32.24,0.243,0.641,506
|
||||
CZCE,WH407,强麦7月,WH,优质强筋小麦,20,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.45,0,0.45,0,3198.0,3198.0,3198.0,0,0,30.01,30.01,30.01,28782.0,28782.0,63960.0,20.0,-40.03,-20.03,-0.139,-0.07,-40.03,-20.03,-0.139,-0.07,407
|
||||
CZCE,WH409,强麦9月,WH,优质强筋小麦,20,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3198.0,3198.0,3198.0,0,0,30.01,30.01,30.01,25584.0,25584.0,63960.0,20.0,-40.03,-20.03,-0.156,-0.078,-40.03,-20.03,-0.156,-0.078,409
|
||||
CZCE,WH411,强麦11月,WH,优质强筋小麦,20,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3198.0,3198.0,3198.0,0,0,30.01,30.01,30.01,25584.0,25584.0,63960.0,20.0,-40.03,-20.03,-0.156,-0.078,-40.03,-20.03,-0.156,-0.078,411
|
||||
CZCE,WH501,强麦1月,WH,优质强筋小麦,20,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3198.0,3198.0,3198.0,0,0,30.01,30.01,30.01,25584.0,25584.0,63960.0,20.0,-40.03,-20.03,-0.156,-0.078,-40.03,-20.03,-0.156,-0.078,501
|
||||
CZCE,WH503,强麦3月,WH,优质强筋小麦,20,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3198.0,3198.0,3198.0,0,0,30.01,30.01,30.01,25584.0,25584.0,63960.0,20.0,-40.03,-20.03,-0.156,-0.078,-40.03,-20.03,-0.156,-0.078,503
|
||||
CZCE,WH505,强麦5月,WH,优质强筋小麦,20,1.0,0.0,30.01,0.0,30.01,0.0,30.01,0.4,0,0.4,0,3198.0,3198.0,3198.0,0,0,30.01,30.01,30.01,25584.0,25584.0,63960.0,20.0,-40.03,-20.03,-0.156,-0.078,-40.03,-20.03,-0.156,-0.078,505
|
||||
CZCE,ZC408,煤8月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,408
|
||||
CZCE,ZC409,煤9月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,409
|
||||
CZCE,ZC410,煤10月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,410
|
||||
CZCE,ZC411,煤11月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,411
|
||||
CZCE,ZC412,煤12月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,412
|
||||
CZCE,ZC501,煤1月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,501
|
||||
CZCE,ZC502,煤2月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,502
|
||||
CZCE,ZC503,煤3月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,503
|
||||
CZCE,ZC504,煤4月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,504
|
||||
CZCE,ZC505,煤5月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,505
|
||||
CZCE,ZC506,煤6月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,506
|
||||
CZCE,ZC507,煤7月,ZC,动力煤N,100,0.2,0.0,150.01,0.0,150.01,0.0,150.01,0.55,0,0.55,0,801.4,801.4,801.4,0,0,150.01,150.01,150.01,44077.0,44077.0,80140.0,20.0,-280.03,-260.03,-0.635,-0.59,-280.03,-260.03,-0.635,-0.59,507
|
||||
DCE,a2407,豆一2407,a,黄大豆1号,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.25,0,0.25,0,4536.0,4639.0,4639.0,0,4,2.01,2.01,2.01,11597.5,11597.5,46390.0,10.0,5.97,15.97,0.052,0.138,5.97,15.97,0.052,0.138,2407
|
||||
DCE,a2409,豆一2409,a,黄大豆1号,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.12,0,0.12,0,4632.0,4633.0,4620.0,22084,130961,2.01,2.01,2.01,5544.0,5544.0,46200.0,10.0,5.97,15.97,0.108,0.288,5.97,15.97,0.108,0.288,2409
|
||||
DCE,a2411,豆一2411,a,黄大豆1号,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.12,0,0.12,0,4522.0,4523.0,4526.0,739,18012,2.01,2.01,2.01,5431.2,5431.2,45260.0,10.0,5.97,15.97,0.11,0.294,5.97,15.97,0.11,0.294,2411
|
||||
DCE,a2501,豆一2501,a,黄大豆1号,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.12,0,0.12,0,4487.0,4487.0,4493.0,2338,36864,2.01,2.01,2.01,5391.6,5391.6,44930.0,10.0,5.97,15.97,0.111,0.296,5.97,15.97,0.111,0.296,2501
|
||||
DCE,a2503,豆一2503,a,黄大豆1号,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.12,0,0.12,0,4457.0,4460.0,4465.0,39,2865,2.01,2.01,2.01,5358.0,5358.0,44650.0,10.0,5.97,15.97,0.112,0.298,5.97,15.97,0.112,0.298,2503
|
||||
DCE,a2505,豆一2505,a,黄大豆1号,10,1.0,0.0,2.01,0.0,2.01,0.0,2.01,0.12,0,0.12,0,4478.0,4483.0,4488.0,105,2824,2.01,2.01,2.01,5385.6,5385.6,44880.0,10.0,5.97,15.97,0.111,0.297,5.97,15.97,0.111,0.297,2505
|
||||
SHFE,ag2407,ag2407,ag,白银,15,1.0,5e-05,0.01,5e-05,0.01,5e-05,0.01,0.25,0,0.25,0,8120.0,8120.0,8150.0,10,6690,6.13,6.13,6.13,30562.5,30562.5,122250.0,15.0,2.74,17.74,0.009,0.058,2.74,17.74,0.009,0.058,2407
|
||||
SHFE,ag2408,ag2408,ag,白银,15,1.0,5e-05,0.01,5e-05,0.01,5e-05,0.01,0.17,0,0.17,0,8112.0,8128.0,8136.0,304225,273408,6.12,6.12,6.12,20746.8,20746.8,122040.0,15.0,2.76,17.76,0.013,0.086,2.76,17.76,0.013,0.086,2408
|
||||
SHFE,ag2409,ag2409,ag,白银,15,1.0,5e-05,0.01,5e-05,0.01,5e-05,0.01,0.17,0,0.17,0,8133.0,8146.0,8152.0,12136,25264,6.13,6.13,6.13,20787.6,20787.6,122280.0,15.0,2.74,17.74,0.013,0.085,2.74,17.74,0.013,0.085,2409
|
||||
SHFE,ag2410,ag2410,ag,白银,15,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.17,0,0.17,0,8144.0,8156.0,8163.0,84162,206760,1.24,1.24,1.24,20815.65,20815.65,122445.0,15.0,12.52,27.52,0.06,0.132,12.52,27.52,0.06,0.132,2410
|
||||
SHFE,ag2411,ag2411,ag,白银,15,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.17,0,0.17,0,8163.0,8177.0,8179.0,5272,17971,1.24,1.24,1.24,20856.45,20856.45,122685.0,15.0,12.51,27.51,0.06,0.132,12.51,27.51,0.06,0.132,2411
|
||||
SHFE,ag2412,ag2412,ag,白银,15,1.0,5e-05,0.01,5e-05,0.01,5e-05,0.01,0.17,0,0.17,0,8173.0,8185.0,8194.0,87383,387376,6.16,6.16,6.16,20894.7,20894.7,122910.0,15.0,2.67,17.67,0.013,0.085,2.67,17.67,0.013,0.085,2412
|
||||
SHFE,ag2501,ag2501,ag,白银,15,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.17,0,0.17,0,8196.0,8207.0,8211.0,3230,12992,1.25,1.25,1.25,20938.05,20938.05,123165.0,15.0,12.5,27.5,0.06,0.131,12.5,27.5,0.06,0.131,2501
|
||||
SHFE,ag2502,ag2502,ag,白银,15,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.17,0,0.17,0,8211.0,8219.0,8225.0,6588,46635,1.25,1.25,1.25,20973.75,20973.75,123375.0,15.0,12.5,27.5,0.06,0.131,12.5,27.5,0.06,0.131,2502
|
||||
SHFE,ag2503,ag2503,ag,白银,15,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.17,0,0.17,0,8232.0,8234.0,8244.0,1552,10692,1.25,1.25,1.25,21022.2,21022.2,123660.0,15.0,12.49,27.49,0.059,0.131,12.49,27.49,0.059,0.131,2503
|
||||
SHFE,ag2504,ag2504,ag,白银,15,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.17,0,0.17,0,8246.0,8248.0,8256.0,2163,23377,1.26,1.26,1.26,21052.8,21052.8,123840.0,15.0,12.49,27.49,0.059,0.131,12.49,27.49,0.059,0.131,2504
|
||||
SHFE,ag2505,ag2505,ag,白银,15,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.17,0,0.17,0,8261.0,8270.0,8277.0,1765,6631,1.26,1.26,1.26,21106.35,21106.35,124155.0,15.0,12.48,27.48,0.059,0.13,12.48,27.48,0.059,0.13,2505
|
||||
SHFE,ag2506,ag2506,ag,白银,15,1.0,5e-05,0.01,5e-05,0.01,5e-05,0.01,0.17,0,0.17,0,8268.0,8279.0,8288.0,574,3106,6.23,6.23,6.23,21134.4,21134.4,124320.0,15.0,2.53,17.53,0.012,0.083,2.53,17.53,0.012,0.083,2506
|
||||
SHFE,al2407,al2407,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.25,0,0.25,0,20235.0,20090.0,20130.0,615,14105,3.02,3.02,3.02,25162.5,25162.5,100650.0,25.0,18.97,43.97,0.075,0.175,18.97,43.97,0.075,0.175,2407
|
||||
SHFE,al2408,al2408,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.15,0,0.15,0,20250.0,20100.0,20175.0,48483,156096,3.02,3.02,3.02,15131.25,15131.25,100875.0,25.0,18.97,43.97,0.125,0.291,18.97,43.97,0.125,0.291,2408
|
||||
SHFE,al2409,al2409,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20290.0,20140.0,20215.0,33184,180607,3.02,3.02,3.02,14150.5,14150.5,101075.0,25.0,18.97,43.97,0.134,0.311,18.97,43.97,0.134,0.311,2409
|
||||
SHFE,al2410,al2410,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20305.0,20175.0,20250.0,6046,61575,3.02,3.02,3.02,14175.0,14175.0,101250.0,25.0,18.97,43.97,0.134,0.31,18.97,43.97,0.134,0.31,2410
|
||||
SHFE,al2411,al2411,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20330.0,20205.0,20265.0,1536,27711,3.02,3.02,3.02,14185.5,14185.5,101325.0,25.0,18.97,43.97,0.134,0.31,18.97,43.97,0.134,0.31,2411
|
||||
SHFE,al2412,al2412,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20315.0,20230.0,20270.0,1551,23514,3.02,3.02,3.02,14189.0,14189.0,101350.0,25.0,18.97,43.97,0.134,0.31,18.97,43.97,0.134,0.31,2412
|
||||
SHFE,al2501,al2501,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20360.0,20250.0,20305.0,310,11686,3.02,3.02,3.02,14213.5,14213.5,101525.0,25.0,18.97,43.97,0.133,0.309,18.97,43.97,0.133,0.309,2501
|
||||
SHFE,al2502,al2502,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20340.0,20285.0,20340.0,64,4258,3.02,3.02,3.02,14238.0,14238.0,101700.0,25.0,18.97,43.97,0.133,0.309,18.97,43.97,0.133,0.309,2502
|
||||
SHFE,al2503,al2503,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20440.0,20330.0,20405.0,3,1515,3.02,3.02,3.02,14283.5,14283.5,102025.0,25.0,18.97,43.97,0.133,0.308,18.97,43.97,0.133,0.308,2503
|
||||
SHFE,al2504,al2504,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20470.0,20350.0,20400.0,6,765,3.02,3.02,3.02,14280.0,14280.0,102000.0,25.0,18.97,43.97,0.133,0.308,18.97,43.97,0.133,0.308,2504
|
||||
SHFE,al2505,al2505,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20480.0,20375.0,20410.0,5,470,3.02,3.02,3.02,14287.0,14287.0,102050.0,25.0,18.97,43.97,0.133,0.308,18.97,43.97,0.133,0.308,2505
|
||||
SHFE,al2506,al2506,al,铝,5,5.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,20450.0,20365.0,20410.0,10,113,3.02,3.02,3.02,14287.0,14287.0,102050.0,25.0,18.97,43.97,0.133,0.308,18.97,43.97,0.133,0.308,2506
|
||||
SHFE,ao2407,ao2407,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,3771.0,3766.0,3766.0,0,3525,7.55,7.55,7.55,18830.0,18830.0,75320.0,20.0,4.91,24.91,0.026,0.132,4.91,24.91,0.026,0.132,2407
|
||||
SHFE,ao2408,ao2408,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.15,0,0.15,0,3793.0,3731.0,3662.0,90468,47576,7.34,7.34,7.34,10986.0,10986.0,73240.0,20.0,5.32,25.32,0.048,0.231,5.32,25.32,0.048,0.231,2408
|
||||
SHFE,ao2409,ao2409,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3801.0,3740.0,3641.0,69659,79416,7.3,7.3,7.3,10194.8,10194.8,72820.0,20.0,5.41,25.41,0.053,0.249,5.41,25.41,0.053,0.249,2409
|
||||
SHFE,ao2410,ao2410,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3809.0,3750.0,3642.0,11780,16762,7.3,7.3,7.3,10197.6,10197.6,72840.0,20.0,5.4,25.4,0.053,0.249,5.4,25.4,0.053,0.249,2410
|
||||
SHFE,ao2411,ao2411,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3812.0,3750.0,3651.0,3744,9493,7.32,7.32,7.32,10222.8,10222.8,73020.0,20.0,5.37,25.37,0.053,0.248,5.37,25.37,0.053,0.248,2411
|
||||
SHFE,ao2412,ao2412,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3800.0,3755.0,3661.0,352,1948,7.34,7.34,7.34,10250.8,10250.8,73220.0,20.0,5.33,25.33,0.052,0.247,5.33,25.33,0.052,0.247,2412
|
||||
SHFE,ao2501,ao2501,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3808.0,3751.0,3659.0,748,1262,7.33,7.33,7.33,10245.2,10245.2,73180.0,20.0,5.34,25.34,0.052,0.247,5.34,25.34,0.052,0.247,2501
|
||||
SHFE,ao2502,ao2502,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3778.0,3749.0,3660.0,39,142,7.33,7.33,7.33,10248.0,10248.0,73200.0,20.0,5.33,25.33,0.052,0.247,5.33,25.33,0.052,0.247,2502
|
||||
SHFE,ao2503,ao2503,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3772.0,3740.0,3657.0,26,107,7.33,7.33,7.33,10239.6,10239.6,73140.0,20.0,5.34,25.34,0.052,0.248,5.34,25.34,0.052,0.248,2503
|
||||
SHFE,ao2504,ao2504,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3777.0,3736.0,3647.0,44,126,7.31,7.31,7.31,10211.6,10211.6,72940.0,20.0,5.38,25.38,0.053,0.249,5.38,25.38,0.053,0.249,2504
|
||||
SHFE,ao2505,ao2505,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3793.0,3739.0,3653.0,46,99,7.32,7.32,7.32,10228.4,10228.4,73060.0,20.0,5.36,25.36,0.052,0.248,5.36,25.36,0.052,0.248,2505
|
||||
SHFE,ao2506,ao2506,ao,氧化铝,20,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.14,0,0.14,0,3737.0,3711.0,3635.0,24,34,7.28,7.28,7.28,10178.0,10178.0,72700.0,20.0,5.43,25.43,0.053,0.25,5.43,25.43,0.053,0.25,2506
|
||||
SHFE,au2407,au2407,au,黄金,1000,0.02,0.0,10.01,0.0,10.01,0.0,0.0,0.25,0,0.25,0,557.46,557.46,557.46,0,96,10.04,10.04,0.03,139365.0,139365.0,557460.0,20.0,-0.09,19.91,-0.0,0.014,9.92,29.92,0.007,0.021,2407
|
||||
SHFE,au2408,au2408,au,黄金,1000,0.02,0.0,10.01,0.0,10.01,0.0,6.01,0.17,0,0.17,0,558.78,561.1,562.22,19810,87433,10.04,10.04,6.04,95577.4,95577.4,562220.0,20.0,-0.09,19.91,-0.0,0.021,3.91,23.91,0.004,0.025,2408
|
||||
SHFE,au2409,au2409,au,黄金,1000,0.02,0.0,10.01,0.0,10.01,0.0,0.0,0.17,0,0.17,0,561.46,562.78,564.06,118,324,10.04,10.04,0.03,95890.2,95890.2,564060.0,20.0,-0.09,19.91,-0.0,0.021,9.92,29.92,0.01,0.031,2409
|
||||
SHFE,au2410,au2410,au,黄金,1000,0.02,0.0,2.01,0.0,2.01,0.0,0.0,0.17,0,0.17,0,561.22,563.4,564.72,34715,140549,2.04,2.04,0.03,96002.4,96002.4,564720.0,20.0,15.91,35.91,0.017,0.037,17.92,37.92,0.019,0.04,2410
|
||||
SHFE,au2412,au2412,au,黄金,1000,0.02,0.0,10.01,0.0,10.01,0.0,0.0,0.17,0,0.17,0,563.44,565.58,566.96,8542,120256,10.04,10.04,0.03,96383.2,96383.2,566960.0,20.0,-0.09,19.91,-0.0,0.021,9.92,29.92,0.01,0.031,2412
|
||||
SHFE,au2502,au2502,au,黄金,1000,0.02,0.0,2.01,0.0,2.01,0.0,0.0,0.17,0,0.17,0,565.56,567.8,569.1,1152,15972,2.04,2.04,0.03,96747.0,96747.0,569100.0,20.0,15.91,35.91,0.016,0.037,17.92,37.92,0.019,0.039,2502
|
||||
SHFE,au2504,au2504,au,黄金,1000,0.02,0.0,2.01,0.0,2.01,0.0,0.0,0.17,0,0.17,0,567.78,570.04,571.3,1136,14497,2.04,2.04,0.03,97121.0,97121.0,571300.0,20.0,15.91,35.91,0.016,0.037,17.92,37.92,0.018,0.039,2504
|
||||
SHFE,au2506,au2506,au,黄金,1000,0.02,0.0,10.01,0.0,10.01,0.0,0.0,0.17,0,0.17,0,570.86,572.78,573.6,288,7299,10.04,10.04,0.03,97512.0,97512.0,573600.0,20.0,-0.09,19.91,-0.0,0.02,9.92,29.92,0.01,0.031,2506
|
||||
DCE,b2407,豆二2407,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.26,0,0.26,0,3601.0,3601.0,3601.0,0,5,1.01,1.01,1.01,9362.6,9362.6,36010.0,10.0,7.98,17.98,0.085,0.192,7.98,17.98,0.085,0.192,2407
|
||||
DCE,b2408,豆二2408,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3671.0,3657.0,3666.0,1193,8918,1.01,1.01,1.01,4765.8,4765.8,36660.0,10.0,7.98,17.98,0.167,0.377,7.98,17.98,0.167,0.377,2408
|
||||
DCE,b2409,豆二2409,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3752.0,3733.0,3737.0,39878,117584,1.01,1.01,1.01,4858.1,4858.1,37370.0,10.0,7.98,17.98,0.164,0.37,7.98,17.98,0.164,0.37,2409
|
||||
DCE,b2410,豆二2410,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3751.0,3744.0,3750.0,2237,10645,1.01,1.01,1.01,4875.0,4875.0,37500.0,10.0,7.98,17.98,0.164,0.369,7.98,17.98,0.164,0.369,2410
|
||||
DCE,b2411,豆二2411,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3788.0,3785.0,3795.0,801,4977,1.01,1.01,1.01,4933.5,4933.5,37950.0,10.0,7.98,17.98,0.162,0.364,7.98,17.98,0.162,0.364,2411
|
||||
DCE,b2412,豆二2412,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3832.0,3822.0,3837.0,182,2960,1.01,1.01,1.01,4988.1,4988.1,38370.0,10.0,7.98,17.98,0.16,0.36,7.98,17.98,0.16,0.36,2412
|
||||
DCE,b2501,豆二2501,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3842.0,3822.0,3837.0,206,3502,1.01,1.01,1.01,4988.1,4988.1,38370.0,10.0,7.98,17.98,0.16,0.36,7.98,17.98,0.16,0.36,2501
|
||||
DCE,b2502,豆二2502,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3819.0,3772.0,3794.0,5,195,1.01,1.01,1.01,4932.2,4932.2,37940.0,10.0,7.98,17.98,0.162,0.364,7.98,17.98,0.162,0.364,2502
|
||||
DCE,b2503,豆二2503,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3742.0,3716.0,3727.0,8,445,1.01,1.01,1.01,4845.1,4845.1,37270.0,10.0,7.98,17.98,0.165,0.371,7.98,17.98,0.165,0.371,2503
|
||||
DCE,b2504,豆二2504,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3715.0,3672.0,3687.0,5,183,1.01,1.01,1.01,4793.1,4793.1,36870.0,10.0,7.98,17.98,0.166,0.375,7.98,17.98,0.166,0.375,2504
|
||||
DCE,b2505,豆二2505,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3674.0,3650.0,3668.0,92,5500,1.01,1.01,1.01,4768.4,4768.4,36680.0,10.0,7.98,17.98,0.167,0.377,7.98,17.98,0.167,0.377,2505
|
||||
DCE,b2506,豆二2506,b,黄大豆2号,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,3671.0,3663.0,3681.0,1,41,1.01,1.01,1.01,4785.3,4785.3,36810.0,10.0,7.98,17.98,0.167,0.376,7.98,17.98,0.167,0.376,2506
|
||||
DCE,bb2407,胶合板2407,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,400.0,400.0,400.0,0,0,20.02,20.02,20.02,90000.0,90000.0,200000.0,25.0,-15.04,9.96,-0.017,0.011,-15.04,9.96,-0.017,0.011,2407
|
||||
DCE,bb2408,胶合板2408,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,400.0,400.0,400.0,0,0,20.02,20.02,20.02,90000.0,90000.0,200000.0,25.0,-15.04,9.96,-0.017,0.011,-15.04,9.96,-0.017,0.011,2408
|
||||
DCE,bb2409,胶合板2409,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,400.0,400.0,400.0,0,0,20.02,20.02,20.02,90000.0,90000.0,200000.0,25.0,-15.04,9.96,-0.017,0.011,-15.04,9.96,-0.017,0.011,2409
|
||||
DCE,bb2410,胶合板2410,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,400.0,400.0,400.0,0,0,20.02,20.02,20.02,90000.0,90000.0,200000.0,25.0,-15.04,9.96,-0.017,0.011,-15.04,9.96,-0.017,0.011,2410
|
||||
DCE,bb2411,胶合板2411,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,400.0,400.0,400.0,0,0,20.02,20.02,20.02,90000.0,90000.0,200000.0,25.0,-15.04,9.96,-0.017,0.011,-15.04,9.96,-0.017,0.011,2411
|
||||
DCE,bb2412,胶合板2412,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,400.0,400.0,400.0,0,0,20.02,20.02,20.02,90000.0,90000.0,200000.0,25.0,-15.04,9.96,-0.017,0.011,-15.04,9.96,-0.017,0.011,2412
|
||||
DCE,bb2501,胶合板2501,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,193.05,191.0,191.0,0,60,9.57,9.57,9.57,42975.0,42975.0,95500.0,25.0,5.87,30.87,0.014,0.072,5.87,30.87,0.014,0.072,2501
|
||||
DCE,bb2502,胶合板2502,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,218.4,218.4,218.4,0,0,10.94,10.94,10.94,49140.0,49140.0,109200.0,25.0,3.13,28.13,0.006,0.057,3.13,28.13,0.006,0.057,2502
|
||||
DCE,bb2503,胶合板2503,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,194.85,194.85,194.85,0,0,9.76,9.76,9.76,43841.25,43841.25,97425.0,25.0,5.48,30.48,0.013,0.07,5.48,30.48,0.013,0.07,2503
|
||||
DCE,bb2504,胶合板2504,bb,胶合板,500,0.05,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.45,0,0.45,0,167.3,167.3,167.3,0,18,8.38,8.38,8.38,37642.5,37642.5,83650.0,25.0,8.24,33.24,0.022,0.088,8.24,33.24,0.022,0.088,2504
|
||||
INE,bc2407,bc2407,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.25,0,0.25,0,70900.0,70900.0,70900.0,0,3250,3.58,3.58,0.02,88625.0,88625.0,354500.0,50.0,42.85,92.85,0.048,0.105,46.4,96.4,0.052,0.109,2407
|
||||
INE,bc2408,bc2408,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.15,0,0.15,0,71230.0,70890.0,71350.0,2695,6944,3.6,3.6,0.02,53512.5,53512.5,356750.0,50.0,42.8,92.8,0.08,0.173,46.38,96.38,0.087,0.18,2408
|
||||
INE,bc2409,bc2409,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,71420.0,71070.0,71540.0,976,5986,3.61,3.61,0.02,50078.0,50078.0,357700.0,50.0,42.78,92.78,0.085,0.185,46.37,96.37,0.093,0.192,2409
|
||||
INE,bc2410,bc2410,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,71540.0,71340.0,71640.0,58,216,3.61,3.61,0.02,50148.0,50148.0,358200.0,50.0,42.77,92.77,0.085,0.185,46.37,96.37,0.092,0.192,2410
|
||||
INE,bc2411,bc2411,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,71460.0,71300.0,71820.0,1,31,3.62,3.62,0.02,50274.0,50274.0,359100.0,50.0,42.75,92.75,0.085,0.184,46.36,96.36,0.092,0.192,2411
|
||||
INE,bc2412,bc2412,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,71350.0,71350.0,71350.0,0,2,3.6,3.6,0.02,49945.0,49945.0,356750.0,50.0,42.8,92.8,0.086,0.186,46.38,96.38,0.093,0.193,2412
|
||||
INE,bc2501,bc2501,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,71050.0,71050.0,71050.0,0,2,3.58,3.58,0.02,49735.0,49735.0,355250.0,50.0,42.83,92.83,0.086,0.187,46.39,96.39,0.093,0.194,2501
|
||||
INE,bc2502,bc2502,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,71370.0,71370.0,71370.0,0,4,3.6,3.6,0.02,49959.0,49959.0,356850.0,50.0,42.8,92.8,0.086,0.186,46.38,96.38,0.093,0.193,2502
|
||||
INE,bc2503,bc2503,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,71110.0,71110.0,71110.0,0,2,3.59,3.59,0.02,49777.0,49777.0,355550.0,50.0,42.83,92.83,0.086,0.186,46.39,96.39,0.093,0.194,2503
|
||||
INE,bc2504,bc2504,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,70480.0,70480.0,70480.0,0,1,3.56,3.56,0.02,49336.0,49336.0,352400.0,50.0,42.89,92.89,0.087,0.188,46.42,96.42,0.094,0.195,2504
|
||||
INE,bc2505,bc2505,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,72330.0,72330.0,72330.0,0,0,3.65,3.65,0.02,50631.0,50631.0,361650.0,50.0,42.7,92.7,0.084,0.183,46.33,96.33,0.092,0.19,2505
|
||||
INE,bc2506,bc2506,bc,国际铜,5,10.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.14,0,0.14,0,72680.0,72680.0,72680.0,0,0,3.67,3.67,0.02,50876.0,50876.0,363400.0,50.0,42.67,92.67,0.084,0.182,46.31,96.31,0.091,0.189,2506
|
||||
SHFE,br2407,br2407,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,0.0001,0.01,0.25,0,0.25,0,14820.0,14715.0,14715.0,0,1336,1.49,1.49,7.37,18393.75,18393.75,73575.0,25.0,22.03,47.03,0.12,0.256,16.14,41.14,0.088,0.224,2407
|
||||
SHFE,br2408,br2408,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,0.0001,0.01,0.17,0,0.17,0,14765.0,14640.0,14745.0,22235,23676,1.49,1.49,7.39,12533.25,12533.25,73725.0,25.0,22.02,47.02,0.176,0.375,16.12,41.12,0.129,0.328,2408
|
||||
SHFE,br2409,br2409,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14670.0,14545.0,14655.0,16423,39727,1.48,1.48,1.48,12456.75,12456.75,73275.0,25.0,22.04,47.04,0.177,0.378,22.04,47.04,0.177,0.378,2409
|
||||
SHFE,br2410,br2410,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14600.0,14490.0,14575.0,447,596,1.47,1.47,1.47,12388.75,12388.75,72875.0,25.0,22.06,47.06,0.178,0.38,22.06,47.06,0.178,0.38,2410
|
||||
SHFE,br2411,br2411,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14605.0,14385.0,14530.0,12,144,1.47,1.47,1.47,12350.5,12350.5,72650.0,25.0,22.07,47.07,0.179,0.381,22.07,47.07,0.179,0.381,2411
|
||||
SHFE,br2412,br2412,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14400.0,14400.0,14550.0,1,9,1.47,1.47,1.47,12367.5,12367.5,72750.0,25.0,22.06,47.06,0.178,0.381,22.06,47.06,0.178,0.381,2412
|
||||
SHFE,br2501,br2501,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14515.0,14320.0,14500.0,52,419,1.46,1.46,1.46,12325.0,12325.0,72500.0,25.0,22.07,47.07,0.179,0.382,22.07,47.07,0.179,0.382,2501
|
||||
SHFE,br2502,br2502,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14525.0,14460.0,14460.0,0,23,1.46,1.46,1.46,12291.0,12291.0,72300.0,25.0,22.08,47.08,0.18,0.383,22.08,47.08,0.18,0.383,2502
|
||||
SHFE,br2503,br2503,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14625.0,14625.0,14625.0,0,19,1.48,1.48,1.48,12431.25,12431.25,73125.0,25.0,22.05,47.05,0.177,0.378,22.05,47.05,0.177,0.378,2503
|
||||
SHFE,br2504,br2504,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14405.0,14290.0,14290.0,0,21,1.44,1.44,1.44,12146.5,12146.5,71450.0,25.0,22.11,47.11,0.182,0.388,22.11,47.11,0.182,0.388,2504
|
||||
SHFE,br2505,br2505,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14395.0,14290.0,14340.0,3,47,1.45,1.45,1.45,12189.0,12189.0,71700.0,25.0,22.1,47.1,0.181,0.386,22.1,47.1,0.181,0.386,2505
|
||||
SHFE,br2506,br2506,br,丁二烯橡胶,5,5.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.17,0,0.17,0,14390.0,14015.0,14285.0,1,4,1.44,1.44,1.44,12142.25,12142.25,71425.0,25.0,22.11,47.11,0.182,0.388,22.11,47.11,0.182,0.388,2506
|
||||
SHFE,bu2407,bu2407,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.25,0,0.25,0,3560.0,3560.0,3560.0,0,780,1.79,1.79,0.0,8900.0,8900.0,35600.0,10.0,6.42,16.42,0.072,0.184,8.21,18.21,0.092,0.205,2407
|
||||
SHFE,bu2408,bu2408,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3622.0,3604.0,3607.0,7,895,1.82,1.82,0.0,5410.5,5410.5,36070.0,10.0,6.37,16.37,0.118,0.303,8.18,18.18,0.151,0.336,2408
|
||||
SHFE,bu2409,bu2409,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3650.0,3626.0,3635.0,52379,208195,1.83,1.83,0.0,5452.5,5452.5,36350.0,10.0,6.34,16.34,0.116,0.3,8.17,18.17,0.15,0.333,2409
|
||||
SHFE,bu2410,bu2410,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3644.0,3617.0,3629.0,12569,92167,1.83,1.83,0.0,5443.5,5443.5,36290.0,10.0,6.35,16.35,0.117,0.3,8.17,18.17,0.15,0.334,2410
|
||||
SHFE,bu2411,bu2411,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3625.0,3597.0,3608.0,3085,66689,1.82,1.82,0.0,5412.0,5412.0,36080.0,10.0,6.37,16.37,0.118,0.302,8.18,18.18,0.151,0.336,2411
|
||||
SHFE,bu2412,bu2412,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3588.0,3572.0,3578.0,1690,19428,1.8,1.8,0.0,5367.0,5367.0,35780.0,10.0,6.4,16.4,0.119,0.306,8.2,18.2,0.153,0.339,2412
|
||||
SHFE,bu2501,bu2501,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3572.0,3560.0,3565.0,4,158,1.79,1.79,0.0,5347.5,5347.5,35650.0,10.0,6.41,16.41,0.12,0.307,8.2,18.2,0.153,0.34,2501
|
||||
SHFE,bu2502,bu2502,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3598.0,3598.0,3598.0,0,5,1.81,1.81,0.0,5397.0,5397.0,35980.0,10.0,6.38,16.38,0.118,0.303,8.19,18.19,0.152,0.337,2502
|
||||
SHFE,bu2503,bu2503,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3568.0,3562.0,3562.0,0,2190,1.79,1.79,0.0,5343.0,5343.0,35620.0,10.0,6.41,16.41,0.12,0.307,8.2,18.2,0.154,0.341,2503
|
||||
SHFE,bu2504,bu2504,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3599.0,3599.0,3599.0,0,2,1.81,1.81,0.0,5398.5,5398.5,35990.0,10.0,6.38,16.38,0.118,0.303,8.19,18.19,0.152,0.337,2504
|
||||
SHFE,bu2505,bu2505,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3589.0,3589.0,3589.0,0,6,1.81,1.81,0.0,5383.5,5383.5,35890.0,10.0,6.39,16.39,0.119,0.304,8.19,18.19,0.152,0.338,2505
|
||||
SHFE,bu2506,bu2506,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3588.0,3570.0,3577.0,3,2234,1.8,1.8,0.0,5365.5,5365.5,35770.0,10.0,6.4,16.4,0.119,0.306,8.2,18.2,0.153,0.339,2506
|
||||
SHFE,bu2509,bu2509,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3581.0,3581.0,3581.0,0,33,1.8,1.8,0.0,5371.5,5371.5,35810.0,10.0,6.39,16.39,0.119,0.305,8.2,18.2,0.153,0.339,2509
|
||||
SHFE,bu2512,bu2512,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3560.0,3550.0,3550.0,0,30,1.79,1.79,0.0,5325.0,5325.0,35500.0,10.0,6.43,16.43,0.121,0.308,8.21,18.21,0.154,0.342,2512
|
||||
SHFE,bu2603,bu2603,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3553.0,3550.0,3530.0,2,15,1.78,1.78,0.0,5295.0,5295.0,35300.0,10.0,6.45,16.45,0.122,0.311,8.22,18.22,0.155,0.344,2603
|
||||
SHFE,bu2606,bu2606,bu,石油沥青,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3566.0,3566.0,3566.0,0,5,1.8,1.8,0.0,5349.0,5349.0,35660.0,10.0,6.41,16.41,0.12,0.307,8.2,18.2,0.153,0.34,2606
|
||||
DCE,c2407,玉米2407,c,黄玉米,10,1.0,0.0,1.21,0.0,1.21,0.0,1.21,0.25,0,0.25,0,2445.0,2445.0,2445.0,0,0,1.21,1.21,1.21,6112.5,6112.5,24450.0,10.0,7.58,17.58,0.124,0.288,7.58,17.58,0.124,0.288,2407
|
||||
DCE,c2409,玉米2409,c,黄玉米,10,1.0,0.0,1.21,0.0,1.21,0.0,1.21,0.12,0,0.12,0,2424.0,2420.0,2420.0,104842,772613,1.21,1.21,1.21,2904.0,2904.0,24200.0,10.0,7.58,17.58,0.261,0.605,7.58,17.58,0.261,0.605,2409
|
||||
DCE,c2411,玉米2411,c,黄玉米,10,1.0,0.0,1.21,0.0,1.21,0.0,1.21,0.12,0,0.12,0,2343.0,2337.0,2342.0,15448,285224,1.21,1.21,1.21,2810.4,2810.4,23420.0,10.0,7.58,17.58,0.27,0.625,7.58,17.58,0.27,0.625,2411
|
||||
DCE,c2501,玉米2501,c,黄玉米,10,1.0,0.0,1.21,0.0,1.21,0.0,1.21,0.12,0,0.12,0,2335.0,2328.0,2333.0,9921,234309,1.21,1.21,1.21,2799.6,2799.6,23330.0,10.0,7.58,17.58,0.271,0.628,7.58,17.58,0.271,0.628,2501
|
||||
DCE,c2503,玉米2503,c,黄玉米,10,1.0,0.0,1.21,0.0,1.21,0.0,1.21,0.12,0,0.12,0,2341.0,2334.0,2337.0,1190,55022,1.21,1.21,1.21,2804.4,2804.4,23370.0,10.0,7.58,17.58,0.27,0.627,7.58,17.58,0.27,0.627,2503
|
||||
DCE,c2505,玉米2505,c,黄玉米,10,1.0,0.0,1.21,0.0,1.21,0.0,1.21,0.12,0,0.12,0,2388.0,2377.0,2381.0,212,6487,1.21,1.21,1.21,2857.2,2857.2,23810.0,10.0,7.58,17.58,0.265,0.615,7.58,17.58,0.265,0.615,2505
|
||||
DCE,cs2407,玉米淀粉2407,cs,玉米淀粉,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.25,0,0.25,0,2800.0,2800.0,2800.0,0,0,1.51,1.51,1.51,7000.0,7000.0,28000.0,10.0,6.98,16.98,0.1,0.243,6.98,16.98,0.1,0.243,2407
|
||||
DCE,cs2409,玉米淀粉2409,cs,玉米淀粉,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.11,0,0.11,0,2893.0,2881.0,2873.0,39962,156258,1.51,1.51,1.51,3160.3,3160.3,28730.0,10.0,6.98,16.98,0.221,0.537,6.98,16.98,0.221,0.537,2409
|
||||
DCE,cs2411,玉米淀粉2411,cs,玉米淀粉,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.11,0,0.11,0,2796.0,2788.0,2789.0,4025,47456,1.51,1.51,1.51,3067.9,3067.9,27890.0,10.0,6.98,16.98,0.227,0.553,6.98,16.98,0.227,0.553,2411
|
||||
DCE,cs2501,玉米淀粉2501,cs,玉米淀粉,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.11,0,0.11,0,2789.0,2781.0,2780.0,919,17191,1.51,1.51,1.51,3058.0,3058.0,27800.0,10.0,6.98,16.98,0.228,0.555,6.98,16.98,0.228,0.555,2501
|
||||
DCE,cs2503,玉米淀粉2503,cs,玉米淀粉,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.11,0,0.11,0,2765.0,2756.0,2759.0,645,8797,1.51,1.51,1.51,3034.9,3034.9,27590.0,10.0,6.98,16.98,0.23,0.559,6.98,16.98,0.23,0.559,2503
|
||||
DCE,cs2505,玉米淀粉2505,cs,玉米淀粉,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.11,0,0.11,0,2805.0,2800.0,2803.0,6,170,1.51,1.51,1.51,3083.3,3083.3,28030.0,10.0,6.98,16.98,0.226,0.551,6.98,16.98,0.226,0.551,2505
|
||||
SHFE,cu2407,cu2407,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.25,0,0.25,0,79580.0,79400.0,79800.0,750,26145,19.98,19.98,39.93,99750.0,99750.0,399000.0,50.0,10.03,60.03,0.01,0.06,-9.92,40.08,-0.01,0.04,2407
|
||||
SHFE,cu2408,cu2408,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.15,0,0.15,0,79870.0,79580.0,80020.0,23542,195740,20.04,20.04,40.04,60015.0,60015.0,400100.0,50.0,9.92,59.92,0.017,0.1,-10.08,39.92,-0.017,0.067,2408
|
||||
SHFE,cu2409,cu2409,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80120.0,79820.0,80250.0,19183,153288,20.1,20.1,40.16,56175.0,56175.0,401250.0,50.0,9.81,59.81,0.017,0.106,-10.26,39.74,-0.018,0.071,2409
|
||||
SHFE,cu2410,cu2410,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80300.0,80020.0,80440.0,3905,61520,20.14,20.14,40.25,56308.0,56308.0,402200.0,50.0,9.71,59.71,0.017,0.106,-10.4,39.6,-0.018,0.07,2410
|
||||
SHFE,cu2411,cu2411,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80560.0,80190.0,80660.0,1415,30605,20.2,20.2,40.36,56462.0,56462.0,403300.0,50.0,9.6,59.6,0.017,0.106,-10.56,39.44,-0.019,0.07,2411
|
||||
SHFE,cu2412,cu2412,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80670.0,80350.0,80740.0,1298,29676,20.22,20.22,40.4,56518.0,56518.0,403700.0,50.0,9.56,59.56,0.017,0.105,-10.62,39.38,-0.019,0.07,2412
|
||||
SHFE,cu2501,cu2501,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80850.0,80520.0,80880.0,272,15427,20.25,20.25,40.47,56616.0,56616.0,404400.0,50.0,9.49,59.49,0.017,0.105,-10.73,39.27,-0.019,0.069,2501
|
||||
SHFE,cu2502,cu2502,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80870.0,80610.0,80980.0,109,7311,20.28,20.28,40.52,56686.0,56686.0,404900.0,50.0,9.44,59.44,0.017,0.105,-10.8,39.2,-0.019,0.069,2502
|
||||
SHFE,cu2503,cu2503,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80830.0,80730.0,81040.0,52,5786,20.29,20.29,40.55,56728.0,56728.0,405200.0,50.0,9.41,59.41,0.017,0.105,-10.85,39.15,-0.019,0.069,2503
|
||||
SHFE,cu2504,cu2504,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80860.0,80780.0,81090.0,34,2798,20.31,20.31,40.58,56763.0,56763.0,405450.0,50.0,9.39,59.39,0.017,0.105,-10.89,39.11,-0.019,0.069,2504
|
||||
SHFE,cu2505,cu2505,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80830.0,80760.0,81150.0,123,2036,20.32,20.32,40.61,56805.0,56805.0,405750.0,50.0,9.36,59.36,0.016,0.104,-10.93,39.07,-0.019,0.069,2505
|
||||
SHFE,cu2506,cu2506,cu,铜,5,10.0,5e-05,0.01,5e-05,0.01,0.0001,0.01,0.14,0,0.14,0,80830.0,80660.0,81130.0,14,486,20.32,20.32,40.6,56791.0,56791.0,405650.0,50.0,9.37,59.37,0.016,0.105,-10.92,39.08,-0.019,0.069,2506
|
||||
DCE,eb2407,苯乙烯2407,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.26,0,0.26,0,9488.0,9511.0,9511.0,406,9807,3.01,3.01,3.01,12364.3,12364.3,47555.0,5.0,-1.03,3.97,-0.008,0.032,-1.03,3.97,-0.008,0.032,2407
|
||||
DCE,eb2408,苯乙烯2408,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,9302.0,9282.0,9368.0,134479,260744,3.01,3.01,3.01,6557.6,6557.6,46840.0,5.0,-1.03,3.97,-0.016,0.061,-1.03,3.97,-0.016,0.061,2408
|
||||
DCE,eb2409,苯乙烯2409,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,9177.0,9146.0,9227.0,40374,133545,3.01,3.01,3.01,6458.9,6458.9,46135.0,5.0,-1.03,3.97,-0.016,0.062,-1.03,3.97,-0.016,0.062,2409
|
||||
DCE,eb2410,苯乙烯2410,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,9028.0,8996.0,9075.0,9220,43152,3.01,3.01,3.01,6352.5,6352.5,45375.0,5.0,-1.03,3.97,-0.016,0.063,-1.03,3.97,-0.016,0.063,2410
|
||||
DCE,eb2411,苯乙烯2411,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,8882.0,8847.0,8943.0,5323,13712,3.01,3.01,3.01,6260.1,6260.1,44715.0,5.0,-1.03,3.97,-0.016,0.063,-1.03,3.97,-0.016,0.063,2411
|
||||
DCE,eb2412,苯乙烯2412,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,8763.0,8732.0,8826.0,3296,3404,3.01,3.01,3.01,6178.2,6178.2,44130.0,5.0,-1.03,3.97,-0.017,0.064,-1.03,3.97,-0.017,0.064,2412
|
||||
DCE,eb2501,苯乙烯2501,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,8702.0,8638.0,8742.0,436,1181,3.01,3.01,3.01,6119.4,6119.4,43710.0,5.0,-1.03,3.97,-0.017,0.065,-1.03,3.97,-0.017,0.065,2501
|
||||
DCE,eb2502,苯乙烯2502,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,8651.0,8582.0,8700.0,20,289,3.01,3.01,3.01,6090.0,6090.0,43500.0,5.0,-1.03,3.97,-0.017,0.065,-1.03,3.97,-0.017,0.065,2502
|
||||
DCE,eb2503,苯乙烯2503,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,8638.0,8519.0,8519.0,0,232,3.01,3.01,3.01,5963.3,5963.3,42595.0,5.0,-1.03,3.97,-0.017,0.067,-1.03,3.97,-0.017,0.067,2503
|
||||
DCE,eb2504,苯乙烯2504,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,8610.0,8495.0,8563.0,2,81,3.01,3.01,3.01,5994.1,5994.1,42815.0,5.0,-1.03,3.97,-0.017,0.066,-1.03,3.97,-0.017,0.066,2504
|
||||
DCE,eb2505,苯乙烯2505,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,8549.0,8484.0,8600.0,8,190,3.01,3.01,3.01,6020.0,6020.0,43000.0,5.0,-1.03,3.97,-0.017,0.066,-1.03,3.97,-0.017,0.066,2505
|
||||
DCE,eb2506,苯乙烯2506,eb,苯乙烯,5,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,8477.0,8470.0,8470.0,0,12,3.01,3.01,3.01,5929.0,5929.0,42350.0,5.0,-1.03,3.97,-0.017,0.067,-1.03,3.97,-0.017,0.067,2506
|
||||
INE,ec2408,ec2408,ec,SCFIS欧线,50,0.1,0.0006,0.01,0.0006,0.01,0.0012,0.01,0.29,0,0.29,0,5742.6,5745.3,5745.3,0,33777,172.39,172.39,344.75,83306.85,83306.85,287265.0,5.0,-339.77,-334.77,-0.408,-0.402,-512.13,-507.13,-0.615,-0.609,2408
|
||||
INE,ec2410,ec2410,ec,SCFIS欧线,50,0.1,0.0006,0.01,0.0006,0.01,0.0012,0.01,0.29,0,0.29,0,4482.0,4435.0,4435.0,0,28743,133.07,133.07,266.12,64307.5,64307.5,221750.0,5.0,-261.15,-256.15,-0.406,-0.398,-394.2,-389.2,-0.613,-0.605,2410
|
||||
INE,ec2412,ec2412,ec,SCFIS欧线,50,0.1,0.0006,0.01,0.0006,0.01,0.0012,0.01,0.29,0,0.29,0,4011.2,3927.0,3927.0,0,15311,117.83,117.83,235.64,56941.5,56941.5,196350.0,5.0,-230.66,-225.66,-0.405,-0.396,-348.47,-343.47,-0.612,-0.603,2412
|
||||
INE,ec2502,ec2502,ec,SCFIS欧线,50,0.1,0.0006,0.01,0.0006,0.01,0.0012,0.01,0.29,0,0.29,0,3262.0,3139.9,3139.9,0,9162,94.22,94.22,188.41,45528.55,45528.55,156995.0,5.0,-183.43,-178.43,-0.403,-0.392,-277.63,-272.63,-0.61,-0.599,2502
|
||||
INE,ec2504,ec2504,ec,SCFIS欧线,50,0.1,0.0006,0.01,0.0006,0.01,0.0012,0.01,0.29,0,0.29,0,2630.5,2514.9,2514.9,0,14765,75.46,75.46,150.91,36466.05,36466.05,125745.0,5.0,-145.93,-140.93,-0.4,-0.386,-221.38,-216.38,-0.607,-0.593,2504
|
||||
INE,ec2506,ec2506,ec,SCFIS欧线,50,0.1,0.0006,0.01,0.0006,0.01,0.0012,0.01,0.29,0,0.29,0,2685.6,2539.6,2539.6,0,7037,76.21,76.21,152.39,36824.2,36824.2,126980.0,5.0,-147.41,-142.41,-0.4,-0.387,-223.6,-218.6,-0.607,-0.594,2506
|
||||
DCE,eg2407,乙二醇2407,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.26,0,0.26,0,4627.0,4627.0,4627.0,0,0,3.01,3.01,3.01,12030.2,12030.2,46270.0,10.0,3.97,13.97,0.033,0.116,3.97,13.97,0.033,0.116,2407
|
||||
DCE,eg2408,乙二醇2408,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4712.0,4720.0,4747.0,140,1665,3.01,3.01,3.01,6645.8,6645.8,47470.0,10.0,3.97,13.97,0.06,0.21,3.97,13.97,0.06,0.21,2408
|
||||
DCE,eg2409,乙二醇2409,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4714.0,4723.0,4752.0,219937,454929,3.01,3.01,3.01,6652.8,6652.8,47520.0,10.0,3.97,13.97,0.06,0.21,3.97,13.97,0.06,0.21,2409
|
||||
DCE,eg2410,乙二醇2410,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4697.0,4705.0,4724.0,520,1736,3.01,3.01,3.01,6613.6,6613.6,47240.0,10.0,3.97,13.97,0.06,0.211,3.97,13.97,0.06,0.211,2410
|
||||
DCE,eg2411,乙二醇2411,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4691.0,4688.0,4718.0,25,407,3.01,3.01,3.01,6605.2,6605.2,47180.0,10.0,3.97,13.97,0.06,0.212,3.97,13.97,0.06,0.212,2411
|
||||
DCE,eg2412,乙二醇2412,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4674.0,4682.0,4704.0,17,101,3.01,3.01,3.01,6585.6,6585.6,47040.0,10.0,3.97,13.97,0.06,0.212,3.97,13.97,0.06,0.212,2412
|
||||
DCE,eg2501,乙二醇2501,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4659.0,4670.0,4687.0,12994,64922,3.01,3.01,3.01,6561.8,6561.8,46870.0,10.0,3.97,13.97,0.061,0.213,3.97,13.97,0.061,0.213,2501
|
||||
DCE,eg2502,乙二醇2502,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4666.0,4648.0,4699.0,10,252,3.01,3.01,3.01,6578.6,6578.6,46990.0,10.0,3.97,13.97,0.06,0.212,3.97,13.97,0.06,0.212,2502
|
||||
DCE,eg2503,乙二醇2503,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4683.0,4650.0,4719.0,2,661,3.01,3.01,3.01,6606.6,6606.6,47190.0,10.0,3.97,13.97,0.06,0.212,3.97,13.97,0.06,0.212,2503
|
||||
DCE,eg2504,乙二醇2504,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4677.0,4685.0,4685.0,0,8,3.01,3.01,3.01,6559.0,6559.0,46850.0,10.0,3.97,13.97,0.061,0.213,3.97,13.97,0.061,0.213,2504
|
||||
DCE,eg2505,乙二醇2505,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4656.0,4665.0,4683.0,4,36,3.01,3.01,3.01,6556.2,6556.2,46830.0,10.0,3.97,13.97,0.061,0.213,3.97,13.97,0.061,0.213,2505
|
||||
DCE,eg2506,乙二醇2506,eg,乙二醇,10,1.0,0.0,3.01,0.0,3.01,0.0,3.01,0.14,0,0.14,0,4688.0,4688.0,4690.0,2,1,3.01,3.01,3.01,6566.0,6566.0,46900.0,10.0,3.97,13.97,0.061,0.213,3.97,13.97,0.061,0.213,2506
|
||||
DCE,fb2407,纤维板2407,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.35,0,0.35,0,1262.5,1262.5,1262.5,0,0,1.27,1.27,1.27,4418.75,4418.75,12625.0,5.0,2.45,7.45,0.056,0.169,2.45,7.45,0.056,0.169,2407
|
||||
DCE,fb2408,纤维板2408,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1272.5,1272.5,1272.5,0,3,1.28,1.28,1.28,3181.25,3181.25,12725.0,5.0,2.43,7.43,0.076,0.234,2.43,7.43,0.076,0.234,2408
|
||||
DCE,fb2409,纤维板2409,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1288.5,1286.5,1286.5,0,1472,1.3,1.3,1.3,3216.25,3216.25,12865.0,5.0,2.41,7.41,0.075,0.23,2.41,7.41,0.075,0.23,2409
|
||||
DCE,fb2410,纤维板2410,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1295.0,1295.0,1295.0,0,6,1.31,1.31,1.31,3237.5,3237.5,12950.0,5.0,2.39,7.39,0.074,0.228,2.39,7.39,0.074,0.228,2410
|
||||
DCE,fb2411,纤维板2411,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1278.5,1278.5,1278.5,0,4,1.29,1.29,1.29,3196.25,3196.25,12785.0,5.0,2.42,7.42,0.076,0.232,2.42,7.42,0.076,0.232,2411
|
||||
DCE,fb2412,纤维板2412,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1280.0,1278.5,1278.5,0,13,1.29,1.29,1.29,3196.25,3196.25,12785.0,5.0,2.42,7.42,0.076,0.232,2.42,7.42,0.076,0.232,2412
|
||||
DCE,fb2501,纤维板2501,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1283.0,1283.0,1283.0,0,17,1.29,1.29,1.29,3207.5,3207.5,12830.0,5.0,2.41,7.41,0.075,0.231,2.41,7.41,0.075,0.231,2501
|
||||
DCE,fb2502,纤维板2502,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1298.5,1298.5,1298.5,0,2,1.31,1.31,1.31,3246.25,3246.25,12985.0,5.0,2.38,7.38,0.073,0.227,2.38,7.38,0.073,0.227,2502
|
||||
DCE,fb2503,纤维板2503,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1294.0,1294.0,1294.0,0,1,1.3,1.3,1.3,3235.0,3235.0,12940.0,5.0,2.39,7.39,0.074,0.228,2.39,7.39,0.074,0.228,2503
|
||||
DCE,fb2504,纤维板2504,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1290.0,1290.0,1290.0,0,1,1.3,1.3,1.3,3225.0,3225.0,12900.0,5.0,2.4,7.4,0.074,0.229,2.4,7.4,0.074,0.229,2504
|
||||
DCE,fb2505,纤维板2505,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1301.0,1300.0,1300.0,0,7,1.31,1.31,1.31,3250.0,3250.0,13000.0,5.0,2.38,7.38,0.073,0.227,2.38,7.38,0.073,0.227,2505
|
||||
DCE,fb2506,纤维板2506,fb,纤维板,10,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.25,0,0.25,0,1275.0,1275.0,1275.0,0,1,1.29,1.29,1.29,3187.5,3187.5,12750.0,5.0,2.43,7.43,0.076,0.233,2.43,7.43,0.076,0.233,2506
|
||||
SHFE,fu2408,fu2408,fu,燃料油,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.2,0,0.2,0,3751.0,3755.0,3757.0,89,890,1.89,1.89,0.0,7514.0,7514.0,37570.0,10.0,6.22,16.22,0.083,0.216,8.11,18.11,0.108,0.241,2408
|
||||
SHFE,fu2409,fu2409,fu,燃料油,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3528.0,3490.0,3510.0,150840,234353,1.77,1.77,0.0,5265.0,5265.0,35100.0,10.0,6.47,16.47,0.123,0.313,8.23,18.23,0.156,0.346,2409
|
||||
SHFE,fu2410,fu2410,fu,燃料油,10,1.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.15,0,0.15,0,3461.0,3425.0,3447.0,2689,9759,0.36,0.36,0.0,5170.5,5170.5,34470.0,10.0,9.29,19.29,0.18,0.373,9.64,19.64,0.186,0.38,2410
|
||||
SHFE,fu2411,fu2411,fu,燃料油,10,1.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.15,0,0.15,0,3402.0,3367.0,3384.0,24879,153916,0.35,0.35,0.0,5076.0,5076.0,33840.0,10.0,9.3,19.3,0.183,0.38,9.65,19.65,0.19,0.387,2411
|
||||
SHFE,fu2412,fu2412,fu,燃料油,10,1.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.15,0,0.15,0,3373.0,3340.0,3352.0,1139,35837,0.35,0.35,0.0,5028.0,5028.0,33520.0,10.0,9.31,19.31,0.185,0.384,9.65,19.65,0.192,0.391,2412
|
||||
SHFE,fu2501,fu2501,fu,燃料油,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3354.0,3308.0,3324.0,11273,76964,1.67,1.67,0.0,4986.0,4986.0,33240.0,10.0,6.65,16.65,0.133,0.334,8.32,18.32,0.167,0.368,2501
|
||||
SHFE,fu2502,fu2502,fu,燃料油,10,1.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.15,0,0.15,0,3309.0,3288.0,3303.0,111,18835,0.34,0.34,0.0,4954.5,4954.5,33030.0,10.0,9.32,19.32,0.188,0.39,9.66,19.66,0.195,0.397,2502
|
||||
SHFE,fu2503,fu2503,fu,燃料油,10,1.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.15,0,0.15,0,3293.0,3271.0,3284.0,60,6528,0.34,0.34,0.0,4926.0,4926.0,32840.0,10.0,9.32,19.32,0.189,0.392,9.66,19.66,0.196,0.399,2503
|
||||
SHFE,fu2504,fu2504,fu,燃料油,10,1.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.15,0,0.15,0,3287.0,3255.0,3271.0,46,349,0.34,0.34,0.0,4906.5,4906.5,32710.0,10.0,9.32,19.32,0.19,0.394,9.66,19.66,0.197,0.401,2504
|
||||
SHFE,fu2505,fu2505,fu,燃料油,10,1.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,3283.0,3242.0,3254.0,179,6345,1.64,1.64,0.0,4881.0,4881.0,32540.0,10.0,6.72,16.72,0.138,0.343,8.36,18.36,0.171,0.376,2505
|
||||
SHFE,fu2506,fu2506,fu,燃料油,10,1.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.15,0,0.15,0,3260.0,3231.0,3243.0,11,343,0.34,0.34,0.0,4864.5,4864.5,32430.0,10.0,9.33,19.33,0.192,0.397,9.66,19.66,0.199,0.404,2506
|
||||
SHFE,fu2507,fu2507,fu,燃料油,10,1.0,1e-05,0.01,1e-05,0.01,0.0,0.0,0.15,0,0.15,0,3254.0,3218.0,3230.0,2,141,0.33,0.33,0.0,4845.0,4845.0,32300.0,10.0,9.33,19.33,0.193,0.399,9.66,19.66,0.199,0.406,2507
|
||||
SHFE,hc2407,hc2407,hc,热轧卷板,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.26,0,0.26,0,3700.0,3700.0,3700.0,0,1800,3.71,3.71,3.71,9620.0,9620.0,37000.0,10.0,2.58,12.58,0.027,0.131,2.58,12.58,0.027,0.131,2407
|
||||
SHFE,hc2408,hc2408,hc,热轧卷板,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.16,0,0.16,0,3700.0,3692.0,3692.0,0,533,3.7,3.7,3.7,5907.2,5907.2,36920.0,10.0,2.59,12.59,0.044,0.213,2.59,12.59,0.044,0.213,2408
|
||||
SHFE,hc2409,hc2409,hc,热轧卷板,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,3681.0,3673.0,3682.0,108,6403,3.69,3.69,3.69,4786.6,4786.6,36820.0,10.0,2.61,12.61,0.055,0.263,2.61,12.61,0.055,0.263,2409
|
||||
SHFE,hc2410,hc2410,hc,热轧卷板,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,3694.0,3681.0,3693.0,82480,1066901,3.71,3.71,3.71,4800.9,4800.9,36930.0,10.0,2.59,12.59,0.054,0.262,2.59,12.59,0.054,0.262,2410
|
||||
SHFE,hc2411,hc2411,hc,热轧卷板,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3700.0,3685.0,3698.0,8285,184930,0.75,0.75,0.75,4807.4,4807.4,36980.0,10.0,8.5,18.5,0.177,0.385,8.5,18.5,0.177,0.385,2411
|
||||
SHFE,hc2412,hc2412,hc,热轧卷板,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3707.0,3703.0,3709.0,205,544,0.75,0.75,0.75,4821.7,4821.7,37090.0,10.0,8.49,18.49,0.176,0.384,8.49,18.49,0.176,0.384,2412
|
||||
SHFE,hc2501,hc2501,hc,热轧卷板,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,3718.0,3705.0,3717.0,6681,222195,3.73,3.73,3.73,4832.1,4832.1,37170.0,10.0,2.54,12.54,0.053,0.26,2.54,12.54,0.053,0.26,2501
|
||||
SHFE,hc2502,hc2502,hc,热轧卷板,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3727.0,3721.0,3727.0,3,391,0.76,0.76,0.76,4845.1,4845.1,37270.0,10.0,8.48,18.48,0.175,0.382,8.48,18.48,0.175,0.382,2502
|
||||
SHFE,hc2503,hc2503,hc,热轧卷板,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3732.0,3723.0,3726.0,33,1429,0.76,0.76,0.76,4843.8,4843.8,37260.0,10.0,8.49,18.49,0.175,0.382,8.49,18.49,0.175,0.382,2503
|
||||
SHFE,hc2504,hc2504,hc,热轧卷板,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3733.0,3727.0,3727.0,0,169,0.76,0.76,0.76,4845.1,4845.1,37270.0,10.0,8.48,18.48,0.175,0.382,8.48,18.48,0.175,0.382,2504
|
||||
SHFE,hc2505,hc2505,hc,热轧卷板,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,3746.0,3729.0,3743.0,146,10920,3.76,3.76,3.76,4865.9,4865.9,37430.0,10.0,2.49,12.49,0.051,0.257,2.49,12.49,0.051,0.257,2505
|
||||
SHFE,hc2506,hc2506,hc,热轧卷板,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3736.0,3731.0,3734.0,5,31,0.76,0.76,0.76,4854.2,4854.2,37340.0,10.0,8.48,18.48,0.175,0.381,8.48,18.48,0.175,0.381,2506
|
||||
DCE,i2407,铁矿石2407,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.26,0,0.26,0,874.0,874.0,874.0,0,200,8.76,8.76,8.76,22724.0,22724.0,87400.0,50.0,32.49,82.49,0.143,0.363,32.49,82.49,0.143,0.363,2407
|
||||
DCE,i2408,铁矿石2408,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,828.0,821.0,826.0,2103,14327,8.27,8.27,8.27,17346.0,17346.0,82600.0,50.0,33.45,83.45,0.193,0.481,33.45,83.45,0.193,0.481,2408
|
||||
DCE,i2409,铁矿石2409,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,821.5,813.0,818.5,73026,342520,8.2,8.2,8.2,17188.5,17188.5,81850.0,50.0,33.6,83.6,0.195,0.486,33.6,83.6,0.195,0.486,2409
|
||||
DCE,i2410,铁矿石2410,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,817.0,807.5,814.0,2576,60230,8.15,8.15,8.15,17094.0,17094.0,81400.0,50.0,33.69,83.69,0.197,0.49,33.69,83.69,0.197,0.49,2410
|
||||
DCE,i2411,铁矿石2411,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,812.0,804.5,810.0,1324,28941,8.11,8.11,8.11,17010.0,17010.0,81000.0,50.0,33.77,83.77,0.199,0.492,33.77,83.77,0.199,0.492,2411
|
||||
DCE,i2412,铁矿石2412,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,810.0,800.5,807.0,615,14012,8.08,8.08,8.08,16947.0,16947.0,80700.0,50.0,33.83,83.83,0.2,0.495,33.83,83.83,0.2,0.495,2412
|
||||
DCE,i2501,铁矿石2501,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,804.0,795.5,801.5,23094,226078,8.03,8.03,8.03,16831.5,16831.5,80150.0,50.0,33.94,83.94,0.202,0.499,33.94,83.94,0.202,0.499,2501
|
||||
DCE,i2502,铁矿石2502,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,801.5,794.5,800.0,110,10864,8.01,8.01,8.01,16800.0,16800.0,80000.0,50.0,33.97,83.97,0.202,0.5,33.97,83.97,0.202,0.5,2502
|
||||
DCE,i2503,铁矿石2503,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,799.5,793.5,799.0,237,5674,8.0,8.0,8.0,16779.0,16779.0,79900.0,50.0,33.99,83.99,0.203,0.501,33.99,83.99,0.203,0.501,2503
|
||||
DCE,i2504,铁矿石2504,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,799.0,792.0,797.5,43,908,7.99,7.99,7.99,16747.5,16747.5,79750.0,50.0,34.02,84.02,0.203,0.502,34.02,84.02,0.203,0.502,2504
|
||||
DCE,i2505,铁矿石2505,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,794.5,787.0,792.0,1734,41648,7.93,7.93,7.93,16632.0,16632.0,79200.0,50.0,34.13,84.13,0.205,0.506,34.13,84.13,0.205,0.506,2505
|
||||
DCE,i2506,铁矿石2506,i,铁矿石,100,0.5,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.21,0,0.21,0,791.5,784.0,789.5,17,326,7.91,7.91,7.91,16579.5,16579.5,78950.0,50.0,34.18,84.18,0.206,0.508,34.18,84.18,0.206,0.508,2506
|
||||
DCE,j2407,焦炭2407,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2007.0,2007.0,2007.0,0,0,28.12,20.09,28.12,50175.0,50175.0,200700.0,50.0,1.79,51.79,0.004,0.103,-6.24,43.76,-0.012,0.087,2407
|
||||
DCE,j2408,焦炭2408,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2204.5,2198.0,2198.0,0,26,30.8,22.0,30.8,54950.0,54950.0,219800.0,50.0,-2.8,47.2,-0.005,0.086,-11.59,38.41,-0.021,0.07,2408
|
||||
DCE,j2409,焦炭2409,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2221.5,2215.0,2221.5,3896,26666,31.12,22.24,31.12,55537.5,55537.5,222150.0,50.0,-3.36,46.64,-0.006,0.084,-12.25,37.75,-0.022,0.068,2409
|
||||
DCE,j2410,焦炭2410,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2266.5,2266.5,2252.0,2,21,31.55,22.54,31.55,56300.0,56300.0,225200.0,50.0,-4.1,45.9,-0.007,0.082,-13.1,36.9,-0.023,0.066,2410
|
||||
DCE,j2411,焦炭2411,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2269.5,2269.5,2269.5,0,1,31.8,22.72,31.8,56737.5,56737.5,226950.0,50.0,-4.52,45.48,-0.008,0.08,-13.59,36.41,-0.024,0.064,2411
|
||||
DCE,j2412,焦炭2412,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2326.0,2326.0,2326.0,0,3,32.59,23.28,32.59,58150.0,58150.0,232600.0,50.0,-5.87,44.13,-0.01,0.076,-15.18,34.82,-0.026,0.06,2412
|
||||
DCE,j2501,焦炭2501,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2307.5,2306.0,2313.0,215,4304,32.41,23.15,32.41,57825.0,57825.0,231300.0,50.0,-5.56,44.44,-0.01,0.077,-14.81,35.19,-0.026,0.061,2501
|
||||
DCE,j2502,焦炭2502,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2297.0,2297.0,2297.0,0,3,32.18,22.99,32.18,57425.0,57425.0,229700.0,50.0,-5.18,44.82,-0.009,0.078,-14.36,35.64,-0.025,0.062,2502
|
||||
DCE,j2503,焦炭2503,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2324.0,2324.0,2324.0,0,1,32.56,23.26,32.56,58100.0,58100.0,232400.0,50.0,-5.82,44.18,-0.01,0.076,-15.12,34.88,-0.026,0.06,2503
|
||||
DCE,j2504,焦炭2504,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2310.5,2310.5,2310.5,0,0,32.37,23.13,32.37,57762.5,57762.5,231050.0,50.0,-5.5,44.5,-0.01,0.077,-14.74,35.26,-0.026,0.061,2504
|
||||
DCE,j2505,焦炭2505,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2315.5,2318.0,2318.0,0,60,32.48,23.2,32.48,57950.0,57950.0,231800.0,50.0,-5.68,44.32,-0.01,0.076,-14.95,35.05,-0.026,0.06,2505
|
||||
DCE,j2506,焦炭2506,j,冶金焦炭,100,0.5,0.00014,0.01,0.0001,0.01,0.00014,0.01,0.25,0,0.25,0,2285.0,2285.0,2285.0,0,1,32.01,22.87,32.01,57125.0,57125.0,228500.0,50.0,-4.89,45.11,-0.009,0.079,-14.03,35.97,-0.025,0.063,2506
|
||||
DCE,jd2407,鸡蛋2407,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.26,0,0.26,0,4179.0,4150.0,4150.0,0,12,6.24,6.24,6.24,10790.0,10790.0,41500.0,10.0,-2.47,7.53,-0.023,0.07,-2.47,7.53,-0.023,0.07,2407
|
||||
DCE,jd2408,鸡蛋2408,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,4448.0,4447.0,4447.0,0,23090,6.68,6.68,6.68,5781.1,5781.1,44470.0,10.0,-3.37,6.63,-0.058,0.115,-3.37,6.63,-0.058,0.115,2408
|
||||
DCE,jd2409,鸡蛋2409,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,4056.0,4062.0,4062.0,0,178656,6.11,6.11,6.11,5280.6,5280.6,40620.0,10.0,-2.21,7.79,-0.042,0.148,-2.21,7.79,-0.042,0.148,2409
|
||||
DCE,jd2410,鸡蛋2410,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,3865.0,3853.0,3853.0,0,43282,5.79,5.79,5.79,5008.9,5008.9,38530.0,10.0,-1.58,8.42,-0.032,0.168,-1.58,8.42,-0.032,0.168,2410
|
||||
DCE,jd2411,鸡蛋2411,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,3983.0,3977.0,3977.0,0,25590,5.98,5.98,5.98,5170.1,5170.1,39770.0,10.0,-1.96,8.04,-0.038,0.156,-1.96,8.04,-0.038,0.156,2411
|
||||
DCE,jd2412,鸡蛋2412,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,4119.0,4113.0,4113.0,0,15118,6.18,6.18,6.18,5346.9,5346.9,41130.0,10.0,-2.36,7.64,-0.044,0.143,-2.36,7.64,-0.044,0.143,2412
|
||||
DCE,jd2501,鸡蛋2501,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,3763.0,3746.0,3746.0,0,34713,5.63,5.63,5.63,4869.8,4869.8,37460.0,10.0,-1.26,8.74,-0.026,0.179,-1.26,8.74,-0.026,0.179,2501
|
||||
DCE,jd2502,鸡蛋2502,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,3484.0,3468.0,3468.0,0,8619,5.21,5.21,5.21,4508.4,4508.4,34680.0,10.0,-0.43,9.57,-0.009,0.212,-0.43,9.57,-0.009,0.212,2502
|
||||
DCE,jd2503,鸡蛋2503,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,3504.0,3493.0,3493.0,0,1856,5.25,5.25,5.25,4540.9,4540.9,34930.0,10.0,-0.5,9.5,-0.011,0.209,-0.5,9.5,-0.011,0.209,2503
|
||||
DCE,jd2504,鸡蛋2504,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,3635.0,3626.0,3626.0,0,1031,5.45,5.45,5.45,4713.8,4713.8,36260.0,10.0,-0.9,9.1,-0.019,0.193,-0.9,9.1,-0.019,0.193,2504
|
||||
DCE,jd2505,鸡蛋2505,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,3653.0,3648.0,3648.0,0,2180,5.48,5.48,5.48,4742.4,4742.4,36480.0,10.0,-0.97,9.03,-0.02,0.19,-0.97,9.03,-0.02,0.19,2505
|
||||
DCE,jd2506,鸡蛋2506,jd,鸡蛋,10,1.0,0.00015,0.01,0.00015,0.01,0.00015,0.01,0.13,0,0.13,0,3477.0,3460.0,3460.0,0,1042,5.2,5.2,5.2,4498.0,4498.0,34600.0,10.0,-0.4,9.6,-0.009,0.213,-0.4,9.6,-0.009,0.213,2506
|
||||
DCE,jm2407,焦煤2407,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1506.0,1506.0,1506.0,0,0,27.12,9.05,27.12,22590.0,22590.0,90360.0,30.0,-6.17,23.83,-0.027,0.105,-24.25,5.75,-0.107,0.025,2407
|
||||
DCE,jm2408,焦煤2408,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1552.5,1550.5,1554.5,31,66,28.0,9.34,28.0,23317.5,23317.5,93270.0,30.0,-7.34,22.66,-0.031,0.097,-25.99,4.01,-0.111,0.017,2408
|
||||
DCE,jm2409,焦煤2409,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1543.5,1531.0,1542.5,25008,160242,27.78,9.27,27.78,23137.5,23137.5,92550.0,30.0,-7.05,22.95,-0.03,0.099,-25.56,4.44,-0.11,0.019,2409
|
||||
DCE,jm2410,焦煤2410,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1583.5,1582.0,1596.0,82,59,28.74,9.59,28.74,23940.0,23940.0,95760.0,30.0,-8.34,21.66,-0.035,0.09,-27.49,2.51,-0.115,0.01,2410
|
||||
DCE,jm2411,焦煤2411,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1678.0,1668.0,1668.0,0,19,30.04,10.02,30.04,25020.0,25020.0,100080.0,30.0,-10.06,19.94,-0.04,0.08,-30.08,-0.08,-0.12,-0.0,2411
|
||||
DCE,jm2412,焦煤2412,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1664.0,1659.0,1676.0,1,93,30.18,10.07,30.18,25140.0,25140.0,100560.0,30.0,-10.26,19.74,-0.041,0.079,-30.37,-0.37,-0.121,-0.001,2412
|
||||
DCE,jm2501,焦煤2501,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1691.5,1683.0,1691.5,1351,25783,30.46,10.17,30.46,25372.5,25372.5,101490.0,30.0,-10.63,19.37,-0.042,0.076,-30.93,-0.93,-0.122,-0.004,2501
|
||||
DCE,jm2502,焦煤2502,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1737.5,1720.5,1720.5,0,4,30.99,10.34,30.99,25807.5,25807.5,103230.0,30.0,-11.32,18.68,-0.044,0.072,-31.97,-1.97,-0.124,-0.008,2502
|
||||
DCE,jm2503,焦煤2503,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1717.0,1717.0,1717.0,0,21,30.92,10.32,30.92,25755.0,25755.0,103020.0,30.0,-11.24,18.76,-0.044,0.073,-31.84,-1.84,-0.124,-0.007,2503
|
||||
DCE,jm2504,焦煤2504,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1749.0,1749.0,1749.0,0,8,31.5,10.51,31.5,26235.0,26235.0,104940.0,30.0,-12.01,17.99,-0.046,0.069,-33.0,-3.0,-0.126,-0.011,2504
|
||||
DCE,jm2505,焦煤2505,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1723.0,1697.0,1710.0,2,740,30.8,10.28,30.8,25650.0,25650.0,102600.0,30.0,-11.07,18.93,-0.043,0.074,-31.59,-1.59,-0.123,-0.006,2505
|
||||
DCE,jm2506,焦煤2506,jm,焦煤,60,0.5,0.0003,0.01,0.0001,0.01,0.0003,0.01,0.25,0,0.25,0,1726.5,1726.5,1726.5,0,1,31.09,10.38,31.09,25897.5,25897.5,103590.0,30.0,-11.47,18.53,-0.044,0.072,-32.19,-2.19,-0.124,-0.008,2506
|
||||
DCE,l2407,聚乙烯2407,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.26,0,0.26,0,8369.0,8369.0,8369.0,0,257,1.01,1.01,1.01,10879.7,10879.7,41845.0,5.0,2.97,7.97,0.027,0.073,2.97,7.97,0.027,0.073,2407
|
||||
DCE,l2408,聚乙烯2408,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8382.0,8353.0,8371.0,86,1354,1.01,1.01,1.01,5441.15,5441.15,41855.0,5.0,2.97,7.97,0.055,0.147,2.97,7.97,0.055,0.147,2408
|
||||
DCE,l2409,聚乙烯2409,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8413.0,8385.0,8402.0,75480,403404,1.01,1.01,1.01,5461.3,5461.3,42010.0,5.0,2.97,7.97,0.054,0.146,2.97,7.97,0.054,0.146,2409
|
||||
DCE,l2410,聚乙烯2410,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8397.0,8378.0,8398.0,49,1239,1.01,1.01,1.01,5458.7,5458.7,41990.0,5.0,2.97,7.97,0.054,0.146,2.97,7.97,0.054,0.146,2410
|
||||
DCE,l2411,聚乙烯2411,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8434.0,8405.0,8426.0,2,60,1.01,1.01,1.01,5476.9,5476.9,42130.0,5.0,2.97,7.97,0.054,0.146,2.97,7.97,0.054,0.146,2411
|
||||
DCE,l2412,聚乙烯2412,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8448.0,8410.0,8433.0,2,56,1.01,1.01,1.01,5481.45,5481.45,42165.0,5.0,2.97,7.97,0.054,0.145,2.97,7.97,0.054,0.145,2412
|
||||
DCE,l2501,聚乙烯2501,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8420.0,8398.0,8417.0,6787,66796,1.01,1.01,1.01,5471.05,5471.05,42085.0,5.0,2.97,7.97,0.054,0.146,2.97,7.97,0.054,0.146,2501
|
||||
DCE,l2502,聚乙烯2502,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8413.0,8395.0,8404.0,3,71,1.01,1.01,1.01,5462.6,5462.6,42020.0,5.0,2.97,7.97,0.054,0.146,2.97,7.97,0.054,0.146,2502
|
||||
DCE,l2503,聚乙烯2503,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8424.0,8400.0,8395.0,4,100,1.01,1.01,1.01,5456.75,5456.75,41975.0,5.0,2.97,7.97,0.055,0.146,2.97,7.97,0.055,0.146,2503
|
||||
DCE,l2504,聚乙烯2504,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8464.0,8460.0,8460.0,0,36,1.01,1.01,1.01,5499.0,5499.0,42300.0,5.0,2.97,7.97,0.054,0.145,2.97,7.97,0.054,0.145,2504
|
||||
DCE,l2505,聚乙烯2505,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8399.0,8381.0,8382.0,103,575,1.01,1.01,1.01,5448.3,5448.3,41910.0,5.0,2.97,7.97,0.055,0.146,2.97,7.97,0.055,0.146,2505
|
||||
DCE,l2506,聚乙烯2506,l,线型低密度聚乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,8454.0,8454.0,8454.0,0,4,1.01,1.01,1.01,5495.1,5495.1,42270.0,5.0,2.97,7.97,0.054,0.145,2.97,7.97,0.054,0.145,2506
|
||||
GFEX,lc2407,碳酸锂2407,lc,碳酸锂,1,50.0,0.00016,0.01,0.00016,0.01,0.00016,0.01,0.28,0,0.28,0,87750.0,86800.0,0.0,0,342,13.9,13.9,13.9,24304.0,24304.0,86800.0,50.0,22.19,72.19,0.091,0.297,22.19,72.19,0.091,0.297,2407
|
||||
GFEX,lc2408,碳酸锂2408,lc,碳酸锂,1,50.0,0.00016,0.01,0.00016,0.01,0.00016,0.01,0.2,0,0.2,0,91250.0,89900.0,0.0,0,56355,14.4,14.4,14.4,17980.0,17980.0,89900.0,50.0,21.2,71.2,0.118,0.396,21.2,71.2,0.118,0.396,2408
|
||||
GFEX,lc2409,碳酸锂2409,lc,碳酸锂,1,50.0,0.00016,0.01,0.00016,0.01,0.00016,0.01,0.2,0,0.2,0,91850.0,90600.0,0.0,0,27745,14.51,14.51,14.51,18120.0,18120.0,90600.0,50.0,20.98,70.98,0.116,0.392,20.98,70.98,0.116,0.392,2409
|
||||
GFEX,lc2410,碳酸锂2410,lc,碳酸锂,1,50.0,0.00016,0.01,0.00016,0.01,0.00016,0.01,0.2,0,0.2,0,92350.0,91200.0,0.0,0,10064,14.61,14.61,14.61,18240.0,18240.0,91200.0,50.0,20.79,70.79,0.114,0.388,20.79,70.79,0.114,0.388,2410
|
||||
GFEX,lc2411,碳酸锂2411,lc,碳酸锂,1,50.0,0.00016,0.01,0.00016,0.01,0.00016,0.01,0.2,0,0.2,0,93100.0,91800.0,0.0,0,176216,14.7,14.7,14.7,18360.0,18360.0,91800.0,50.0,20.59,70.59,0.112,0.384,20.59,70.59,0.112,0.384,2411
|
||||
GFEX,lc2412,碳酸锂2412,lc,碳酸锂,1,50.0,8e-05,0.01,8e-05,0.01,0.0,0.0,0.2,0,0.2,0,95600.0,94650.0,0.0,0,15109,7.59,7.59,0.01,18930.0,18930.0,94650.0,50.0,34.82,84.82,0.184,0.448,42.41,92.41,0.224,0.488,2412
|
||||
GFEX,lc2501,碳酸锂2501,lc,碳酸锂,1,50.0,8e-05,0.01,8e-05,0.01,0.0,0.0,0.2,0,0.2,0,96400.0,95350.0,0.0,0,21099,7.64,7.64,0.01,19070.0,19070.0,95350.0,50.0,34.71,84.71,0.182,0.444,42.35,92.35,0.222,0.484,2501
|
||||
GFEX,lc2502,碳酸锂2502,lc,碳酸锂,1,50.0,8e-05,0.01,8e-05,0.01,0.0,0.0,0.2,0,0.2,0,96900.0,95600.0,0.0,0,2263,7.66,7.66,0.01,19120.0,19120.0,95600.0,50.0,34.67,84.67,0.181,0.443,42.33,92.33,0.221,0.483,2502
|
||||
GFEX,lc2503,碳酸锂2503,lc,碳酸锂,1,50.0,8e-05,0.01,8e-05,0.01,0.0,0.0,0.2,0,0.2,0,96600.0,96000.0,0.0,0,1451,7.7,7.7,0.01,19200.0,19200.0,96000.0,50.0,34.61,84.61,0.18,0.441,42.3,92.3,0.22,0.481,2503
|
||||
GFEX,lc2504,碳酸锂2504,lc,碳酸锂,1,50.0,8e-05,0.01,8e-05,0.01,0.0,0.0,0.2,0,0.2,0,98100.0,97550.0,0.0,0,1286,7.82,7.82,0.01,19510.0,19510.0,97550.0,50.0,34.36,84.36,0.176,0.432,42.17,92.17,0.216,0.472,2504
|
||||
GFEX,lc2505,碳酸锂2505,lc,碳酸锂,1,50.0,8e-05,0.01,8e-05,0.01,0.0,0.0,0.2,0,0.2,0,98800.0,98000.0,0.0,0,2321,7.86,7.86,0.01,19600.0,19600.0,98000.0,50.0,34.29,84.29,0.175,0.43,42.14,92.14,0.215,0.47,2505
|
||||
GFEX,lc2506,碳酸锂2506,lc,碳酸锂,1,50.0,8e-05,0.01,8e-05,0.01,0.0,0.0,0.2,0,0.2,0,99700.0,98300.0,0.0,0,881,7.88,7.88,0.01,19660.0,19660.0,98300.0,50.0,34.24,84.24,0.174,0.428,42.11,92.11,0.214,0.469,2506
|
||||
DCE,lh2407,生猪2407,lh,生猪,16,5.0,0.0002,0.01,0.0001,0.01,0.0002,0.01,0.26,0,0.26,0,17670.0,17530.0,17530.0,0,74,56.12,28.07,56.12,72924.8,72924.8,280480.0,80.0,-4.2,75.8,-0.006,0.104,-32.25,47.75,-0.044,0.065,2407
|
||||
DCE,lh2409,生猪2409,lh,生猪,16,5.0,0.0002,0.01,0.0001,0.01,0.0002,0.01,0.14,0,0.14,0,17760.0,17510.0,17510.0,0,63950,56.06,28.04,56.06,39222.4,39222.4,280160.0,80.0,-4.1,75.9,-0.01,0.194,-32.12,47.88,-0.082,0.122,2409
|
||||
DCE,lh2411,生猪2411,lh,生猪,16,5.0,0.0002,0.01,0.0001,0.01,0.0002,0.01,0.14,0,0.14,0,17755.0,17670.0,17670.0,0,56259,56.57,28.3,56.57,39580.8,39580.8,282720.0,80.0,-4.87,75.13,-0.012,0.19,-33.14,46.86,-0.084,0.118,2411
|
||||
DCE,lh2501,生猪2501,lh,生猪,16,5.0,0.0002,0.01,0.0001,0.01,0.0002,0.01,0.14,0,0.14,0,16755.0,16710.0,16710.0,0,29204,53.5,26.76,53.5,37430.4,37430.4,267360.0,80.0,-0.26,79.74,-0.001,0.213,-27.0,53.0,-0.072,0.142,2501
|
||||
DCE,lh2503,生猪2503,lh,生猪,16,5.0,0.0002,0.01,0.0001,0.01,0.0002,0.01,0.14,0,0.14,0,15380.0,15290.0,15290.0,0,16024,48.95,24.49,48.95,34249.6,34249.6,244640.0,80.0,6.56,86.56,0.019,0.253,-17.91,62.09,-0.052,0.181,2503
|
||||
DCE,lh2505,生猪2505,lh,生猪,16,5.0,0.0002,0.01,0.0001,0.01,0.0002,0.01,0.14,0,0.14,0,15580.0,15550.0,15550.0,0,2270,49.78,24.9,49.78,34832.0,34832.0,248800.0,80.0,5.31,85.31,0.015,0.245,-19.57,60.43,-0.056,0.173,2505
|
||||
INE,lu2408,lu2408,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4318.0,4292.0,4320.0,462,4851,0.44,0.44,0.44,6480.0,6480.0,43200.0,10.0,9.11,19.11,0.141,0.295,9.11,19.11,0.141,0.295,2408
|
||||
INE,lu2409,lu2409,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4329.0,4294.0,4319.0,24117,63427,0.44,0.44,0.44,6478.5,6478.5,43190.0,10.0,9.11,19.11,0.141,0.295,9.11,19.11,0.141,0.295,2409
|
||||
INE,lu2410,lu2410,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4320.0,4285.0,4309.0,8933,65899,0.44,0.44,0.44,6463.5,6463.5,43090.0,10.0,9.11,19.11,0.141,0.296,9.11,19.11,0.141,0.296,2410
|
||||
INE,lu2411,lu2411,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4304.0,4271.0,4288.0,36,2834,0.44,0.44,0.44,6432.0,6432.0,42880.0,10.0,9.12,19.12,0.142,0.297,9.12,19.12,0.142,0.297,2411
|
||||
INE,lu2412,lu2412,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4272.0,4249.0,4272.0,1,1605,0.44,0.44,0.44,6408.0,6408.0,42720.0,10.0,9.12,19.12,0.142,0.298,9.12,19.12,0.142,0.298,2412
|
||||
INE,lu2501,lu2501,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4251.0,4232.0,4245.0,5,337,0.44,0.44,0.44,6367.5,6367.5,42450.0,10.0,9.13,19.13,0.143,0.3,9.13,19.13,0.143,0.3,2501
|
||||
INE,lu2502,lu2502,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4221.0,4208.0,4230.0,3,1764,0.44,0.44,0.44,6345.0,6345.0,42300.0,10.0,9.13,19.13,0.144,0.301,9.13,19.13,0.144,0.301,2502
|
||||
INE,lu2503,lu2503,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4206.0,4186.0,4186.0,0,188,0.43,0.43,0.43,6279.0,6279.0,41860.0,10.0,9.14,19.14,0.146,0.305,9.14,19.14,0.146,0.305,2503
|
||||
INE,lu2504,lu2504,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4226.0,4226.0,4226.0,0,29,0.44,0.44,0.44,6339.0,6339.0,42260.0,10.0,9.13,19.13,0.144,0.302,9.13,19.13,0.144,0.302,2504
|
||||
INE,lu2505,lu2505,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4157.0,4156.0,4156.0,0,410,0.43,0.43,0.43,6234.0,6234.0,41560.0,10.0,9.14,19.14,0.147,0.307,9.14,19.14,0.147,0.307,2505
|
||||
INE,lu2506,lu2506,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4182.0,4182.0,4182.0,0,18,0.43,0.43,0.43,6273.0,6273.0,41820.0,10.0,9.14,19.14,0.146,0.305,9.14,19.14,0.146,0.305,2506
|
||||
INE,lu2507,lu2507,lu,低硫燃料油,10,1.0,1e-05,0.01,1e-05,0.01,1e-05,0.01,0.15,0,0.15,0,4251.0,4251.0,4251.0,0,15,0.44,0.44,0.44,6376.5,6376.5,42510.0,10.0,9.12,19.12,0.143,0.3,9.12,19.12,0.143,0.3,2507
|
||||
DCE,m2407,豆粕2407,m,豆粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.26,0,0.26,0,3082.0,3024.0,3024.0,0,4250,1.51,1.51,1.51,7862.4,7862.4,30240.0,10.0,6.98,16.98,0.089,0.216,6.98,16.98,0.089,0.216,2407
|
||||
DCE,m2408,豆粕2408,m,豆粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,3203.0,3201.0,3210.0,5327,56153,1.51,1.51,1.51,4173.0,4173.0,32100.0,10.0,6.98,16.98,0.167,0.407,6.98,16.98,0.167,0.407,2408
|
||||
DCE,m2409,豆粕2409,m,豆粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,3230.0,3225.0,3231.0,253652,1582210,1.51,1.51,1.51,4200.3,4200.3,32310.0,10.0,6.98,16.98,0.166,0.404,6.98,16.98,0.166,0.404,2409
|
||||
DCE,m2411,豆粕2411,m,豆粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,3253.0,3250.0,3256.0,16633,427507,1.51,1.51,1.51,4232.8,4232.8,32560.0,10.0,6.98,16.98,0.165,0.401,6.98,16.98,0.165,0.401,2411
|
||||
DCE,m2412,豆粕2412,m,豆粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,3307.0,3296.0,3299.0,2336,47907,1.51,1.51,1.51,4288.7,4288.7,32990.0,10.0,6.98,16.98,0.163,0.396,6.98,16.98,0.163,0.396,2412
|
||||
DCE,m2501,豆粕2501,m,豆粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,3284.0,3282.0,3287.0,68136,724952,1.51,1.51,1.51,4273.1,4273.1,32870.0,10.0,6.98,16.98,0.163,0.397,6.98,16.98,0.163,0.397,2501
|
||||
DCE,m2503,豆粕2503,m,豆粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,3114.0,3108.0,3116.0,2252,51599,1.51,1.51,1.51,4050.8,4050.8,31160.0,10.0,6.98,16.98,0.172,0.419,6.98,16.98,0.172,0.419,2503
|
||||
DCE,m2505,豆粕2505,m,豆粕,10,1.0,0.0,1.51,0.0,1.51,0.0,1.51,0.13,0,0.13,0,3038.0,3023.0,3034.0,21708,480828,1.51,1.51,1.51,3944.2,3944.2,30340.0,10.0,6.98,16.98,0.177,0.43,6.98,16.98,0.177,0.43,2505
|
||||
SHFE,ni2407,ni2407,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,9.01,0.25,0,0.25,0,135610.0,133000.0,133500.0,480,5010,3.02,3.02,9.02,33375.0,33375.0,133500.0,10.0,3.96,13.96,0.012,0.042,-2.04,7.96,-0.006,0.024,2407
|
||||
SHFE,ni2408,ni2408,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,9.01,0.17,0,0.17,0,134830.0,133430.0,133930.0,4011,26904,3.02,3.02,9.02,22768.1,22768.1,133930.0,10.0,3.96,13.96,0.017,0.061,-2.04,7.96,-0.009,0.035,2408
|
||||
SHFE,ni2409,ni2409,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,9.01,0.17,0,0.17,0,135270.0,133740.0,134260.0,39889,120494,3.02,3.02,9.02,22824.2,22824.2,134260.0,10.0,3.96,13.96,0.017,0.061,-2.04,7.96,-0.009,0.035,2409
|
||||
SHFE,ni2410,ni2410,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,135580.0,134190.0,134690.0,2583,18834,3.02,3.02,3.02,22897.3,22897.3,134690.0,10.0,3.96,13.96,0.017,0.061,3.96,13.96,0.017,0.061,2410
|
||||
SHFE,ni2411,ni2411,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,135930.0,134440.0,135150.0,256,4866,3.02,3.02,3.02,22975.5,22975.5,135150.0,10.0,3.96,13.96,0.017,0.061,3.96,13.96,0.017,0.061,2411
|
||||
SHFE,ni2412,ni2412,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,136370.0,134950.0,135690.0,105,2408,3.02,3.02,3.02,23067.3,23067.3,135690.0,10.0,3.96,13.96,0.017,0.061,3.96,13.96,0.017,0.061,2412
|
||||
SHFE,ni2501,ni2501,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,136800.0,135490.0,136080.0,167,3376,3.02,3.02,3.02,23133.6,23133.6,136080.0,10.0,3.96,13.96,0.017,0.06,3.96,13.96,0.017,0.06,2501
|
||||
SHFE,ni2502,ni2502,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,136900.0,136140.0,136140.0,0,298,3.02,3.02,3.02,23143.8,23143.8,136140.0,10.0,3.96,13.96,0.017,0.06,3.96,13.96,0.017,0.06,2502
|
||||
SHFE,ni2503,ni2503,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,138020.0,137100.0,137000.0,1,187,3.02,3.02,3.02,23290.0,23290.0,137000.0,10.0,3.96,13.96,0.017,0.06,3.96,13.96,0.017,0.06,2503
|
||||
SHFE,ni2504,ni2504,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,138450.0,137290.0,137300.0,2,64,3.02,3.02,3.02,23341.0,23341.0,137300.0,10.0,3.96,13.96,0.017,0.06,3.96,13.96,0.017,0.06,2504
|
||||
SHFE,ni2505,ni2505,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,138700.0,138000.0,137800.0,4,169,3.02,3.02,3.02,23426.0,23426.0,137800.0,10.0,3.96,13.96,0.017,0.06,3.96,13.96,0.017,0.06,2505
|
||||
SHFE,ni2506,ni2506,ni,镍,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,139250.0,137870.0,137870.0,0,35,3.02,3.02,3.02,23437.9,23437.9,137870.0,10.0,3.96,13.96,0.017,0.06,3.96,13.96,0.017,0.06,2506
|
||||
INE,nr2407,nr2407,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.25,0,0.25,0,12170.0,12170.0,12170.0,10,2070,2.45,2.45,0.01,30425.0,30425.0,121700.0,50.0,45.1,95.1,0.148,0.313,47.54,97.54,0.156,0.321,2407
|
||||
INE,nr2408,nr2408,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.15,0,0.15,0,12205.0,12205.0,12265.0,2801,17779,2.47,2.47,0.01,18397.5,18397.5,122650.0,50.0,45.06,95.06,0.245,0.517,47.52,97.52,0.258,0.53,2408
|
||||
INE,nr2409,nr2409,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,12270.0,12280.0,12340.0,20759,67736,2.49,2.49,0.01,16042.0,16042.0,123400.0,50.0,45.03,95.03,0.281,0.592,47.51,97.51,0.296,0.608,2409
|
||||
INE,nr2410,nr2410,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,12370.0,12360.0,12420.0,1308,9378,2.5,2.5,0.01,16146.0,16146.0,124200.0,50.0,45.0,95.0,0.279,0.588,47.49,97.49,0.294,0.604,2410
|
||||
INE,nr2411,nr2411,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,12445.0,12465.0,12515.0,138,1504,2.52,2.52,0.01,16269.5,16269.5,125150.0,50.0,44.96,94.96,0.276,0.584,47.47,97.47,0.292,0.599,2411
|
||||
INE,nr2412,nr2412,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,12525.0,12650.0,12650.0,0,235,2.55,2.55,0.01,16445.0,16445.0,126500.0,50.0,44.9,94.9,0.273,0.577,47.44,97.44,0.289,0.593,2412
|
||||
INE,nr2501,nr2501,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,12650.0,12615.0,12700.0,31,457,2.56,2.56,0.01,16510.0,16510.0,127000.0,50.0,44.88,94.88,0.272,0.575,47.43,97.43,0.287,0.59,2501
|
||||
INE,nr2502,nr2502,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,12670.0,12670.0,12730.0,1,29,2.56,2.56,0.01,16549.0,16549.0,127300.0,50.0,44.87,94.87,0.271,0.573,47.43,97.43,0.287,0.589,2502
|
||||
INE,nr2503,nr2503,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,12800.0,12800.0,12800.0,0,48,2.58,2.58,0.01,16640.0,16640.0,128000.0,50.0,44.84,94.84,0.269,0.57,47.41,97.41,0.285,0.585,2503
|
||||
INE,nr2504,nr2504,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,12850.0,12850.0,12850.0,0,25,2.59,2.59,0.01,16705.0,16705.0,128500.0,50.0,44.82,94.82,0.268,0.568,47.4,97.4,0.284,0.583,2504
|
||||
INE,nr2505,nr2505,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,12935.0,12910.0,12910.0,0,34,2.6,2.6,0.01,16783.0,16783.0,129100.0,50.0,44.8,94.8,0.267,0.565,47.39,97.39,0.282,0.58,2505
|
||||
INE,nr2506,nr2506,nr,20号胶,10,5.0,2e-05,0.01,2e-05,0.01,0.0,0.0,0.13,0,0.13,0,13045.0,13045.0,13045.0,0,8,2.63,2.63,0.01,16958.5,16958.5,130450.0,50.0,44.75,94.75,0.264,0.559,47.37,97.37,0.279,0.574,2506
|
||||
DCE,p2407,棕榈油2407,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.25,0,0.25,0,7834.0,7834.0,7834.0,0,0,2.51,2.51,2.51,19585.0,19585.0,78340.0,20.0,14.97,34.97,0.076,0.179,14.97,34.97,0.076,0.179,2407
|
||||
DCE,p2408,棕榈油2408,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7692.0,7634.0,7690.0,29,1722,2.51,2.51,2.51,9997.0,9997.0,76900.0,20.0,14.97,34.97,0.15,0.35,14.97,34.97,0.15,0.35,2408
|
||||
DCE,p2409,棕榈油2409,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7648.0,7612.0,7664.0,206793,432072,2.51,2.51,2.51,9963.2,9963.2,76640.0,20.0,14.97,34.97,0.15,0.351,14.97,34.97,0.15,0.351,2409
|
||||
DCE,p2410,棕榈油2410,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7622.0,7592.0,7642.0,244,2341,2.51,2.51,2.51,9934.6,9934.6,76420.0,20.0,14.97,34.97,0.151,0.352,14.97,34.97,0.151,0.352,2410
|
||||
DCE,p2411,棕榈油2411,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7618.0,7584.0,7622.0,83,463,2.51,2.51,2.51,9908.6,9908.6,76220.0,20.0,14.97,34.97,0.151,0.353,14.97,34.97,0.151,0.353,2411
|
||||
DCE,p2412,棕榈油2412,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7606.0,7566.0,7600.0,34,325,2.51,2.51,2.51,9880.0,9880.0,76000.0,20.0,14.97,34.97,0.152,0.354,14.97,34.97,0.152,0.354,2412
|
||||
DCE,p2501,棕榈油2501,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7558.0,7542.0,7594.0,28513,229001,2.51,2.51,2.51,9872.2,9872.2,75940.0,20.0,14.97,34.97,0.152,0.354,14.97,34.97,0.152,0.354,2501
|
||||
DCE,p2502,棕榈油2502,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7562.0,7540.0,7540.0,0,309,2.51,2.51,2.51,9802.0,9802.0,75400.0,20.0,14.97,34.97,0.153,0.357,14.97,34.97,0.153,0.357,2502
|
||||
DCE,p2503,棕榈油2503,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7538.0,7550.0,7590.0,19,2278,2.51,2.51,2.51,9867.0,9867.0,75900.0,20.0,14.97,34.97,0.152,0.354,14.97,34.97,0.152,0.354,2503
|
||||
DCE,p2504,棕榈油2504,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7570.0,7544.0,7586.0,6,223,2.51,2.51,2.51,9861.8,9861.8,75860.0,20.0,14.97,34.97,0.152,0.355,14.97,34.97,0.152,0.355,2504
|
||||
DCE,p2505,棕榈油2505,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7560.0,7552.0,7600.0,1582,33844,2.51,2.51,2.51,9880.0,9880.0,76000.0,20.0,14.97,34.97,0.152,0.354,14.97,34.97,0.152,0.354,2505
|
||||
DCE,p2506,棕榈油2506,p,棕榈油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7554.0,7542.0,7576.0,7,175,2.51,2.51,2.51,9848.8,9848.8,75760.0,20.0,14.97,34.97,0.152,0.355,14.97,34.97,0.152,0.355,2506
|
||||
SHFE,pb2407,pb2407,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.25,0,0.25,0,19545.0,19490.0,19480.0,285,7070,3.91,3.91,0.01,24350.0,24350.0,97400.0,25.0,17.18,42.18,0.071,0.173,21.08,46.08,0.087,0.189,2407
|
||||
SHFE,pb2408,pb2408,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.15,0,0.15,0,19480.0,19430.0,19440.0,34120,87149,3.9,3.9,0.01,14580.0,14580.0,97200.0,25.0,17.19,42.19,0.118,0.289,21.09,46.09,0.145,0.316,2408
|
||||
SHFE,pb2409,pb2409,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,19235.0,19175.0,19200.0,17336,62901,3.86,3.86,0.01,13440.0,13440.0,96000.0,25.0,17.29,42.29,0.129,0.315,21.14,46.14,0.157,0.343,2409
|
||||
SHFE,pb2410,pb2410,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,19025.0,18960.0,18975.0,1543,11593,3.81,3.81,0.01,13282.5,13282.5,94875.0,25.0,17.38,42.38,0.131,0.319,21.18,46.18,0.159,0.348,2410
|
||||
SHFE,pb2411,pb2411,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,18885.0,18815.0,18825.0,148,3047,3.78,3.78,0.01,13177.5,13177.5,94125.0,25.0,17.44,42.44,0.132,0.322,21.21,46.21,0.161,0.351,2411
|
||||
SHFE,pb2412,pb2412,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,18840.0,18765.0,18815.0,15,811,3.78,3.78,0.01,13170.5,13170.5,94075.0,25.0,17.44,42.44,0.132,0.322,21.22,46.22,0.161,0.351,2412
|
||||
SHFE,pb2501,pb2501,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,18760.0,18690.0,18685.0,14,667,3.75,3.75,0.01,13079.5,13079.5,93425.0,25.0,17.49,42.49,0.134,0.325,21.24,46.24,0.162,0.354,2501
|
||||
SHFE,pb2502,pb2502,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,18730.0,18665.0,18650.0,3,199,3.75,3.75,0.01,13055.0,13055.0,93250.0,25.0,17.51,42.51,0.134,0.326,21.25,46.25,0.163,0.354,2502
|
||||
SHFE,pb2503,pb2503,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,18690.0,18630.0,18630.0,0,157,3.74,3.74,0.01,13041.0,13041.0,93150.0,25.0,17.52,42.52,0.134,0.326,21.25,46.25,0.163,0.355,2503
|
||||
SHFE,pb2504,pb2504,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,18620.0,18600.0,18575.0,6,108,3.73,3.73,0.01,13002.5,13002.5,92875.0,25.0,17.54,42.54,0.135,0.327,21.26,46.26,0.164,0.356,2504
|
||||
SHFE,pb2505,pb2505,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,18555.0,18545.0,18545.0,14,208,3.72,3.72,0.01,12981.5,12981.5,92725.0,25.0,17.55,42.55,0.135,0.328,21.27,46.27,0.164,0.356,2505
|
||||
SHFE,pb2506,pb2506,pb,铅,5,5.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,18530.0,18530.0,18545.0,2,131,3.72,3.72,0.01,12981.5,12981.5,92725.0,25.0,17.55,42.55,0.135,0.328,21.27,46.27,0.164,0.356,2506
|
||||
DCE,pg2407,液化石油气2407,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.25,0,0.25,0,5001.0,5001.0,5001.0,0,1195,6.02,6.02,6.02,25005.0,25005.0,100020.0,20.0,7.97,27.97,0.032,0.112,7.97,27.97,0.032,0.112,2407
|
||||
DCE,pg2408,液化石油气2408,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,4628.0,4595.0,4624.0,385,2452,6.02,6.02,6.02,12022.4,12022.4,92480.0,20.0,7.97,27.97,0.066,0.233,7.97,27.97,0.066,0.233,2408
|
||||
DCE,pg2409,液化石油气2409,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,4548.0,4520.0,4553.0,24272,77938,6.02,6.02,6.02,11837.8,11837.8,91060.0,20.0,7.97,27.97,0.067,0.236,7.97,27.97,0.067,0.236,2409
|
||||
DCE,pg2410,液化石油气2410,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,5174.0,5148.0,5183.0,2463,37866,6.02,6.02,6.02,13475.8,13475.8,103660.0,20.0,7.97,27.97,0.059,0.208,7.97,27.97,0.059,0.208,2410
|
||||
DCE,pg2411,液化石油气2411,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,5091.0,5073.0,5103.0,186,5008,6.02,6.02,6.02,13267.8,13267.8,102060.0,20.0,7.97,27.97,0.06,0.211,7.97,27.97,0.06,0.211,2411
|
||||
DCE,pg2412,液化石油气2412,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,5006.0,4981.0,5013.0,51,388,6.02,6.02,6.02,13033.8,13033.8,100260.0,20.0,7.97,27.97,0.061,0.215,7.97,27.97,0.061,0.215,2412
|
||||
DCE,pg2501,液化石油气2501,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,4906.0,4882.0,4901.0,36,1775,6.02,6.02,6.02,12742.6,12742.6,98020.0,20.0,7.97,27.97,0.063,0.219,7.97,27.97,0.063,0.219,2501
|
||||
DCE,pg2502,液化石油气2502,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,4799.0,4755.0,4755.0,0,144,6.02,6.02,6.02,12363.0,12363.0,95100.0,20.0,7.97,27.97,0.064,0.226,7.97,27.97,0.064,0.226,2502
|
||||
DCE,pg2503,液化石油气2503,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,4611.0,4593.0,4617.0,14,919,6.02,6.02,6.02,12004.2,12004.2,92340.0,20.0,7.97,27.97,0.066,0.233,7.97,27.97,0.066,0.233,2503
|
||||
DCE,pg2504,液化石油气2504,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,4964.0,4940.0,4969.0,3,755,6.02,6.02,6.02,12919.4,12919.4,99380.0,20.0,7.97,27.97,0.062,0.216,7.97,27.97,0.062,0.216,2504
|
||||
DCE,pg2505,液化石油气2505,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,4811.0,4810.0,4826.0,2,327,6.02,6.02,6.02,12547.6,12547.6,96520.0,20.0,7.97,27.97,0.064,0.223,7.97,27.97,0.064,0.223,2505
|
||||
DCE,pg2506,液化石油气2506,pg,液化石油气,20,1.0,0.0,6.01,0.0,6.01,0.0,6.01,0.13,0,0.13,0,4825.0,4825.0,4825.0,0,7,6.02,6.02,6.02,12545.0,12545.0,96500.0,20.0,7.97,27.97,0.064,0.223,7.97,27.97,0.064,0.223,2506
|
||||
DCE,pp2407,聚丙烯2407,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.26,0,0.26,0,7650.0,7627.0,7627.0,0,1142,1.01,1.01,1.01,9915.1,9915.1,38135.0,5.0,2.98,7.98,0.03,0.08,2.98,7.98,0.03,0.08,2407
|
||||
DCE,pp2408,聚丙烯2408,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7662.0,7641.0,7657.0,358,5492,1.01,1.01,1.01,4977.05,4977.05,38285.0,5.0,2.98,7.98,0.06,0.16,2.98,7.98,0.06,0.16,2408
|
||||
DCE,pp2409,聚丙烯2409,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7689.0,7669.0,7693.0,85480,401207,1.01,1.01,1.01,5000.45,5000.45,38465.0,5.0,2.98,7.98,0.06,0.159,2.98,7.98,0.06,0.159,2409
|
||||
DCE,pp2410,聚丙烯2410,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7685.0,7681.0,7703.0,336,2991,1.01,1.01,1.01,5006.95,5006.95,38515.0,5.0,2.98,7.98,0.059,0.159,2.98,7.98,0.059,0.159,2410
|
||||
DCE,pp2411,聚丙烯2411,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7703.0,7692.0,7732.0,6,171,1.01,1.01,1.01,5025.8,5025.8,38660.0,5.0,2.98,7.98,0.059,0.159,2.98,7.98,0.059,0.159,2411
|
||||
DCE,pp2412,聚丙烯2412,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7732.0,7696.0,7743.0,12,118,1.01,1.01,1.01,5032.95,5032.95,38715.0,5.0,2.98,7.98,0.059,0.158,2.98,7.98,0.059,0.158,2412
|
||||
DCE,pp2501,聚丙烯2501,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7716.0,7697.0,7722.0,14070,70676,1.01,1.01,1.01,5019.3,5019.3,38610.0,5.0,2.98,7.98,0.059,0.159,2.98,7.98,0.059,0.159,2501
|
||||
DCE,pp2502,聚丙烯2502,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7693.0,7679.0,7712.0,1,102,1.01,1.01,1.01,5012.8,5012.8,38560.0,5.0,2.98,7.98,0.059,0.159,2.98,7.98,0.059,0.159,2502
|
||||
DCE,pp2503,聚丙烯2503,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7692.0,7687.0,7687.0,0,31,1.01,1.01,1.01,4996.55,4996.55,38435.0,5.0,2.98,7.98,0.06,0.16,2.98,7.98,0.06,0.16,2503
|
||||
DCE,pp2504,聚丙烯2504,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7770.0,7770.0,7770.0,0,22,1.01,1.01,1.01,5050.5,5050.5,38850.0,5.0,2.98,7.98,0.059,0.158,2.98,7.98,0.059,0.158,2504
|
||||
DCE,pp2505,聚丙烯2505,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7692.0,7666.0,7691.0,722,6984,1.01,1.01,1.01,4999.15,4999.15,38455.0,5.0,2.98,7.98,0.06,0.16,2.98,7.98,0.06,0.16,2505
|
||||
DCE,pp2506,聚丙烯2506,pp,聚丙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,7709.0,7709.0,7709.0,0,12,1.01,1.01,1.01,5010.85,5010.85,38545.0,5.0,2.98,7.98,0.059,0.159,2.98,7.98,0.059,0.159,2506
|
||||
SHFE,rb2407,rb2407,rb,螺纹钢,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.26,0,0.26,0,3311.0,3311.0,3298.0,90,2010,3.31,3.31,3.31,8574.8,8574.8,32980.0,10.0,3.38,13.38,0.039,0.156,3.38,13.38,0.039,0.156,2407
|
||||
SHFE,rb2408,rb2408,rb,螺纹钢,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.16,0,0.16,0,3319.0,3301.0,3318.0,107,5267,3.33,3.33,3.33,5308.8,5308.8,33180.0,10.0,3.34,13.34,0.063,0.251,3.34,13.34,0.063,0.251,2408
|
||||
SHFE,rb2409,rb2409,rb,螺纹钢,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,3396.0,3380.0,3400.0,2916,39489,3.41,3.41,3.41,4420.0,4420.0,34000.0,10.0,3.18,13.18,0.072,0.298,3.18,13.18,0.072,0.298,2409
|
||||
SHFE,rb2410,rb2410,rb,螺纹钢,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,3492.0,3478.0,3493.0,306361,2243085,3.51,3.51,3.51,4540.9,4540.9,34930.0,10.0,2.99,12.99,0.066,0.286,2.99,12.99,0.066,0.286,2410
|
||||
SHFE,rb2411,rb2411,rb,螺纹钢,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3520.0,3501.0,3518.0,15855,303589,0.72,0.72,0.72,4573.4,4573.4,35180.0,10.0,8.57,18.57,0.187,0.406,8.57,18.57,0.187,0.406,2411
|
||||
SHFE,rb2412,rb2412,rb,螺纹钢,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3556.0,3532.0,3549.0,61,67840,0.72,0.72,0.72,4613.7,4613.7,35490.0,10.0,8.56,18.56,0.185,0.402,8.56,18.56,0.185,0.402,2412
|
||||
SHFE,rb2501,rb2501,rb,螺纹钢,10,1.0,0.0003,0.01,0.0003,0.01,0.0003,0.01,0.13,0,0.13,0,3581.0,3562.0,3578.0,15677,333691,10.75,10.75,10.75,4651.4,4651.4,35780.0,10.0,-11.49,-1.49,-0.247,-0.032,-11.49,-1.49,-0.247,-0.032,2501
|
||||
SHFE,rb2502,rb2502,rb,螺纹钢,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3593.0,3576.0,3586.0,7,3217,0.73,0.73,0.73,4661.8,4661.8,35860.0,10.0,8.54,18.54,0.183,0.398,8.54,18.54,0.183,0.398,2502
|
||||
SHFE,rb2503,rb2503,rb,螺纹钢,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3608.0,3588.0,3609.0,167,4086,0.73,0.73,0.73,4691.7,4691.7,36090.0,10.0,8.53,18.53,0.182,0.395,8.53,18.53,0.182,0.395,2503
|
||||
SHFE,rb2504,rb2504,rb,螺纹钢,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3624.0,3604.0,3618.0,23,342,0.74,0.74,0.74,4703.4,4703.4,36180.0,10.0,8.53,18.53,0.181,0.394,8.53,18.53,0.181,0.394,2504
|
||||
SHFE,rb2505,rb2505,rb,螺纹钢,10,1.0,0.0001,0.01,0.0001,0.01,0.0001,0.01,0.13,0,0.13,0,3638.0,3617.0,3639.0,1614,33344,3.65,3.65,3.65,4730.7,4730.7,36390.0,10.0,2.7,12.7,0.057,0.268,2.7,12.7,0.057,0.268,2505
|
||||
SHFE,rb2506,rb2506,rb,螺纹钢,10,1.0,2e-05,0.01,2e-05,0.01,2e-05,0.01,0.13,0,0.13,0,3653.0,3640.0,3651.0,14,158,0.74,0.74,0.74,4746.3,4746.3,36510.0,10.0,8.52,18.52,0.179,0.39,8.52,18.52,0.179,0.39,2506
|
||||
DCE,rr2407,粳米2407,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.25,0,0.25,0,3425.0,3425.0,3425.0,0,0,1.01,1.01,1.01,8562.5,8562.5,34250.0,10.0,7.98,17.98,0.093,0.21,7.98,17.98,0.093,0.21,2407
|
||||
DCE,rr2408,粳米2408,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3485.0,3488.0,3488.0,762,1954,1.01,1.01,1.01,3836.8,3836.8,34880.0,10.0,7.98,17.98,0.208,0.469,7.98,17.98,0.208,0.469,2408
|
||||
DCE,rr2409,粳米2409,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3485.0,3487.0,3485.0,602,5229,1.01,1.01,1.01,3833.5,3833.5,34850.0,10.0,7.98,17.98,0.208,0.469,7.98,17.98,0.208,0.469,2409
|
||||
DCE,rr2410,粳米2410,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3504.0,3503.0,3504.0,398,1271,1.01,1.01,1.01,3854.4,3854.4,35040.0,10.0,7.98,17.98,0.207,0.466,7.98,17.98,0.207,0.466,2410
|
||||
DCE,rr2411,粳米2411,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3528.0,3531.0,3526.0,6,159,1.01,1.01,1.01,3878.6,3878.6,35260.0,10.0,7.98,17.98,0.206,0.463,7.98,17.98,0.206,0.463,2411
|
||||
DCE,rr2412,粳米2412,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3534.0,3535.0,3530.0,3,90,1.01,1.01,1.01,3883.0,3883.0,35300.0,10.0,7.98,17.98,0.205,0.463,7.98,17.98,0.205,0.463,2412
|
||||
DCE,rr2501,粳米2501,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3534.0,3533.0,3534.0,3,119,1.01,1.01,1.01,3887.4,3887.4,35340.0,10.0,7.98,17.98,0.205,0.462,7.98,17.98,0.205,0.462,2501
|
||||
DCE,rr2502,粳米2502,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3561.0,3561.0,3544.0,1,129,1.01,1.01,1.01,3898.4,3898.4,35440.0,10.0,7.98,17.98,0.205,0.461,7.98,17.98,0.205,0.461,2502
|
||||
DCE,rr2503,粳米2503,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3556.0,3556.0,3540.0,1,42,1.01,1.01,1.01,3894.0,3894.0,35400.0,10.0,7.98,17.98,0.205,0.462,7.98,17.98,0.205,0.462,2503
|
||||
DCE,rr2504,粳米2504,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3560.0,3569.0,3569.0,0,10,1.01,1.01,1.01,3925.9,3925.9,35690.0,10.0,7.98,17.98,0.203,0.458,7.98,17.98,0.203,0.458,2504
|
||||
DCE,rr2505,粳米2505,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3590.0,3591.0,3590.0,6,1981,1.01,1.01,1.01,3949.0,3949.0,35900.0,10.0,7.98,17.98,0.202,0.455,7.98,17.98,0.202,0.455,2505
|
||||
DCE,rr2506,粳米2506,rr,粳米,10,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.11,0,0.11,0,3585.0,3585.0,3585.0,0,19,1.01,1.01,1.01,3943.5,3943.5,35850.0,10.0,7.98,17.98,0.202,0.456,7.98,17.98,0.202,0.456,2506
|
||||
SHFE,ru2407,ru2407,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.25,0,0.25,0,14430.0,14430.0,14430.0,0,620,3.02,3.02,0.01,36075.0,36075.0,144300.0,50.0,43.96,93.96,0.122,0.26,46.97,96.97,0.13,0.269,2407
|
||||
SHFE,ru2408,ru2408,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.15,0,0.15,0,14560.0,14555.0,14620.0,65,1356,3.02,3.02,0.01,21930.0,21930.0,146200.0,50.0,43.96,93.96,0.2,0.428,46.97,96.97,0.214,0.442,2408
|
||||
SHFE,ru2409,ru2409,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,12.01,0.13,0,0.13,0,14645.0,14625.0,14690.0,73828,213058,3.02,3.02,12.02,19097.0,19097.0,146900.0,50.0,43.96,93.96,0.23,0.492,34.96,84.96,0.183,0.445,2409
|
||||
SHFE,ru2410,ru2410,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.13,0,0.13,0,14705.0,14680.0,14755.0,14,320,3.02,3.02,0.01,19181.5,19181.5,147550.0,50.0,43.96,93.96,0.229,0.49,46.97,96.97,0.245,0.506,2410
|
||||
SHFE,ru2411,ru2411,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.13,0,0.13,0,14715.0,14695.0,14760.0,377,4200,3.02,3.02,0.01,19188.0,19188.0,147600.0,50.0,43.96,93.96,0.229,0.49,46.97,96.97,0.245,0.505,2411
|
||||
SHFE,ru2501,ru2501,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.13,0,0.13,0,15815.0,15805.0,15865.0,14440,57191,3.02,3.02,0.01,20624.5,20624.5,158650.0,50.0,43.96,93.96,0.213,0.456,46.97,96.97,0.228,0.47,2501
|
||||
SHFE,ru2503,ru2503,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.13,0,0.13,0,15840.0,15835.0,15900.0,1,231,3.02,3.02,0.01,20670.0,20670.0,159000.0,50.0,43.96,93.96,0.213,0.455,46.97,96.97,0.227,0.469,2503
|
||||
SHFE,ru2504,ru2504,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.13,0,0.13,0,15930.0,15930.0,15930.0,0,20,3.02,3.02,0.01,20709.0,20709.0,159300.0,50.0,43.96,93.96,0.212,0.454,46.97,96.97,0.227,0.468,2504
|
||||
SHFE,ru2505,ru2505,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.13,0,0.13,0,15945.0,15940.0,15990.0,302,5246,3.02,3.02,0.01,20787.0,20787.0,159900.0,50.0,43.96,93.96,0.211,0.452,46.97,96.97,0.226,0.466,2505
|
||||
SHFE,ru2506,ru2506,ru,天然橡胶,10,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.13,0,0.13,0,15960.0,15960.0,16000.0,1,21,3.02,3.02,0.01,20800.0,20800.0,160000.0,50.0,43.96,93.96,0.211,0.452,46.97,96.97,0.226,0.466,2506
|
||||
INE,sc2408,sc2408,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,621.3,614.5,617.9,20934,25742,20.05,20.05,0.04,92685.0,92685.0,617900.0,100.0,59.91,159.91,0.065,0.173,79.92,179.92,0.086,0.194,2408
|
||||
INE,sc2409,sc2409,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,617.0,612.0,615.7,9806,20024,20.05,20.05,0.04,92355.0,92355.0,615700.0,100.0,59.91,159.91,0.065,0.173,79.92,179.92,0.087,0.195,2409
|
||||
INE,sc2410,sc2410,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,613.1,609.3,612.2,1699,6335,20.05,20.05,0.04,91830.0,91830.0,612200.0,100.0,59.91,159.91,0.065,0.174,79.92,179.92,0.087,0.196,2410
|
||||
INE,sc2411,sc2411,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,608.5,605.4,608.3,97,633,20.05,20.05,0.04,91245.0,91245.0,608300.0,100.0,59.91,159.91,0.066,0.175,79.92,179.92,0.088,0.197,2411
|
||||
INE,sc2412,sc2412,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,604.9,601.1,603.0,8,377,20.05,20.05,0.04,90450.0,90450.0,603000.0,100.0,59.91,159.91,0.066,0.177,79.92,179.92,0.088,0.199,2412
|
||||
INE,sc2501,sc2501,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,600.0,596.6,600.1,16,134,20.05,20.05,0.04,90015.0,90015.0,600100.0,100.0,59.91,159.91,0.067,0.178,79.92,179.92,0.089,0.2,2501
|
||||
INE,sc2502,sc2502,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,597.7,599.7,595.0,3,37,20.05,20.05,0.04,89250.0,89250.0,595000.0,100.0,59.91,159.91,0.067,0.179,79.92,179.92,0.09,0.202,2502
|
||||
INE,sc2503,sc2503,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,592.9,592.1,591.9,1,47,20.05,20.05,0.04,88785.0,88785.0,591900.0,100.0,59.91,159.91,0.067,0.18,79.92,179.92,0.09,0.203,2503
|
||||
INE,sc2504,sc2504,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,592.7,592.7,592.7,0,22,20.05,20.05,0.04,88905.0,88905.0,592700.0,100.0,59.91,159.91,0.067,0.18,79.92,179.92,0.09,0.202,2504
|
||||
INE,sc2505,sc2505,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,586.7,585.0,585.0,0,27,20.05,20.05,0.04,87750.0,87750.0,585000.0,100.0,59.91,159.91,0.068,0.182,79.92,179.92,0.091,0.205,2505
|
||||
INE,sc2506,sc2506,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,586.8,586.8,586.8,0,56,20.05,20.05,0.04,88020.0,88020.0,586800.0,100.0,59.91,159.91,0.068,0.182,79.92,179.92,0.091,0.204,2506
|
||||
INE,sc2507,sc2507,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,592.8,592.8,592.8,0,5,20.05,20.05,0.04,88920.0,88920.0,592800.0,100.0,59.91,159.91,0.067,0.18,79.92,179.92,0.09,0.202,2507
|
||||
INE,sc2509,sc2509,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,584.6,584.6,584.6,0,13,20.05,20.05,0.04,87690.0,87690.0,584600.0,100.0,59.91,159.91,0.068,0.182,79.92,179.92,0.091,0.205,2509
|
||||
INE,sc2512,sc2512,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,578.7,578.7,578.7,0,10,20.04,20.04,0.03,86805.0,86805.0,578700.0,100.0,59.91,159.91,0.069,0.184,79.92,179.92,0.092,0.207,2512
|
||||
INE,sc2603,sc2603,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,579.7,579.7,579.7,0,12,20.04,20.04,0.03,86955.0,86955.0,579700.0,100.0,59.91,159.91,0.069,0.184,79.92,179.92,0.092,0.207,2603
|
||||
INE,sc2606,sc2606,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,577.0,575.3,575.3,0,73,20.04,20.04,0.03,86295.0,86295.0,575300.0,100.0,59.91,159.91,0.069,0.185,79.92,179.92,0.093,0.208,2606
|
||||
INE,sc2609,sc2609,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,573.9,573.9,573.9,0,20,20.04,20.04,0.03,86085.0,86085.0,573900.0,100.0,59.91,159.91,0.07,0.186,79.92,179.92,0.093,0.209,2609
|
||||
INE,sc2612,sc2612,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,567.0,567.0,567.0,0,12,20.04,20.04,0.03,85050.0,85050.0,567000.0,100.0,59.91,159.91,0.07,0.188,79.92,179.92,0.094,0.212,2612
|
||||
INE,sc2703,sc2703,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,570.0,570.0,570.0,0,43,20.04,20.04,0.03,85500.0,85500.0,570000.0,100.0,59.91,159.91,0.07,0.187,79.92,179.92,0.093,0.21,2703
|
||||
INE,sc2706,sc2706,sc,原油,1000,0.1,0.0,20.01,0.0,20.01,0.0,0.0,0.15,0,0.15,0,568.0,568.0,568.0,0,24,20.04,20.04,0.03,85200.0,85200.0,568000.0,100.0,59.91,159.91,0.07,0.188,79.92,179.92,0.094,0.211,2706
|
||||
GFEX,si2407,工业硅2407,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.27,0,0.27,0,11030.0,11000.0,0.0,0,407,5.51,5.51,0.0,14850.0,14850.0,55000.0,25.0,13.97,38.97,0.094,0.262,19.48,44.48,0.131,0.3,2407
|
||||
GFEX,si2408,工业硅2408,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,11125.0,11020.0,0.0,0,23016,5.52,5.52,0.0,8816.0,8816.0,55100.0,25.0,13.95,38.95,0.158,0.442,19.47,44.47,0.221,0.504,2408
|
||||
GFEX,si2409,工业硅2409,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,11170.0,11110.0,0.0,0,236506,5.57,5.57,0.0,8888.0,8888.0,55550.0,25.0,13.86,38.86,0.156,0.437,19.43,44.43,0.219,0.5,2409
|
||||
GFEX,si2410,工业硅2410,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,11260.0,11190.0,0.0,0,38111,5.61,5.61,0.0,8952.0,8952.0,55950.0,25.0,13.78,38.78,0.154,0.433,19.39,44.39,0.217,0.496,2410
|
||||
GFEX,si2411,工业硅2411,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,11355.0,11265.0,0.0,0,36834,5.65,5.65,0.0,9012.0,9012.0,56325.0,25.0,13.71,38.71,0.152,0.43,19.35,44.35,0.215,0.492,2411
|
||||
GFEX,si2412,工业硅2412,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,14190.0,14145.0,0.0,0,29263,7.09,7.09,0.0,11316.0,11316.0,70725.0,25.0,10.83,35.83,0.096,0.317,17.91,42.91,0.158,0.379,2412
|
||||
GFEX,si2501,工业硅2501,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,14250.0,14230.0,0.0,0,1147,7.13,7.13,0.0,11384.0,11384.0,71150.0,25.0,10.74,35.74,0.094,0.314,17.87,42.87,0.157,0.377,2501
|
||||
GFEX,si2502,工业硅2502,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,14300.0,14300.0,0.0,0,43,7.16,7.16,0.0,11440.0,11440.0,71500.0,25.0,10.67,35.67,0.093,0.312,17.83,42.83,0.156,0.374,2502
|
||||
GFEX,si2503,工业硅2503,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,14440.0,14440.0,0.0,0,19,7.23,7.23,0.0,11552.0,11552.0,72200.0,25.0,10.53,35.53,0.091,0.308,17.76,42.76,0.154,0.37,2503
|
||||
GFEX,si2504,工业硅2504,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,14420.0,14425.0,0.0,0,12,7.23,7.23,0.0,11540.0,11540.0,72125.0,25.0,10.55,35.55,0.091,0.308,17.77,42.77,0.154,0.371,2504
|
||||
GFEX,si2505,工业硅2505,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,14620.0,14530.0,0.0,0,152,7.28,7.28,0.0,11624.0,11624.0,72650.0,25.0,10.44,35.44,0.09,0.305,17.72,42.72,0.152,0.367,2505
|
||||
GFEX,si2506,工业硅2506,si,工业硅,5,5.0,0.0001,0.01,0.0001,0.01,0.0,0.0,0.16,0,0.16,0,14620.0,14580.0,0.0,0,50,7.3,7.3,0.0,11664.0,11664.0,72900.0,25.0,10.39,35.39,0.089,0.303,17.69,42.69,0.152,0.366,2506
|
||||
SHFE,sn2407,sn2407,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,36.01,0.25,0,0.25,0,278430.0,276700.0,281910.0,10,2836,3.03,3.03,36.03,70477.5,70477.5,281910.0,10.0,3.95,13.95,0.006,0.02,-29.05,-19.05,-0.041,-0.027,2407
|
||||
SHFE,sn2408,sn2408,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,278190.0,277240.0,281820.0,63023,37314,3.03,3.03,3.03,47909.4,47909.4,281820.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2408
|
||||
SHFE,sn2409,sn2409,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,278920.0,277970.0,282360.0,18516,24096,3.03,3.03,3.03,48001.2,48001.2,282360.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2409
|
||||
SHFE,sn2410,sn2410,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,279210.0,278210.0,282570.0,2649,6022,3.03,3.03,3.03,48036.9,48036.9,282570.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2410
|
||||
SHFE,sn2411,sn2411,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,278900.0,278060.0,282120.0,125,1845,3.03,3.03,3.03,47960.4,47960.4,282120.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2411
|
||||
SHFE,sn2412,sn2412,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,278760.0,277900.0,282240.0,87,650,3.03,3.03,3.03,47980.8,47980.8,282240.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2412
|
||||
SHFE,sn2501,sn2501,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,278920.0,277480.0,281930.0,64,687,3.03,3.03,3.03,47928.1,47928.1,281930.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2501
|
||||
SHFE,sn2502,sn2502,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,277720.0,277570.0,281030.0,3,118,3.03,3.03,3.03,47775.1,47775.1,281030.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2502
|
||||
SHFE,sn2503,sn2503,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,278360.0,278800.0,281480.0,2,81,3.03,3.03,3.03,47851.6,47851.6,281480.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2503
|
||||
SHFE,sn2504,sn2504,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,277810.0,277860.0,279190.0,1,134,3.03,3.03,3.03,47462.3,47462.3,279190.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2504
|
||||
SHFE,sn2505,sn2505,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,277590.0,277110.0,280980.0,3,41,3.03,3.03,3.03,47766.6,47766.6,280980.0,10.0,3.95,13.95,0.008,0.029,3.95,13.95,0.008,0.029,2505
|
||||
SHFE,sn2506,sn2506,sn,锡,1,10.0,0.0,3.01,0.0,3.01,0.0,3.01,0.17,0,0.17,0,276740.0,276740.0,276740.0,0,11,3.03,3.03,3.03,47045.8,47045.8,276740.0,10.0,3.95,13.95,0.008,0.03,3.95,13.95,0.008,0.03,2506
|
||||
SHFE,sp2407,sp2407,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.25,0,0.25,0,5670.0,5670.0,5670.0,0,4182,2.85,2.85,0.0,14175.0,14175.0,56700.0,20.0,14.3,34.3,0.101,0.242,17.15,37.15,0.121,0.262,2407
|
||||
SHFE,sp2408,sp2408,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.15,0,0.15,0,5662.0,5656.0,5644.0,140,5218,2.84,2.84,0.0,8466.0,8466.0,56440.0,20.0,14.33,34.33,0.169,0.405,17.16,37.16,0.203,0.439,2408
|
||||
SHFE,sp2409,sp2409,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5694.0,5678.0,5666.0,60856,264545,2.85,2.85,0.0,7365.8,7365.8,56660.0,20.0,14.31,34.31,0.194,0.466,17.15,37.15,0.233,0.504,2409
|
||||
SHFE,sp2410,sp2410,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5708.0,5692.0,5692.0,14,1678,2.86,2.86,0.0,7399.6,7399.6,56920.0,20.0,14.28,34.28,0.193,0.463,17.14,37.14,0.232,0.502,2410
|
||||
SHFE,sp2411,sp2411,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5726.0,5710.0,5704.0,1769,62761,2.87,2.87,0.0,7415.2,7415.2,57040.0,20.0,14.27,34.27,0.192,0.462,17.13,37.13,0.231,0.501,2411
|
||||
SHFE,sp2412,sp2412,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5730.0,5722.0,5706.0,18,2262,2.87,2.87,0.0,7417.8,7417.8,57060.0,20.0,14.27,34.27,0.192,0.462,17.13,37.13,0.231,0.501,2412
|
||||
SHFE,sp2501,sp2501,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5878.0,5856.0,5862.0,2510,39787,2.94,2.94,0.0,7620.6,7620.6,58620.0,20.0,14.11,34.11,0.185,0.448,17.05,37.05,0.224,0.486,2501
|
||||
SHFE,sp2502,sp2502,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5888.0,5850.0,5850.0,0,34,2.94,2.94,0.0,7605.0,7605.0,58500.0,20.0,14.12,34.12,0.186,0.449,17.06,37.06,0.224,0.487,2502
|
||||
SHFE,sp2503,sp2503,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5918.0,5872.0,5880.0,7,1223,2.95,2.95,0.0,7644.0,7644.0,58800.0,20.0,14.09,34.09,0.184,0.446,17.04,37.04,0.223,0.485,2503
|
||||
SHFE,sp2504,sp2504,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5880.0,5874.0,5888.0,10,1091,2.96,2.96,0.0,7654.4,7654.4,58880.0,20.0,14.08,34.08,0.184,0.445,17.04,37.04,0.223,0.484,2504
|
||||
SHFE,sp2505,sp2505,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5912.0,5892.0,5910.0,70,341,2.97,2.97,0.0,7683.0,7683.0,59100.0,20.0,14.06,34.06,0.183,0.443,17.03,37.03,0.222,0.482,2505
|
||||
SHFE,sp2506,sp2506,sp,漂针浆,10,2.0,5e-05,0.01,5e-05,0.01,0.0,0.0,0.13,0,0.13,0,5928.0,5902.0,5910.0,2,51,2.97,2.97,0.0,7683.0,7683.0,59100.0,20.0,14.06,34.06,0.183,0.443,17.03,37.03,0.222,0.482,2506
|
||||
SHFE,ss2407,ss2407,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.26,0,0.26,0,13735.0,13720.0,13720.0,0,1728,2.01,2.01,0.0,17836.0,17836.0,68600.0,25.0,20.97,45.97,0.118,0.258,22.98,47.98,0.129,0.269,2407
|
||||
SHFE,ss2408,ss2408,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.16,0,0.16,0,13795.0,13785.0,13765.0,136,6030,2.01,2.01,0.0,11012.0,11012.0,68825.0,25.0,20.97,45.97,0.19,0.417,22.98,47.98,0.209,0.436,2408
|
||||
SHFE,ss2409,ss2409,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,13980.0,13930.0,13935.0,37326,142183,2.01,2.01,0.0,9057.75,9057.75,69675.0,25.0,20.97,45.97,0.232,0.508,22.98,47.98,0.254,0.53,2409
|
||||
SHFE,ss2410,ss2410,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,14010.0,13975.0,13985.0,2944,52542,2.01,2.01,0.0,9090.25,9090.25,69925.0,25.0,20.97,45.97,0.231,0.506,22.98,47.98,0.253,0.528,2410
|
||||
SHFE,ss2411,ss2411,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,14030.0,13995.0,14005.0,1968,41927,2.01,2.01,0.0,9103.25,9103.25,70025.0,25.0,20.97,45.97,0.23,0.505,22.98,47.98,0.252,0.527,2411
|
||||
SHFE,ss2412,ss2412,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,14070.0,14030.0,14030.0,2,1621,2.01,2.01,0.0,9119.5,9119.5,70150.0,25.0,20.97,45.97,0.23,0.504,22.98,47.98,0.252,0.526,2412
|
||||
SHFE,ss2501,ss2501,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,14110.0,14080.0,14100.0,685,16604,2.01,2.01,0.0,9165.0,9165.0,70500.0,25.0,20.97,45.97,0.229,0.502,22.98,47.98,0.251,0.524,2501
|
||||
SHFE,ss2502,ss2502,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,14220.0,14180.0,14170.0,6,883,2.01,2.01,0.0,9210.5,9210.5,70850.0,25.0,20.97,45.97,0.228,0.499,22.98,47.98,0.25,0.521,2502
|
||||
SHFE,ss2503,ss2503,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,14300.0,14275.0,14275.0,0,144,2.01,2.01,0.0,9278.75,9278.75,71375.0,25.0,20.97,45.97,0.226,0.495,22.98,47.98,0.248,0.517,2503
|
||||
SHFE,ss2504,ss2504,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,14365.0,14380.0,14365.0,3,45,2.01,2.01,0.0,9337.25,9337.25,71825.0,25.0,20.97,45.97,0.225,0.492,22.98,47.98,0.246,0.514,2504
|
||||
SHFE,ss2505,ss2505,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,14425.0,14385.0,14405.0,9,169,2.01,2.01,0.0,9363.25,9363.25,72025.0,25.0,20.97,45.97,0.224,0.491,22.98,47.98,0.245,0.512,2505
|
||||
SHFE,ss2506,ss2506,ss,不锈钢,5,5.0,0.0,2.01,0.0,2.01,0.0,0.0,0.13,0,0.13,0,14465.0,14465.0,14455.0,2,28,2.01,2.01,0.0,9395.75,9395.75,72275.0,25.0,20.97,45.97,0.223,0.489,22.98,47.98,0.245,0.511,2506
|
||||
DCE,v2407,聚氯乙烯2407,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.26,0,0.26,0,5836.0,5790.0,5790.0,202,22420,1.01,1.01,1.01,7527.0,7527.0,28950.0,5.0,2.98,7.98,0.04,0.106,2.98,7.98,0.04,0.106,2407
|
||||
DCE,v2408,聚氯乙烯2408,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,5861.0,5839.0,5843.0,3761,18972,1.01,1.01,1.01,3797.95,3797.95,29215.0,5.0,2.98,7.98,0.078,0.21,2.98,7.98,0.078,0.21,2408
|
||||
DCE,v2409,聚氯乙烯2409,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,5924.0,5897.0,5895.0,205311,956761,1.01,1.01,1.01,3831.75,3831.75,29475.0,5.0,2.98,7.98,0.078,0.208,2.98,7.98,0.078,0.208,2409
|
||||
DCE,v2410,聚氯乙烯2410,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,5966.0,5942.0,5943.0,470,7385,1.01,1.01,1.01,3862.95,3862.95,29715.0,5.0,2.98,7.98,0.077,0.206,2.98,7.98,0.077,0.206,2410
|
||||
DCE,v2411,聚氯乙烯2411,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,6013.0,5986.0,5983.0,25,1366,1.01,1.01,1.01,3888.95,3888.95,29915.0,5.0,2.98,7.98,0.077,0.205,2.98,7.98,0.077,0.205,2411
|
||||
DCE,v2412,聚氯乙烯2412,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,6049.0,6038.0,6033.0,56,888,1.01,1.01,1.01,3921.45,3921.45,30165.0,5.0,2.98,7.98,0.076,0.203,2.98,7.98,0.076,0.203,2412
|
||||
DCE,v2501,聚氯乙烯2501,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,6094.0,6072.0,6072.0,11239,143822,1.01,1.01,1.01,3946.8,3946.8,30360.0,5.0,2.98,7.98,0.075,0.202,2.98,7.98,0.075,0.202,2501
|
||||
DCE,v2502,聚氯乙烯2502,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,6115.0,6084.0,6089.0,15,796,1.01,1.01,1.01,3957.85,3957.85,30445.0,5.0,2.98,7.98,0.075,0.202,2.98,7.98,0.075,0.202,2502
|
||||
DCE,v2503,聚氯乙烯2503,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,6118.0,6106.0,6094.0,16,1646,1.01,1.01,1.01,3961.1,3961.1,30470.0,5.0,2.98,7.98,0.075,0.201,2.98,7.98,0.075,0.201,2503
|
||||
DCE,v2504,聚氯乙烯2504,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,6348.0,6339.0,6337.0,20,503,1.01,1.01,1.01,4119.05,4119.05,31685.0,5.0,2.98,7.98,0.072,0.194,2.98,7.98,0.072,0.194,2504
|
||||
DCE,v2505,聚氯乙烯2505,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,6387.0,6365.0,6365.0,323,16891,1.01,1.01,1.01,4137.25,4137.25,31825.0,5.0,2.98,7.98,0.072,0.193,2.98,7.98,0.072,0.193,2505
|
||||
DCE,v2506,聚氯乙烯2506,v,聚氯乙烯,5,1.0,0.0,1.01,0.0,1.01,0.0,1.01,0.13,0,0.13,0,6415.0,6404.0,6403.0,50,84,1.01,1.01,1.01,4161.95,4161.95,32015.0,5.0,2.98,7.98,0.072,0.192,2.98,7.98,0.072,0.192,2506
|
||||
SHFE,wr2407,wr2407,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.25,0,0.25,0,3701.0,3701.0,3701.0,0,0,1.49,1.49,0.0,9252.5,9252.5,37010.0,10.0,7.01,17.01,0.076,0.184,8.51,18.51,0.092,0.2,2407
|
||||
SHFE,wr2408,wr2408,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.15,0,0.15,0,3741.0,3741.0,3741.0,0,4,1.51,1.51,0.0,5611.5,5611.5,37410.0,10.0,6.98,16.98,0.124,0.303,8.49,18.49,0.151,0.329,2408
|
||||
SHFE,wr2409,wr2409,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3661.0,3660.0,3660.0,0,689,1.48,1.48,0.0,5124.0,5124.0,36600.0,10.0,7.05,17.05,0.138,0.333,8.52,18.52,0.166,0.361,2409
|
||||
SHFE,wr2410,wr2410,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3742.0,3742.0,3742.0,0,10,1.51,1.51,0.0,5238.8,5238.8,37420.0,10.0,6.98,16.98,0.133,0.324,8.49,18.49,0.162,0.353,2410
|
||||
SHFE,wr2411,wr2411,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3767.0,3767.0,3767.0,0,2,1.52,1.52,0.0,5273.8,5273.8,37670.0,10.0,6.96,16.96,0.132,0.322,8.48,18.48,0.161,0.35,2411
|
||||
SHFE,wr2412,wr2412,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3455.0,3455.0,3455.0,0,0,1.39,1.39,0.0,4837.0,4837.0,34550.0,10.0,7.21,17.21,0.149,0.356,8.6,18.6,0.178,0.385,2412
|
||||
SHFE,wr2501,wr2501,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3734.0,3750.0,3750.0,0,31,1.51,1.51,0.0,5250.0,5250.0,37500.0,10.0,6.98,16.98,0.133,0.323,8.49,18.49,0.162,0.352,2501
|
||||
SHFE,wr2502,wr2502,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3785.0,3785.0,3785.0,0,0,1.53,1.53,0.0,5299.0,5299.0,37850.0,10.0,6.95,16.95,0.131,0.32,8.47,18.47,0.16,0.349,2502
|
||||
SHFE,wr2503,wr2503,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3840.0,3840.0,3840.0,0,0,1.55,1.55,0.0,5376.0,5376.0,38400.0,10.0,6.9,16.9,0.128,0.314,8.45,18.45,0.157,0.343,2503
|
||||
SHFE,wr2504,wr2504,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3838.0,3838.0,3838.0,0,0,1.55,1.55,0.0,5373.2,5373.2,38380.0,10.0,6.9,16.9,0.129,0.315,8.45,18.45,0.157,0.343,2504
|
||||
SHFE,wr2505,wr2505,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3726.0,3726.0,3726.0,0,0,1.5,1.5,0.0,5216.4,5216.4,37260.0,10.0,6.99,16.99,0.134,0.326,8.5,18.5,0.163,0.355,2505
|
||||
SHFE,wr2506,wr2506,wr,线材,10,1.0,4e-05,0.01,4e-05,0.01,0.0,0.0,0.14,0,0.14,0,3733.0,3733.0,3733.0,0,0,1.51,1.51,0.0,5226.2,5226.2,37330.0,10.0,6.99,16.99,0.134,0.325,8.49,18.49,0.162,0.354,2506
|
||||
DCE,y2407,豆油2407,y,豆油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.26,0,0.26,0,7580.0,7580.0,7580.0,0,365,2.51,2.51,2.51,19708.0,19708.0,75800.0,20.0,14.97,34.97,0.076,0.177,14.97,34.97,0.076,0.177,2407
|
||||
DCE,y2408,豆油2408,y,豆油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7612.0,7524.0,7568.0,3274,17346,2.51,2.51,2.51,9838.4,9838.4,75680.0,20.0,14.97,34.97,0.152,0.355,14.97,34.97,0.152,0.355,2408
|
||||
DCE,y2409,豆油2409,y,豆油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7638.0,7572.0,7616.0,139127,641834,2.51,2.51,2.51,9900.8,9900.8,76160.0,20.0,14.97,34.97,0.151,0.353,14.97,34.97,0.151,0.353,2409
|
||||
DCE,y2411,豆油2411,y,豆油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7624.0,7582.0,7614.0,1893,12471,2.51,2.51,2.51,9898.2,9898.2,76140.0,20.0,14.97,34.97,0.151,0.353,14.97,34.97,0.151,0.353,2411
|
||||
DCE,y2412,豆油2412,y,豆油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7710.0,7674.0,7710.0,32,1674,2.51,2.51,2.51,10023.0,10023.0,77100.0,20.0,14.97,34.97,0.149,0.349,14.97,34.97,0.149,0.349,2412
|
||||
DCE,y2501,豆油2501,y,豆油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7722.0,7670.0,7706.0,30867,275698,2.51,2.51,2.51,10017.8,10017.8,77060.0,20.0,14.97,34.97,0.149,0.349,14.97,34.97,0.149,0.349,2501
|
||||
DCE,y2503,豆油2503,y,豆油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7588.0,7566.0,7600.0,174,3322,2.51,2.51,2.51,9880.0,9880.0,76000.0,20.0,14.97,34.97,0.152,0.354,14.97,34.97,0.152,0.354,2503
|
||||
DCE,y2505,豆油2505,y,豆油,10,2.0,0.0,2.51,0.0,2.51,0.0,2.51,0.13,0,0.13,0,7524.0,7498.0,7538.0,2480,71088,2.51,2.51,2.51,9799.4,9799.4,75380.0,20.0,14.97,34.97,0.153,0.357,14.97,34.97,0.153,0.357,2505
|
||||
SHFE,zn2407,zn2407,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.25,0,0.25,0,24130.0,24055.0,24275.0,30,4225,3.02,3.02,0.01,30343.75,30343.75,121375.0,25.0,18.97,43.97,0.063,0.145,21.98,46.98,0.072,0.155,2407
|
||||
SHFE,zn2408,zn2408,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.15,0,0.15,0,24240.0,24120.0,24355.0,45884,75529,3.02,3.02,0.01,18266.25,18266.25,121775.0,25.0,18.97,43.97,0.104,0.241,21.98,46.98,0.12,0.257,2408
|
||||
SHFE,zn2409,zn2409,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24280.0,24165.0,24405.0,23716,74609,3.02,3.02,0.01,17083.5,17083.5,122025.0,25.0,18.97,43.97,0.111,0.257,21.98,46.98,0.129,0.275,2409
|
||||
SHFE,zn2410,zn2410,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24285.0,24165.0,24405.0,4707,24192,3.02,3.02,0.01,17083.5,17083.5,122025.0,25.0,18.97,43.97,0.111,0.257,21.98,46.98,0.129,0.275,2410
|
||||
SHFE,zn2411,zn2411,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24240.0,24115.0,24360.0,603,7686,3.02,3.02,0.01,17052.0,17052.0,121800.0,25.0,18.97,43.97,0.111,0.258,21.98,46.98,0.129,0.275,2411
|
||||
SHFE,zn2412,zn2412,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24210.0,24080.0,24300.0,232,3399,3.02,3.02,0.01,17010.0,17010.0,121500.0,25.0,18.97,43.97,0.111,0.258,21.98,46.98,0.129,0.276,2412
|
||||
SHFE,zn2501,zn2501,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24155.0,24055.0,24290.0,59,1096,3.02,3.02,0.01,17003.0,17003.0,121450.0,25.0,18.97,43.97,0.112,0.259,21.98,46.98,0.129,0.276,2501
|
||||
SHFE,zn2502,zn2502,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24135.0,24085.0,24205.0,45,378,3.02,3.02,0.01,16943.5,16943.5,121025.0,25.0,18.97,43.97,0.112,0.259,21.98,46.98,0.13,0.277,2502
|
||||
SHFE,zn2503,zn2503,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24075.0,24000.0,24235.0,1,383,3.02,3.02,0.01,16964.5,16964.5,121175.0,25.0,18.97,43.97,0.112,0.259,21.98,46.98,0.13,0.277,2503
|
||||
SHFE,zn2504,zn2504,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24080.0,24010.0,24165.0,1,68,3.02,3.02,0.01,16915.5,16915.5,120825.0,25.0,18.97,43.97,0.112,0.26,21.98,46.98,0.13,0.278,2504
|
||||
SHFE,zn2505,zn2505,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24055.0,23975.0,24180.0,2,92,3.02,3.02,0.01,16926.0,16926.0,120900.0,25.0,18.97,43.97,0.112,0.26,21.98,46.98,0.13,0.278,2505
|
||||
SHFE,zn2506,zn2506,zn,锌,5,5.0,0.0,3.01,0.0,3.01,0.0,0.0,0.14,0,0.14,0,24035.0,23950.0,24145.0,12,30,3.02,3.02,0.01,16901.5,16901.5,120725.0,25.0,18.97,43.97,0.112,0.26,21.98,46.98,0.13,0.278,2506
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,74 @@
|
||||
,合约,最新价,涨跌,涨跌幅,开盘价,最高价,最低价,昨收价,涨停价,跌停价,最新持仓,成交量,更新时间,说明,交易品种,主连代码,品种代码,交割月份
|
||||
0,豆一2409(a2409),4623.0,-12.0,-0.3%,4635.0,4641.0,4620.0,4632.0,4909.0,4355.0,131113,17837,2024-07-10 21:58:41,主力,豆一2409,a2409,a,2409
|
||||
1,白银2408(ag2408),8197.0,37.0,0.5%,8160.0,8207.0,8138.0,8112.0,8923.0,7300.0,275003,186519,2024-07-10 21:58:43,主力,白银2408,ag2408,ag,2408
|
||||
2,沪铝2408(al2408),20195.0,55.0,0.3%,20140.0,20265.0,20140.0,20250.0,21665.0,18830.0,156460,42560,2024-07-10 21:58:42,主力,沪铝2408,al2408,al,2408
|
||||
3,氧化铝2408(ao2408),3688.0,-62.0,-1.7%,3750.0,3757.0,3667.0,3793.0,4058.0,3527.0,45211,70246,2024-07-10 21:58:42,主力,氧化铝2408,ao2408,ao,2408
|
||||
4,苹果410(AP410),6926.0,36.0,0.5%,6890.0,6932.0,6842.0,6896.0,7517.0,6275.0,167339,107790,2024-07-10 20:53:26,主力,苹果410,AP410,AP,410
|
||||
5,黄金2410(au2410),566.08,1.3,0.2%,564.8,566.48,564.16,561.22,617.34,505.08,140030,23597,2024-07-10 21:58:42,主力,黄金2410,au2410,au,2410
|
||||
6,豆二2409(b2409),3739.0,-7.0,-0.2%,3746.0,3753.0,3730.0,3752.0,3977.0,3527.0,116847,31830,2024-07-10 21:58:38,主力,豆二2409,b2409,b,2409
|
||||
7,胶板2501(bb2501),191.0,-5.4,-2.7%,196.4,196.4,191.0,193.05,202.7,183.4,60,10,2024-07-10 20:53:13,主力,胶板2501,bb2501,bb,2501
|
||||
8,国际铜2408(bc2408),71530.0,310.0,0.4%,71220.0,71640.0,71140.0,71230.0,76210.0,66240.0,6864,2014,2024-07-10 21:58:43,主力,国际铜2408,bc2408,bc,2408
|
||||
9,合成橡胶2408(br2408),14760.0,80.0,0.5%,14680.0,14805.0,14680.0,14765.0,16240.0,13285.0,23749,18369,2024-07-10 21:58:42,主力,合成橡胶2408,br2408,br,2408
|
||||
10,沥青2409(bu2409),3634.0,1.0,0%,3633.0,3652.0,3629.0,3650.0,3942.0,3358.0,208645,46335,2024-07-10 21:58:42,主力,沥青2409,bu2409,bu,2409
|
||||
11,玉米2409(c2409),2423.0,3.0,0.1%,2420.0,2427.0,2420.0,2424.0,2569.0,2279.0,772305,94934,2024-07-10 21:58:42,主力,玉米2409,c2409,c,2409
|
||||
12,棉花409(CF409),14530.0,105.0,0.7%,14425.0,14560.0,14425.0,14470.0,15340.0,13600.0,518618,103523,2024-07-10 21:58:41,主力,棉花409,CF409,CF,409
|
||||
13,红枣409(CJ409),10420.0,5.0,0%,10415.0,10480.0,10130.0,10325.0,11565.0,9085.0,59460,53341,2024-07-10 20:53:24,主力,红枣409,CJ409,CJ,409
|
||||
14,玉米淀粉2409(cs2409),2876.0,2.0,0.1%,2874.0,2884.0,2872.0,2893.0,3037.0,2749.0,155619,34899,2024-07-10 21:58:42,主力,玉米淀粉2409,cs2409,cs,2409
|
||||
15,沪铜2408(cu2408),80190.0,220.0,0.3%,79970.0,80300.0,79870.0,79870.0,85460.0,74270.0,196248,17954,2024-07-10 21:58:42,主力,沪铜2408,cu2408,cu,2408
|
||||
16,棉纱409(CY409),20135.0,60.0,0.3%,20075.0,20165.0,20030.0,20125.0,21335.0,18915.0,4977,609,2024-07-10 21:58:33,主力,棉纱409,CY409,CY,409
|
||||
17,苯乙烯2408(eb2408),9352.0,43.0,0.5%,9309.0,9376.0,9300.0,9302.0,9953.0,8651.0,260194,112788,2024-07-10 21:58:43,主力,苯乙烯2408,eb2408,eb,2408
|
||||
18,集运指数2410(ec2410),4435.0,35.0,0.8%,4400.0,4618.8,4355.0,4482.0,5199.1,3764.8,28743,45054,2024-07-10 20:53:13,主力,集运指数2410,ec2410,ec,2410
|
||||
19,乙二醇2409(eg2409),4774.0,51.0,1.1%,4723.0,4788.0,4722.0,4714.0,5043.0,4385.0,462368,177134,2024-07-10 21:58:41,主力,乙二醇2409,eg2409,eg,2409
|
||||
20,纤维板2409(fb2409),1286.5,-1.5,-0.1%,1288.0,1300.0,1283.0,1288.5,1352.5,1224.5,1472,3225,2024-07-10 20:53:12,主力,纤维板2409,fb2409,fb,2409
|
||||
21,玻璃409(FG409),1473.0,3.0,0.2%,1470.0,1474.0,1462.0,1477.0,1625.0,1329.0,701892,117098,2024-07-10 21:58:42,主力,玻璃409,FG409,FG,409
|
||||
22,燃油2409(fu2409),3514.0,7.0,0.2%,3507.0,3517.0,3496.0,3528.0,3810.0,3245.0,233905,120845,2024-07-10 21:58:41,主力,燃油2409,fu2409,fu,2409
|
||||
23,热卷2410(hc2410),3691.0,9.0,0.2%,3682.0,3694.0,3681.0,3694.0,3878.0,3509.0,1069877,64407,2024-07-10 21:58:44,主力,热卷2410,hc2410,hc,2410
|
||||
24,铁矿石2409(i2409),820.0,6.5,0.8%,813.5,821.0,813.5,821.5,911.5,731.5,341446,60834,2024-07-10 21:58:43,主力,铁矿石2409,i2409,i,2409
|
||||
25,中证500指数2407(IC2407),4831.4,-22.4,-0.5%,4853.8,4881.8,4827.0,4862.8,5349.0,4376.6,73064,40434,2024-07-10 15:24:13,主力,中证500指数2407,IC2407,IC,2407
|
||||
26,沪深300指数2407(IF2407),3412.4,-3.6,-0.1%,3416.0,3432.0,3409.0,3422.0,3764.2,3079.8,75866,39700,2024-07-10 15:24:13,主力,沪深300指数2407,IF2407,IF,2407
|
||||
27,上证50指数2407(IH2407),2364.4,-0.2,-0%,2364.6,2375.0,2361.8,2370.0,2607.0,2133.0,36666,20718,2024-07-10 15:24:13,主力,上证50指数2407,IH2407,IH,2407
|
||||
28,中证股指期货2407(IM2407),4758.0,2.2,0%,4755.8,4813.6,4747.8,4776.0,5253.6,4298.4,90954,83873,2024-07-10 15:24:13,主力,中证股指期货2407,IM2407,IM,2407
|
||||
29,焦炭2409(j2409),2226.5,10.0,0.5%,2216.5,2228.0,2211.5,2221.5,2399.0,2044.0,26714,3402,2024-07-10 21:58:41,主力,焦炭2409,j2409,j,2409
|
||||
30,鸡蛋2409(jd2409),4062.0,-28.0,-0.7%,4090.0,4092.0,4021.0,4056.0,4299.0,3813.0,178656,241161,2024-07-10 20:53:19,主力,鸡蛋2409,jd2409,jd,2409
|
||||
31,焦煤2409(jm2409),1546.0,8.0,0.5%,1538.0,1548.0,1534.0,1543.5,1666.5,1420.5,160798,21409,2024-07-10 21:58:41,主力,焦煤2409,jm2409,jm,2409
|
||||
32,塑料2409(l2409),8412.0,17.0,0.2%,8395.0,8418.0,8384.0,8413.0,8917.0,7909.0,403983,62527,2024-07-10 21:58:42,主力,塑料2409,l2409,l,2409
|
||||
33,碳酸锂2411(lc2411),91800.0,-2100.0,-2.2%,93900.0,94400.0,91600.0,93900.0,103250.0,84550.0,176216,149171,2024-07-10 15:00:27,主力,碳酸锂2411,lc2411,lc,2411
|
||||
34,生猪2409(lh2409),17510.0,-500.0,-2.8%,18010.0,18030.0,17505.0,17760.0,18825.0,16695.0,63950,60992,2024-07-10 20:53:20,主力,生猪2409,lh2409,lh,2409
|
||||
35,低硫燃料油2409(lu2409),4319.0,14.0,0.3%,4305.0,4323.0,4295.0,4329.0,4675.0,3982.0,63705,20408,2024-07-10 21:58:44,主力,低硫燃料油2409,lu2409,lu,2409
|
||||
36,豆粕2409(m2409),3235.0,-6.0,-0.2%,3241.0,3248.0,3230.0,3230.0,3423.0,3037.0,1581523,202682,2024-07-10 21:58:43,主力,豆粕2409,m2409,m,2409
|
||||
37,甲醇409(MA409),2569.0,25.0,1%,2544.0,2574.0,2542.0,2538.0,2716.0,2360.0,746529,328085,2024-07-10 21:58:44,主力,甲醇409,MA409,MA,409
|
||||
38,沪镍2409(ni2409),134370.0,340.0,0.3%,134030.0,134790.0,134010.0,135270.0,148790.0,121740.0,120389,31972,2024-07-10 21:58:42,主力,沪镍2409,ni2409,ni,2409
|
||||
39,20号胶2409(nr2409),12315.0,35.0,0.3%,12280.0,12370.0,12275.0,12270.0,13005.0,11530.0,67524,16767,2024-07-10 21:58:44,主力,20号胶2409,nr2409,nr,2409
|
||||
40,菜籽油409(OI409),8309.0,-21.0,-0.3%,8330.0,8344.0,8283.0,8377.0,8880.0,7874.0,288033,146832,2024-07-10 21:58:43,主力,菜籽油409,OI409,OI,409
|
||||
41,棕榈油2409(p2409),7662.0,12.0,0.2%,7650.0,7692.0,7638.0,7648.0,8182.0,7114.0,432148,173591,2024-07-10 21:58:42,主力,棕榈油2409,p2409,p,2409
|
||||
42,沪铅2408(pb2408),19460.0,5.0,0%,19455.0,19520.0,19360.0,19480.0,20840.0,18115.0,87358,29903,2024-07-10 21:58:41,主力,沪铅2408,pb2408,pb,2408
|
||||
43,短纤409(PF409),7588.0,28.0,0.4%,7560.0,7594.0,7548.0,7572.0,8104.0,7040.0,140607,24507,2024-07-10 21:58:40,主力,短纤409,PF409,PF,409
|
||||
44,液化石油气2409(pg2409),4557.0,31.0,0.7%,4526.0,4562.0,4522.0,4548.0,4866.0,4230.0,78155,21277,2024-07-10 21:58:43,主力,液化石油气2409,pg2409,pg,2409
|
||||
45,花生410(PK410),8670.0,-54.0,-0.6%,8724.0,8740.0,8612.0,8676.0,9284.0,8068.0,133417,82137,2024-07-10 20:53:11,主力,花生410,PK410,PK,410
|
||||
46,聚丙烯2409(pp2409),7704.0,34.0,0.4%,7670.0,7708.0,7670.0,7689.0,8150.0,7228.0,401883,73091,2024-07-10 21:58:43,主力,聚丙烯2409,pp2409,pp,2409
|
||||
47,对二甲苯 409(PX409),8518.0,28.0,0.3%,8490.0,8522.0,8488.0,8500.0,9096.0,7904.0,73855,8131,2024-07-10 21:58:42,主力,对二甲苯 409,PX409,PX,409
|
||||
48,螺纹钢2410(rb2410),3495.0,9.0,0.3%,3486.0,3497.0,3480.0,3492.0,3666.0,3317.0,2246168,244244,2024-07-10 21:58:42,主力,螺纹钢2410,rb2410,rb,2410
|
||||
49,菜籽粕409(RM409),2515.0,-13.0,-0.5%,2528.0,2530.0,2509.0,2520.0,2672.0,2368.0,1011648,176386,2024-07-10 21:58:43,主力,菜籽粕409,RM409,RM,409
|
||||
50,粳米2409(rr2409),3486.0,1.0,0%,3485.0,3486.0,3483.0,3485.0,3659.0,3311.0,5211,419,2024-07-10 21:55:03,主力,粳米2409,rr2409,rr,2409
|
||||
51,油菜籽411(RS411),5146.0,-166.0,-3.1%,5312.0,5335.0,5140.0,5216.0,5738.0,4694.0,155,85,2024-07-10 20:53:12,主力,油菜籽411,RS411,RS,411
|
||||
52,橡胶2409(ru2409),14690.0,30.0,0.2%,14660.0,14715.0,14645.0,14645.0,15520.0,13765.0,212409,52408,2024-07-10 21:58:42,主力,橡胶2409,ru2409,ru,2409
|
||||
53,纯碱409(SA409),1956.0,-2.0,-0.1%,1958.0,1961.0,1945.0,2003.0,2204.0,1802.0,820754,237739,2024-07-10 21:58:41,主力,纯碱409,SA409,SA,409
|
||||
54,原油2408(sc2408),617.1,0.9,0.1%,616.2,617.7,614.5,621.3,671.0,571.5,25621,15352,2024-07-10 21:58:43,主力,原油2408,sc2408,sc,2408
|
||||
55,硅铁409(SF409),6672.0,-34.0,-0.5%,6706.0,6756.0,6652.0,6696.0,7232.0,6160.0,163656,76007,2024-07-10 20:53:22,主力,硅铁409,SF409,SF,409
|
||||
56,烧碱 409(SH409),2574.0,-6.0,-0.2%,2580.0,2588.0,2564.0,2582.0,2763.0,2401.0,56255,11898,2024-07-10 21:58:41,主力,烧碱 409,SH409,SH,409
|
||||
57,工业硅2409(si2409),11110.0,-180.0,-1.6%,11290.0,11295.0,11095.0,11200.0,11980.0,10420.0,236506,153139,2024-07-10 15:00:27,主力,工业硅2409,si2409,si,2409
|
||||
58,锰硅501(SM501),7324.0,-214.0,-2.8%,7538.0,7598.0,7280.0,7412.0,8154.0,6670.0,279664,291395,2024-07-10 20:53:20,主力,锰硅501,SM501,SM,501
|
||||
59,沪锡2408(sn2408),282070.0,2530.0,0.9%,279540.0,282880.0,279500.0,278190.0,306000.0,250370.0,37361,54822,2024-07-10 21:58:44,主力,沪锡2408,sn2408,sn,2408
|
||||
60,纸浆2409(sp2409),5672.0,14.0,0.2%,5658.0,5684.0,5656.0,5694.0,6034.0,5352.0,264768,50733,2024-07-10 21:58:44,主力,纸浆2409,sp2409,sp,2409
|
||||
61,白糖409(SR409),6187.0,17.0,0.3%,6170.0,6191.0,6163.0,6174.0,6545.0,5803.0,313149,89315,2024-07-10 21:58:44,主力,白糖409,SR409,SR,409
|
||||
62,不锈钢2409(ss2409),13930.0,0.0,0%,13930.0,13960.0,13905.0,13980.0,14675.0,13280.0,142308,29073,2024-07-10 21:58:43,主力,不锈钢2409,ss2409,ss,2409
|
||||
63,10年国债2409(T2409),105.11,0.0,0%,105.085,105.145,105.035,105.065,107.165,102.965,188590,29670,2024-07-10 15:24:13,主力,10年国债2409,T2409,T,2409
|
||||
64,PTA409(TA409),5910.0,18.0,0.3%,5892.0,5912.0,5892.0,5902.0,6258.0,5546.0,892109,96388,2024-07-10 21:58:42,主力,PTA409,TA409,TA,409
|
||||
65,5年期国债2409(TF2409),103.865,0.1,0.1%,103.81,103.89,103.8,103.84,105.085,102.595,116126,25935,2024-07-10 15:24:13,主力,5年期国债2409,TF2409,TF,2409
|
||||
66,30年期国债期货2409(TL2409),108.46,0.1,0.1%,108.35,108.5,108.27,108.34,112.13,104.55,75624,29336,2024-07-10 15:24:13,主力,30年期国债期货2409,TL2409,TL,2409
|
||||
67,2年期国债2409(TS2409),101.938,0.0,0%,101.918,101.946,101.91,101.922,102.43,101.414,54860,20514,2024-07-10 15:24:13,主力,2年期国债2409,TS2409,TS,2409
|
||||
68,尿素409(UR409),2055.0,-22.0,-1.1%,2077.0,2080.0,2050.0,2061.0,2247.0,1875.0,185561,178245,2024-07-10 20:53:21,主力,尿素409,UR409,UR,409
|
||||
69,PVC2409(v2409),5904.0,2.0,0%,5902.0,5907.0,5875.0,5924.0,6279.0,5569.0,951642,162407,2024-07-10 21:58:43,主力,PVC2409,v2409,v,2409
|
||||
70,线材2409(wr2409),3660.0,-25.0,-0.7%,3685.0,3685.0,3655.0,3661.0,3917.0,3404.0,689,190,2024-07-10 21:38:55,主力,线材2409,wr2409,wr,2409
|
||||
71,豆油2409(y2409),7606.0,0.0,0%,7606.0,7622.0,7580.0,7638.0,8096.0,7180.0,644683,106957,2024-07-10 21:58:43,主力,豆油2409,y2409,y,2409
|
||||
72,沪锌2408(zn2408),24370.0,160.0,0.7%,24210.0,24395.0,24205.0,24240.0,25935.0,22540.0,75969,37672,2024-07-10 21:58:41,主力,沪锌2408,zn2408,zn,2408
|
||||
|
@@ -0,0 +1,74 @@
|
||||
,合约,最新价,涨跌,涨跌幅,开盘价,最高价,最低价,昨收价,涨停价,跌停价,最新持仓,成交量,更新时间,说明,交易品种,主连代码,品种代码,交割月份
|
||||
0,豆一2409(a2409),4623.0,-12.0,-0.3%,4635.0,4641.0,4620.0,4632.0,4909.0,4355.0,131113,17837,2024-07-10 21:58:41,主力,豆一2409,a2409,a,2409
|
||||
1,白银2408(ag2408),8197.0,37.0,0.5%,8160.0,8207.0,8138.0,8112.0,8923.0,7300.0,275003,186519,2024-07-10 21:58:43,主力,白银2408,ag2408,ag,2408
|
||||
2,沪铝2408(al2408),20195.0,55.0,0.3%,20140.0,20265.0,20140.0,20250.0,21665.0,18830.0,156460,42560,2024-07-10 21:58:42,主力,沪铝2408,al2408,al,2408
|
||||
3,氧化铝2408(ao2408),3688.0,-62.0,-1.7%,3750.0,3757.0,3667.0,3793.0,4058.0,3527.0,45211,70246,2024-07-10 21:58:42,主力,氧化铝2408,ao2408,ao,2408
|
||||
4,苹果410(AP410),6926.0,36.0,0.5%,6890.0,6932.0,6842.0,6896.0,7517.0,6275.0,167339,107790,2024-07-10 20:53:26,主力,苹果410,AP410,AP,410
|
||||
5,黄金2410(au2410),566.08,1.3,0.2%,564.8,566.48,564.16,561.22,617.34,505.08,140030,23597,2024-07-10 21:58:42,主力,黄金2410,au2410,au,2410
|
||||
6,豆二2409(b2409),3739.0,-7.0,-0.2%,3746.0,3753.0,3730.0,3752.0,3977.0,3527.0,116847,31830,2024-07-10 21:58:38,主力,豆二2409,b2409,b,2409
|
||||
7,胶板2501(bb2501),191.0,-5.4,-2.7%,196.4,196.4,191.0,193.05,202.7,183.4,60,10,2024-07-10 20:53:13,主力,胶板2501,bb2501,bb,2501
|
||||
8,国际铜2408(bc2408),71530.0,310.0,0.4%,71220.0,71640.0,71140.0,71230.0,76210.0,66240.0,6864,2014,2024-07-10 21:58:43,主力,国际铜2408,bc2408,bc,2408
|
||||
9,合成橡胶2408(br2408),14760.0,80.0,0.5%,14680.0,14805.0,14680.0,14765.0,16240.0,13285.0,23749,18369,2024-07-10 21:58:42,主力,合成橡胶2408,br2408,br,2408
|
||||
10,沥青2409(bu2409),3634.0,1.0,0%,3633.0,3652.0,3629.0,3650.0,3942.0,3358.0,208645,46335,2024-07-10 21:58:42,主力,沥青2409,bu2409,bu,2409
|
||||
11,玉米2409(c2409),2423.0,3.0,0.1%,2420.0,2427.0,2420.0,2424.0,2569.0,2279.0,772305,94934,2024-07-10 21:58:42,主力,玉米2409,c2409,c,2409
|
||||
12,棉花409(CF409),14530.0,105.0,0.7%,14425.0,14560.0,14425.0,14470.0,15340.0,13600.0,518618,103523,2024-07-10 21:58:41,主力,棉花409,CF409,CF,409
|
||||
13,红枣409(CJ409),10420.0,5.0,0%,10415.0,10480.0,10130.0,10325.0,11565.0,9085.0,59460,53341,2024-07-10 20:53:24,主力,红枣409,CJ409,CJ,409
|
||||
14,玉米淀粉2409(cs2409),2876.0,2.0,0.1%,2874.0,2884.0,2872.0,2893.0,3037.0,2749.0,155619,34899,2024-07-10 21:58:42,主力,玉米淀粉2409,cs2409,cs,2409
|
||||
15,沪铜2408(cu2408),80190.0,220.0,0.3%,79970.0,80300.0,79870.0,79870.0,85460.0,74270.0,196248,17954,2024-07-10 21:58:42,主力,沪铜2408,cu2408,cu,2408
|
||||
16,棉纱409(CY409),20135.0,60.0,0.3%,20075.0,20165.0,20030.0,20125.0,21335.0,18915.0,4977,609,2024-07-10 21:58:33,主力,棉纱409,CY409,CY,409
|
||||
17,苯乙烯2408(eb2408),9352.0,43.0,0.5%,9309.0,9376.0,9300.0,9302.0,9953.0,8651.0,260194,112788,2024-07-10 21:58:43,主力,苯乙烯2408,eb2408,eb,2408
|
||||
18,集运指数2410(ec2410),4435.0,35.0,0.8%,4400.0,4618.8,4355.0,4482.0,5199.1,3764.8,28743,45054,2024-07-10 20:53:13,主力,集运指数2410,ec2410,ec,2410
|
||||
19,乙二醇2409(eg2409),4774.0,51.0,1.1%,4723.0,4788.0,4722.0,4714.0,5043.0,4385.0,462368,177134,2024-07-10 21:58:41,主力,乙二醇2409,eg2409,eg,2409
|
||||
20,纤维板2409(fb2409),1286.5,-1.5,-0.1%,1288.0,1300.0,1283.0,1288.5,1352.5,1224.5,1472,3225,2024-07-10 20:53:12,主力,纤维板2409,fb2409,fb,2409
|
||||
21,玻璃409(FG409),1473.0,3.0,0.2%,1470.0,1474.0,1462.0,1477.0,1625.0,1329.0,701892,117098,2024-07-10 21:58:42,主力,玻璃409,FG409,FG,409
|
||||
22,燃油2409(fu2409),3514.0,7.0,0.2%,3507.0,3517.0,3496.0,3528.0,3810.0,3245.0,233905,120845,2024-07-10 21:58:41,主力,燃油2409,fu2409,fu,2409
|
||||
23,热卷2410(hc2410),3691.0,9.0,0.2%,3682.0,3694.0,3681.0,3694.0,3878.0,3509.0,1069877,64407,2024-07-10 21:58:44,主力,热卷2410,hc2410,hc,2410
|
||||
24,铁矿石2409(i2409),820.0,6.5,0.8%,813.5,821.0,813.5,821.5,911.5,731.5,341446,60834,2024-07-10 21:58:43,主力,铁矿石2409,i2409,i,2409
|
||||
25,中证500指数2407(IC2407),4831.4,-22.4,-0.5%,4853.8,4881.8,4827.0,4862.8,5349.0,4376.6,73064,40434,2024-07-10 15:24:13,主力,中证500指数2407,IC2407,IC,2407
|
||||
26,沪深300指数2407(IF2407),3412.4,-3.6,-0.1%,3416.0,3432.0,3409.0,3422.0,3764.2,3079.8,75866,39700,2024-07-10 15:24:13,主力,沪深300指数2407,IF2407,IF,2407
|
||||
27,上证50指数2407(IH2407),2364.4,-0.2,-0%,2364.6,2375.0,2361.8,2370.0,2607.0,2133.0,36666,20718,2024-07-10 15:24:13,主力,上证50指数2407,IH2407,IH,2407
|
||||
28,中证股指期货2407(IM2407),4758.0,2.2,0%,4755.8,4813.6,4747.8,4776.0,5253.6,4298.4,90954,83873,2024-07-10 15:24:13,主力,中证股指期货2407,IM2407,IM,2407
|
||||
29,焦炭2409(j2409),2226.5,10.0,0.5%,2216.5,2228.0,2211.5,2221.5,2399.0,2044.0,26714,3402,2024-07-10 21:58:41,主力,焦炭2409,j2409,j,2409
|
||||
30,鸡蛋2409(jd2409),4062.0,-28.0,-0.7%,4090.0,4092.0,4021.0,4056.0,4299.0,3813.0,178656,241161,2024-07-10 20:53:19,主力,鸡蛋2409,jd2409,jd,2409
|
||||
31,焦煤2409(jm2409),1546.0,8.0,0.5%,1538.0,1548.0,1534.0,1543.5,1666.5,1420.5,160798,21409,2024-07-10 21:58:41,主力,焦煤2409,jm2409,jm,2409
|
||||
32,塑料2409(l2409),8412.0,17.0,0.2%,8395.0,8418.0,8384.0,8413.0,8917.0,7909.0,403983,62527,2024-07-10 21:58:42,主力,塑料2409,l2409,l,2409
|
||||
33,碳酸锂2411(lc2411),91800.0,-2100.0,-2.2%,93900.0,94400.0,91600.0,93900.0,103250.0,84550.0,176216,149171,2024-07-10 15:00:27,主力,碳酸锂2411,lc2411,lc,2411
|
||||
34,生猪2409(lh2409),17510.0,-500.0,-2.8%,18010.0,18030.0,17505.0,17760.0,18825.0,16695.0,63950,60992,2024-07-10 20:53:20,主力,生猪2409,lh2409,lh,2409
|
||||
35,低硫燃料油2409(lu2409),4319.0,14.0,0.3%,4305.0,4323.0,4295.0,4329.0,4675.0,3982.0,63705,20408,2024-07-10 21:58:44,主力,低硫燃料油2409,lu2409,lu,2409
|
||||
36,豆粕2409(m2409),3235.0,-6.0,-0.2%,3241.0,3248.0,3230.0,3230.0,3423.0,3037.0,1581523,202682,2024-07-10 21:58:43,主力,豆粕2409,m2409,m,2409
|
||||
37,甲醇409(MA409),2569.0,25.0,1%,2544.0,2574.0,2542.0,2538.0,2716.0,2360.0,746529,328085,2024-07-10 21:58:44,主力,甲醇409,MA409,MA,409
|
||||
38,沪镍2409(ni2409),134370.0,340.0,0.3%,134030.0,134790.0,134010.0,135270.0,148790.0,121740.0,120389,31972,2024-07-10 21:58:42,主力,沪镍2409,ni2409,ni,2409
|
||||
39,20号胶2409(nr2409),12315.0,35.0,0.3%,12280.0,12370.0,12275.0,12270.0,13005.0,11530.0,67524,16767,2024-07-10 21:58:44,主力,20号胶2409,nr2409,nr,2409
|
||||
40,菜籽油409(OI409),8309.0,-21.0,-0.3%,8330.0,8344.0,8283.0,8377.0,8880.0,7874.0,288033,146832,2024-07-10 21:58:43,主力,菜籽油409,OI409,OI,409
|
||||
41,棕榈油2409(p2409),7662.0,12.0,0.2%,7650.0,7692.0,7638.0,7648.0,8182.0,7114.0,432148,173591,2024-07-10 21:58:42,主力,棕榈油2409,p2409,p,2409
|
||||
42,沪铅2408(pb2408),19460.0,5.0,0%,19455.0,19520.0,19360.0,19480.0,20840.0,18115.0,87358,29903,2024-07-10 21:58:41,主力,沪铅2408,pb2408,pb,2408
|
||||
43,短纤409(PF409),7588.0,28.0,0.4%,7560.0,7594.0,7548.0,7572.0,8104.0,7040.0,140607,24507,2024-07-10 21:58:40,主力,短纤409,PF409,PF,409
|
||||
44,液化石油气2409(pg2409),4557.0,31.0,0.7%,4526.0,4562.0,4522.0,4548.0,4866.0,4230.0,78155,21277,2024-07-10 21:58:43,主力,液化石油气2409,pg2409,pg,2409
|
||||
45,花生410(PK410),8670.0,-54.0,-0.6%,8724.0,8740.0,8612.0,8676.0,9284.0,8068.0,133417,82137,2024-07-10 20:53:11,主力,花生410,PK410,PK,410
|
||||
46,聚丙烯2409(pp2409),7704.0,34.0,0.4%,7670.0,7708.0,7670.0,7689.0,8150.0,7228.0,401883,73091,2024-07-10 21:58:43,主力,聚丙烯2409,pp2409,pp,2409
|
||||
47,对二甲苯 409(PX409),8518.0,28.0,0.3%,8490.0,8522.0,8488.0,8500.0,9096.0,7904.0,73855,8131,2024-07-10 21:58:42,主力,对二甲苯 409,PX409,PX,409
|
||||
48,螺纹钢2410(rb2410),3495.0,9.0,0.3%,3486.0,3497.0,3480.0,3492.0,3666.0,3317.0,2246168,244244,2024-07-10 21:58:42,主力,螺纹钢2410,rb2410,rb,2410
|
||||
49,菜籽粕409(RM409),2515.0,-13.0,-0.5%,2528.0,2530.0,2509.0,2520.0,2672.0,2368.0,1011648,176386,2024-07-10 21:58:43,主力,菜籽粕409,RM409,RM,409
|
||||
50,粳米2409(rr2409),3486.0,1.0,0%,3485.0,3486.0,3483.0,3485.0,3659.0,3311.0,5211,419,2024-07-10 21:55:03,主力,粳米2409,rr2409,rr,2409
|
||||
51,油菜籽411(RS411),5146.0,-166.0,-3.1%,5312.0,5335.0,5140.0,5216.0,5738.0,4694.0,155,85,2024-07-10 20:53:12,主力,油菜籽411,RS411,RS,411
|
||||
52,橡胶2409(ru2409),14690.0,30.0,0.2%,14660.0,14715.0,14645.0,14645.0,15520.0,13765.0,212409,52408,2024-07-10 21:58:42,主力,橡胶2409,ru2409,ru,2409
|
||||
53,纯碱409(SA409),1956.0,-2.0,-0.1%,1958.0,1961.0,1945.0,2003.0,2204.0,1802.0,820754,237739,2024-07-10 21:58:41,主力,纯碱409,SA409,SA,409
|
||||
54,原油2408(sc2408),617.1,0.9,0.1%,616.2,617.7,614.5,621.3,671.0,571.5,25621,15352,2024-07-10 21:58:43,主力,原油2408,sc2408,sc,2408
|
||||
55,硅铁409(SF409),6672.0,-34.0,-0.5%,6706.0,6756.0,6652.0,6696.0,7232.0,6160.0,163656,76007,2024-07-10 20:53:22,主力,硅铁409,SF409,SF,409
|
||||
56,烧碱 409(SH409),2574.0,-6.0,-0.2%,2580.0,2588.0,2564.0,2582.0,2763.0,2401.0,56255,11898,2024-07-10 21:58:41,主力,烧碱 409,SH409,SH,409
|
||||
57,工业硅2409(si2409),11110.0,-180.0,-1.6%,11290.0,11295.0,11095.0,11200.0,11980.0,10420.0,236506,153139,2024-07-10 15:00:27,主力,工业硅2409,si2409,si,2409
|
||||
58,锰硅501(SM501),7324.0,-214.0,-2.8%,7538.0,7598.0,7280.0,7412.0,8154.0,6670.0,279664,291395,2024-07-10 20:53:20,主力,锰硅501,SM501,SM,501
|
||||
59,沪锡2408(sn2408),282070.0,2530.0,0.9%,279540.0,282880.0,279500.0,278190.0,306000.0,250370.0,37361,54822,2024-07-10 21:58:44,主力,沪锡2408,sn2408,sn,2408
|
||||
60,纸浆2409(sp2409),5672.0,14.0,0.2%,5658.0,5684.0,5656.0,5694.0,6034.0,5352.0,264768,50733,2024-07-10 21:58:44,主力,纸浆2409,sp2409,sp,2409
|
||||
61,白糖409(SR409),6187.0,17.0,0.3%,6170.0,6191.0,6163.0,6174.0,6545.0,5803.0,313149,89315,2024-07-10 21:58:44,主力,白糖409,SR409,SR,409
|
||||
62,不锈钢2409(ss2409),13930.0,0.0,0%,13930.0,13960.0,13905.0,13980.0,14675.0,13280.0,142308,29073,2024-07-10 21:58:43,主力,不锈钢2409,ss2409,ss,2409
|
||||
63,10年国债2409(T2409),105.11,0.0,0%,105.085,105.145,105.035,105.065,107.165,102.965,188590,29670,2024-07-10 15:24:13,主力,10年国债2409,T2409,T,2409
|
||||
64,PTA409(TA409),5910.0,18.0,0.3%,5892.0,5912.0,5892.0,5902.0,6258.0,5546.0,892109,96388,2024-07-10 21:58:42,主力,PTA409,TA409,TA,409
|
||||
65,5年期国债2409(TF2409),103.865,0.1,0.1%,103.81,103.89,103.8,103.84,105.085,102.595,116126,25935,2024-07-10 15:24:13,主力,5年期国债2409,TF2409,TF,2409
|
||||
66,30年期国债期货2409(TL2409),108.46,0.1,0.1%,108.35,108.5,108.27,108.34,112.13,104.55,75624,29336,2024-07-10 15:24:13,主力,30年期国债期货2409,TL2409,TL,2409
|
||||
67,2年期国债2409(TS2409),101.938,0.0,0%,101.918,101.946,101.91,101.922,102.43,101.414,54860,20514,2024-07-10 15:24:13,主力,2年期国债2409,TS2409,TS,2409
|
||||
68,尿素409(UR409),2055.0,-22.0,-1.1%,2077.0,2080.0,2050.0,2061.0,2247.0,1875.0,185561,178245,2024-07-10 20:53:21,主力,尿素409,UR409,UR,409
|
||||
69,PVC2409(v2409),5904.0,2.0,0%,5902.0,5907.0,5875.0,5924.0,6279.0,5569.0,951642,162407,2024-07-10 21:58:43,主力,PVC2409,v2409,v,2409
|
||||
70,线材2409(wr2409),3660.0,-25.0,-0.7%,3685.0,3685.0,3655.0,3661.0,3917.0,3404.0,689,190,2024-07-10 21:38:55,主力,线材2409,wr2409,wr,2409
|
||||
71,豆油2409(y2409),7606.0,0.0,0%,7606.0,7622.0,7580.0,7638.0,8096.0,7180.0,644683,106957,2024-07-10 21:58:43,主力,豆油2409,y2409,y,2409
|
||||
72,沪锌2408(zn2408),24370.0,160.0,0.7%,24210.0,24395.0,24205.0,24240.0,25935.0,22540.0,75969,37672,2024-07-10 21:58:41,主力,沪锌2408,zn2408,zn,2408
|
||||
|
@@ -0,0 +1,179 @@
|
||||
import subprocess
|
||||
import schedule
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
# jerome:增加akshare库
|
||||
import akshare as ak
|
||||
|
||||
# jerome:增加下列库用于爬虫获取主力连续代码
|
||||
import pandas as pd
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
import csv
|
||||
import re
|
||||
import os
|
||||
# jerome:增加文件名修改工作
|
||||
import shutil
|
||||
|
||||
# Jerome:需要设置的参数
|
||||
new_directory = r"C:/simnow_trader" #设置运行目录为程序所在目录new_directory
|
||||
# 定义要启动的文件
|
||||
files_to_run = ['dingdanliu_nb.py']
|
||||
# 定义生成的保证金、手续费csv文件
|
||||
fees_filepath = r'./futures_fees_info.csv'
|
||||
contracts_filepath = r'./main_contacts.csv'
|
||||
contracts_yd_filepath = r'./main_contacts_yd.csv'
|
||||
exchange_filepath = r'./exchange_for_months.csv'
|
||||
|
||||
|
||||
|
||||
# jerome:修改运行目录
|
||||
# 获取当前工作目录
|
||||
current_directory = os.getcwd()
|
||||
print("当前工作目录:", current_directory)
|
||||
# 设置新的工作目录
|
||||
os.chdir(new_directory)
|
||||
# 验证新的工作目录
|
||||
updated_directory = os.getcwd()
|
||||
print("已更改为新的工作目录:", updated_directory)
|
||||
|
||||
def run_scripts():
|
||||
print("启动程序...")
|
||||
for file in files_to_run:
|
||||
time.sleep(1)
|
||||
# 使用subprocess模块运行命令
|
||||
subprocess.Popen(['start', 'cmd', '/k', 'python', file], shell=True)
|
||||
print(file)
|
||||
print(datetime.now(),'程序重新启动完成,等待明天关闭重启')
|
||||
|
||||
def close_scripts():
|
||||
print("关闭程序...")
|
||||
# 通过创建一个包含关闭指定窗口命令的批处理文件来关闭CMD窗口
|
||||
def close_specific_cmd_window(cmd_window_title):
|
||||
with open("close_cmd_window.bat", "w") as batch_file:
|
||||
batch_file.write(f'@echo off\nfor /f "tokens=2 delims=," %%a in (\'tasklist /v /fo csv ^| findstr /i "{cmd_window_title}"\') do taskkill /pid %%~a')
|
||||
|
||||
# 运行批处理文件
|
||||
subprocess.run("close_cmd_window.bat", shell=True)
|
||||
|
||||
|
||||
# 循环关闭所有脚本对应的CMD窗口
|
||||
for title in files_to_run:
|
||||
close_specific_cmd_window(title)
|
||||
print(datetime.now(),'已关闭程序,等待重新运行程序')
|
||||
|
||||
# jerome:增加使用akshare获取期货的手续费等数据,并保存到对应目录下
|
||||
def get_futures_fees_info():
|
||||
futures_fees_info_df = ak.futures_fees_info()
|
||||
futures_fees_info_df[['品种代码', '交割月份']] = futures_fees_info_df['合约代码'].apply(lambda x: pd.Series(split_alpha_numeric(x)))
|
||||
futures_fees_info_df.to_csv(fees_filepath, index=False)
|
||||
print("期货保证金、手续费csv文件已经保存!")
|
||||
|
||||
def get_main_contacts():
|
||||
url = "https://www.9qihuo.com/hangqing"
|
||||
|
||||
# 发送GET请求,禁用SSL验证
|
||||
response = requests.get(url, verify=False)
|
||||
response.encoding = 'utf-8' # 确保编码正确
|
||||
|
||||
# 解析网页内容
|
||||
soup = BeautifulSoup(response.text, 'lxml')
|
||||
|
||||
# 找到目标表格
|
||||
table = soup.find('table', {'id': 'tblhangqinglist'})
|
||||
|
||||
# 初始化CSV文件
|
||||
with open(r'./tmp_main_contacts.csv', mode='w', newline='', encoding='utf-8') as file:
|
||||
writer = csv.writer(file)
|
||||
|
||||
# 遍历表格的所有行
|
||||
for row in table.find_all('tr'):
|
||||
# 获取每一行的所有单元格
|
||||
cols = row.find_all(['th', 'td'])
|
||||
# 提取文本内容并写入CSV文件
|
||||
writer.writerow([col.text.strip() for col in cols])
|
||||
|
||||
df = pd.read_csv(r'./tmp_main_contacts.csv',encoding='utf-8')
|
||||
df['交易品种'] = df['合约'].str.split(r'[()]', n=1, expand=True)[0]
|
||||
df['主连代码'] = df['合约'].str.split(r'[()]', n=2, expand=True)[1]
|
||||
|
||||
df[['品种代码', '交割月份']] = df['主连代码'].apply(lambda x: pd.Series(split_alpha_numeric(x)))
|
||||
if os.path.exists(contracts_filepath):
|
||||
os.remove(contracts_filepath)
|
||||
print("原有今日期货主连csv文件已经删除!")
|
||||
|
||||
df.to_csv(r'./main_contacts.csv')
|
||||
os.remove(r'./tmp_main_contacts.csv')
|
||||
print("今日期货主连csv文件已经保存!")
|
||||
|
||||
# 拆分字母和数字的函数
|
||||
def split_alpha_numeric(s):
|
||||
match = re.match(r"([a-zA-Z]+)([0-9]+)", s)
|
||||
if match:
|
||||
return match.groups()
|
||||
else:
|
||||
return (s, None) # 如果没有匹配,返回原始字符串和None
|
||||
|
||||
def rename_file():
|
||||
# source_file = r'./main_contacts.csv'
|
||||
# target_file = r'./main_contacts_yd.csv'
|
||||
|
||||
# 检查是否存在 main_contacts_yd.csv,如果存在则删除
|
||||
if os.path.exists(contracts_yd_filepath):
|
||||
os.remove(contracts_yd_filepath)
|
||||
print("原有昨日期货主连csv文件已经删除!")
|
||||
|
||||
shutil.copy(contracts_filepath, contracts_yd_filepath)
|
||||
# print(f"{contracts_filepath} has been copied to {contracts_yd_filepath}")
|
||||
print("今日期货主连csv文件已经修改为昨日主连csv文件!")
|
||||
|
||||
# # 重命名文件
|
||||
# if os.path.exists(source_file):
|
||||
# os.rename(source_file, target_file)
|
||||
# print(f'Renamed {source_file} to {target_file}')
|
||||
# else:
|
||||
# print(f'{source_file} does not exist')
|
||||
|
||||
def exchange_for_months():
|
||||
td_df = pd.read_csv(contracts_filepath, header = 0, usecols= [16, 17],names=['主连代码', '品种代码'])
|
||||
if not os.path.exists(contracts_yd_filepath):
|
||||
shutil.copy(contracts_filepath, contracts_yd_filepath)
|
||||
print("昨日主连csv文件不存在,已经使用今日主连csv替代!")
|
||||
yd_df = pd.read_csv(contracts_yd_filepath, header = 0, usecols= [16, 17],names=['主连代码', '品种代码'])
|
||||
|
||||
# 合并两个 DataFrame
|
||||
merged_df = pd.merge(td_df, yd_df, on='品种代码', suffixes=('_今日', '_昨日'))
|
||||
# 检查 '主连代码' 是否相等
|
||||
merged_df['主连代码_相等'] = merged_df['主连代码_今日'] == merged_df['主连代码_昨日']
|
||||
|
||||
if os.path.exists(exchange_filepath):
|
||||
os.remove(exchange_filepath)
|
||||
print("原有换月对比csv文件已经删除!")
|
||||
merged_df.to_csv(exchange_filepath)
|
||||
print("换月对比csv文件已经生成!")
|
||||
|
||||
# 程序时间建议(以每晚9点交易为最开始时间):1生成费率表和今日主连文件;2生成换月对比文件;3、启动晚间交易程序并登录账户;
|
||||
# 4关闭晚间交易程序;5启动白天交易程序并登录账户;6生成昨日主连文件;7关闭白天交易程序。
|
||||
# 设置定时任务,关闭程序
|
||||
schedule.every().day.at("15:10").do(close_scripts)
|
||||
schedule.every().day.at("03:00").do(close_scripts)
|
||||
|
||||
# 设置定时任务,启动程序
|
||||
schedule.every().day.at("08:55").do(run_scripts)
|
||||
schedule.every().day.at("20:55").do(run_scripts)
|
||||
|
||||
# 设置定时任务,生成费率表文件和今日主连文件
|
||||
schedule.every().day.at("20:53").do(get_futures_fees_info)
|
||||
schedule.every().day.at("20:53").do(get_main_contacts)
|
||||
|
||||
# 设置定时任务,生成换月对比文件
|
||||
schedule.every().day.at("20:55").do(exchange_for_months)
|
||||
|
||||
# 设置定时任务,安排任务每天15:30执行, 生成昨日主连文件
|
||||
schedule.every().day.at("15:05").do(rename_file)
|
||||
|
||||
# 保持脚本运行,等待定时任务触发
|
||||
while True:
|
||||
schedule.run_pending()
|
||||
time.sleep(1)
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user