Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion requirements.txt

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

郑商所的方案也失效了,中金所的当前可用@20250119

Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ psutil
fastapi
uvicorn
itsdangerous
websockets>=9.1
websockets>=9.1
xlrd
30 changes: 7 additions & 23 deletions wtpy/apps/WtBtAnalyst.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,29 +894,13 @@ def strategy_analyze(workbook:Workbook, df_closes, df_trades,df_funds, capital,
策略分析
'''

# 截取开仓明细
data1_open = df_trades[df_trades['action'].apply(lambda x: 'OPEN' in x)].reset_index()
data1_open = data1_open.drop(columns=['index'])
# 截取平仓明细
data1_close = df_trades[df_trades['action'].apply(lambda x: 'CLOSE' in x)].reset_index()
data1_close = data1_close.drop(columns=['index'])

# 将平仓明细字段重命名,并跟开仓明细合并成一个大表
data1_close = data1_close.rename(columns={'code': 'code_1', 'time': 'time_1', 'direct': 'direct_1',
'action': 'action_1', 'price': 'price_1', 'qty': 'qty_1', 'tag': 'tag_1',
'fee': 'fee_1'})

new_data = pd.concat([data1_open, data1_close], axis=1)
new_data = new_data.dropna()
new_data = new_data.drop(columns=['code_1', 'qty_1'])

# 计算开仓平仓手续费
new_data['transaction_fee'] = new_data['fee'] + new_data['fee_1']
clean_data = new_data[['time', 'transaction_fee']]
clean_data = clean_data.rename(columns={'time': 'opentime'})

# 合并数据
after_merge = pd.merge(df_closes, clean_data, how='inner', on='opentime')
# 合并开仓手续费
after_merge = pd.merge(df_closes, df_trades[df_trades['action'].apply(lambda x: 'OPEN' in x)][['code', 'time', 'fee', 'qty']], how='left', left_on=['code', 'opentime'], right_on=['code', 'time'], suffixes=('', '_open')).rename(columns={'fee': 'openfee'})
# 合并平仓手续费
after_merge = pd.merge(after_merge, df_trades[df_trades['action'].apply(lambda x: 'CLOSE' in x)][['code', 'time', 'fee', 'qty']], how='left', left_on=['code', 'closetime'], right_on=['code', 'time'], suffixes=('','_close')).rename(columns={'fee': 'closefee'})
# 去重
after_merge = after_merge.drop_duplicates(['code', 'opentime', 'closetime', 'qty'])
after_merge['transaction_fee'] = (after_merge['openfee']/after_merge['qty_open'] + after_merge['closefee']/after_merge['qty_close']) * after_merge['qty']

data_long = df_closes[df_closes['direct'].apply(lambda x:'LONG' in x )].reset_index()
after_merge_long = after_merge[after_merge['direct'].apply(lambda x: 'LONG' in x)].reset_index()
Expand Down
102 changes: 44 additions & 58 deletions wtpy/apps/WtHotPicker.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@

import datetime
import time
import gzip
import io
import json
import os
import logging

import os
import re
import time
import urllib.request
import io
import gzip
import xml.dom.minidom

import pandas as pd
from pyquery import PyQuery as pq
import re


class DayData:
'''
Expand Down Expand Up @@ -181,7 +183,7 @@ def getShfeData(curDT:datetime.datetime) -> dict:
'''

dtStr = curDT.strftime('%Y%m%d')
content = httpGet("http://www.shfe.com.cn/data/dailydata/kx/kx%s.dat" % (dtStr))
content = httpGet("http://tsite.shfe.com.cn/data/dailydata/kx/kx%s.dat" % (dtStr))
if len(content) == 0:
return None

Expand Down Expand Up @@ -218,63 +220,47 @@ def getCzceData(curDT:datetime.datetime) -> dict:
@curDT 指定的日期
'''

dtStr = curDT.strftime('%Y%m%d')
url = 'http://www.czce.com.cn/cn/DFSStaticFiles/Future/%s/%s/FutureDataDaily.htm' % (dtStr[0:4], dtStr)
try:
html = httpGet(url).strip()
except urllib.error.HTTPError as httperror:
print(httperror)
return None
def correct_code(query_date, contract_code):
from dateutil.relativedelta import relativedelta

if len(html) == 0:
return None
# 提取品种代码和月份代码
pid = re.findall('[A-Za-z]+', contract_code)[0]
month_code = contract_code[len(pid):]

# 在给定`query_date`的情况下, 合约的月份只能是当前到九年之后
for i in range(10):
year_full = (query_date + relativedelta(years=i)).year
if str(year_full)[-1] == month_code[0]:
return f"{pid}{str(year_full)[-2:]}{month_code[-2:]}"

dataitems = {}
doc = pq(html)
# print(doc(#senfe .table table))
items = doc('#tab1')
# 去掉第一行标题
items.remove('tr.tr0')
# 获取tr items.find('tr')
lis = items('tbody>tr')
# print(lis)
# tr行数
trcount = len(lis)
# 遍历行
for tr in range(0, trcount-1):
dtStr = curDT.strftime('%Y%m%d')
try:
url = 'http://www.czce.com.cn/cn/DFSStaticFiles/Future/%s/%s/FutureDataDaily.xls' % (dtStr[0:4], dtStr)
df = pd.read_excel(url, skiprows=1)
except Exception as e:
return None
df.dropna(subset=['今收盘', '成交量(手)', ], inplace=True)
for _, row in df.iterrows():
item = DayData()
tdlis = doc(lis[tr])('td')

item.code = doc(tdlis[0]).text()
ay = re.compile('[A-Za-z]+').findall(item.code)
if len(ay) == 0:
continue

item.pid = ay[0]

close = doc(tdlis[5]).text()
if close != '':
item.close = float(close.replace(",",""))

volume = doc(tdlis[9]).text()
if volume != '':
item.volume = int(volume.replace(",",""))

hold = doc(tdlis[10]).text()
if hold != '':
item.hold = int(hold.replace(",",""))

item.month = item.code[len(item.pid):]
# 这个逻辑是有点问题的,但是没好的办法
# 因为郑商所只有3位数字,必须自动补全,不然后面处理会有问题
# By Wesley @ 2021.12.15
if int(item.month[0]) < 5:
item.month = "2" + item.month
else:
item.month = "1" + item.month
# 郑商所的xls表格, 列名不统一
if '合约代码' in df.columns:
item.code = row['合约代码']
elif '品种月份' in df.columns:
item.code = row['品种月份']

if '持仓量' in df.columns:
item.hold = int(row['持仓量'].replace(',', ''))
elif '空盘量' in df.columns:
item.hold = int(row['空盘量'].replace(',', ''))

item.pid = re.findall('[A-Za-z]+', item.code)[0]
item.month = correct_code(curDT, item.code)[len(item.pid):]
item.close = float(row['今收盘'].replace(',', ''))
item.volume = int(row['成交量(手)'].replace(',', ''))

dataitems[item.code] = item
# print(dataitems)

return dataitems

@staticmethod
Expand Down