增加交易策略、交易指标、量化库代码等文件夹
This commit is contained in:
@@ -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)
|
||||
Reference in New Issue
Block a user