588 lines
30 KiB
Python
588 lines
30 KiB
Python
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()
|
|
|
|
|