def compass(date): listfile = os.listdir(dirname) for fn in listfile: os.remove(dirname + fn) d2 = get_dss() + 'info/hold/img/' listfile = os.listdir(d2) for fn in listfile: os.remove(d2 + fn) fn = get_dss() + 'fut/cfg/opt_mature.csv' df2 = pd.read_csv(fn) df2 = df2[pd.notnull(df2.flag)] fn_list = [] for func in [CF, m, RM, al, IO]: # for func in [m]: try: fn_list += func(date, df2) except Exception as e: s = traceback.format_exc() to_log(s) # print(fn_list) send_email(get_dss(), 'compass', '', fn_list)
def on_bar_minx(self, bar): self.am.updateBar(bar) if not self.am.inited: return # 涨跌停时暂停交易 if bar.close == bar.UpperLimitPrice: self.pause = True to_log(self.vtSymbol + ' 已涨停,该品种dali策略暂停交易') if bar.close == bar.LowerLimitPrice: self.pause = True to_log(self.vtSymbol + ' 已跌停,该品种dali策略暂停交易') if self.paused == True and self.backtest == False: self.counter += 1 if self.counter == 3: filename = get_dss() + 'gateway_closed.csv' if os.path.exists(filename): pass else: send_email(get_dss(), self.vtSymbol + ' 挂单未成交!!!', '') return self.calculateIndicator() # 计算指标 self.generateSignal(bar) # 触发信号,产生交易指令
def deal_single_ins(item): r = False if item['ins'] == 'down_sell': df = ts.get_realtime_quotes(item['code']) b3_price = float(df.at[0, 'b3_p']) if b3_price <= item['price'] and b3_price > 0: to_log('reach price by down_sell ins ') item['ins'] = 'sell_order' send_instruction(item) r = True if item['ins'] == 'up_warn': df = ts.get_realtime_quotes(item['code']) b3_price = float(df.at[0, 'b3_p']) if b3_price >= item['price']: to_log('reach price by up_warn ins ') send_email(dss, 'up_warn', str(item)) r = True if item['ins'] == 'down_warn': df = ts.get_realtime_quotes(item['code']) b3_price = float(df.at[0, 'b3_p']) if b3_price <= item['price'] and b3_price > 0: to_log('reach price by down_warn ins ') send_email(dss, 'down_warn', str(item)) r = True if item['ins'] in ['sell_order', 'buy_order']: to_log('send sell_order or buy_order ins ') send_instruction(item) r = True return r
def mail_1515(): to_log('in mail_1515') try: now = datetime.now() today = now.strftime('%Y-%m-%d') weekday = int(now.strftime('%w')) if 1 <= weekday <= 5: r = [] logfile = dss + 'log/autotrade.log' df = pd.read_csv(logfile, sep=' ', header=None, encoding='ansi') df = df[df[0] == today] for i, row in df.iterrows(): r.append(str(list(row)[:7])) send_email(dss, 'show log', '\n'.join(r)) r = [] txtfile = dss + 'csv/ins.txt' with open(txtfile, 'r', encoding='utf-8') as f: line = f.readline() while line: if line[0] == '{': #line_dict = eval(line) r.append(line) line = f.readline() send_email(dss, 'show ins ', '\n'.join(r)) except Exception as e: print('error') print(e)
def worker_1450(self): """盘中推送bar""" to_log('in TradeEngine.worker_1450') for p in self.portfolio_list: for vtSymbol in p.vtSymbolList: #print(vtSymbol) df = None i = 0 while df is None and i < 2: try: i += 1 df = ts.get_realtime_quotes(vtSymbol) except Exception as e: print('error get_realtime_quotes') print(e) time.sleep(0.1) if df is None: continue code = vtSymbol df1 = None i = 0 while df1 is None and i < 2: try: i += 1 df1 = get_adj_factor(self.dss, code) except Exception as e: print('error adj_factor ' + code) print(e) time.sleep(0.1) if df1 is None: continue factor = float(df1.at[0, 'adj_factor']) d = df.loc[0, :] bar = VtBarData() bar.vtSymbol = vtSymbol bar.symbol = vtSymbol bar.open = float(d['open']) * factor bar.high = float(d['high']) * factor bar.low = float(d['low']) * factor bar.close = float(d['price']) * factor bar.close_bfq = float(d['price']) date = d['date'].split('-') #去掉字符串中间的'-' date = ''.join(date) bar.date = date bar.time = '00:00:00' bar.datetime = datetime.strptime(bar.date + ' ' + bar.time, '%Y%m%d %H:%M:%S') bar.volume = float(d['volume']) p.onBar(bar) send_email(self.dss, 'worker_1450处理完毕', '')
def mail_pdf(s): try: # 将url页面转化为pdf url = 'http://114.116.190.167:5000/show_' + s fn = 'web/static/out3.pdf' pdfkit.from_url(url, fn) send_email(dss, url[33:], '', [fn]) except Exception as e: s = traceback.format_exc() to_log(s)
def run_examine(): kj = round(get_free_space_mb('C:\\'), 2) # print(kj,'GB') if kj < 3: send_email(dss, '预警:磁盘空间不足, 仅剩余', str(kj) + 'GB') now = datetime.datetime.now() weekday = int(now.strftime('%w')) if 1 <= weekday <= 5 and is_market_date(): print('\n' + str(now) + " examine begin...") examine() now = datetime.datetime.now() print('\n' + str(now) + " examine end ")
def mail_0200(): to_log('in mail_0200') try: now = datetime.now() weekday = int(now.strftime('%w')) if 2 <= weekday <= 6: print('\n' + str(now) + " mail_ma begin...") r = use_ma(dss) #print(r) #print(type(r)) send_email(dss, str(len(r)) + ' setting items ', '') except Exception as e: print('error') print(e)
def run_arbitrage(): try: now = datetime.datetime.now() weekday = int(now.strftime('%w')) if 1 <= weekday <= 5 and is_market_date(): print('\n' + str(now) + " arbitrage begin...") if calc_pcp(): fn = get_dss() + 'opt/pcp.csv' send_email(dss, 'pcp', '', [fn]) if calc_die(): fn = get_dss() + 'opt/die.csv' send_email(dss, 'die', '', [fn]) print(" arbitrage end ") except Exception as e: s = traceback.format_exc() to_log(s)
def run_price_signal(): try: now = datetime.datetime.now() weekday = int(now.strftime('%w')) if 2 <= weekday <= 6: dates = get_trading_dates(dss) today = dates[-1] arr = price_signal(dss, today) r = [] for a in arr: r.append(str(a)) #print(str(r)) send_email(dss, 'price_signal', '\n'.join(r)) except Exception as e: s = traceback.format_exc() to_log(s)
def check_trade(self): fn = get_dss() + 'fut/engine/gateway_order.csv' df1 = pd.read_csv(fn) df1 = df1[self.file_order_length:] # 读取发单文件,获得最新的发单记录,按合约、多空、开平字段进行汇总 if len(df1) > 0: g1 = df1.groupby(by=['symbol', 'direction', 'offset']) r1 = g1.agg({'volume': np.sum}) r1 = r1.reset_index() #print(r1) fn = get_dss() + 'fut/engine/gateway_trade.csv' df2 = pd.read_csv(fn) df2 = df2[self.file_trade_length:] # 读取成交文件,获得最新的成交记录,按合约、多空、开平字段进行汇总 if len(df2) > 0: # 处理路由记录存在重复的情况 df2 = df2.drop_duplicates() g2 = df2.groupby(by=['InstrumentID', 'Direction', 'Offset']) r2 = g2.agg({'Volume': np.sum}) r2 = r2.reset_index() r2.columns = ['symbol', 'direction', 'offset', 'volume'] #print(r2) if len(df1) > 0: if len(df2) > 0: result = pd.merge( r1, r2, how='left', on=['symbol', 'direction', 'offset', 'volume'], indicator=True) #print(result) result = result[result._merge == 'left_only'] #print(result) if len(result) > 0: # symbol_name = str(set(result.symbol)) # send_email(get_dss(), 'Alert: 发单未成交:' + symbol_name, '') send_email(get_dss(), 'Alert: 发单未成交', '') else: to_log('all order dealed') else: send_email(get_dss(), 'Alert: 发单全部未成交', '')
def calculateIndicator(self): """计算技术指标""" r = [] for row in self.ins_list: self.can_buy = False self.can_sell = False self.can_short = False self.can_cover = False ins = row[0] price = row[1] self.fixedSize = row[2] # print(ins, price, self.fixedSize) if ins == 'up_buy' and self.bar.close >= price: self.can_buy = True elif ins == 'down_buy' and self.bar.close <= price: self.can_buy = True elif ins == 'up_sell' and self.bar.close >= price: self.can_sell = True elif ins == 'down_sell' and self.bar.close <= price: self.can_sell = True elif ins == 'up_short' and self.bar.close >= price: self.can_short = True elif ins == 'down_short' and self.bar.close <= price: self.can_short = True elif ins == 'up_cover' and self.bar.close >= price: self.can_cover = True elif ins == 'down_cover' and self.bar.close <= price: self.can_cover = True elif ins == 'up_warn' and self.bar.close >= price: send_email(get_dss(), self.bar.vtSymbol + ' up_warn: ' + str(price), '') elif ins == 'down_warn' and self.bar.close <= price: send_email(get_dss(), self.bar.vtSymbol + ' down_warn: ' + str(price), '') else: r.append(row) self.generateSignal(self.bar) # 触发信号,产生交易指令 self.ins_list = r
def mail_value(): try: now = datetime.datetime.now() weekday = int(now.strftime('%w')) if 0 <= weekday <= 5: pnl_base = 54562 value_base = 103E4 date_base = '2020-12-30' fn = get_dss() + 'fut/engine/focus/all.csv' df = pd.read_csv(fn) df['value'] = 1 + round((df['pnl'] - pnl_base) / value_base, 2) df = df[df.date >= date_base] df = df.set_index('date') date_list = list(df.index) plt.figure(figsize=(7, 3)) plt.title(date_list[-1] + ': ' + str(df.at[date_list[-1], 'value'])) plt.plot(df.value) # plt.xticks(rotation=90) plt.xticks('off') plt.grid(True, axis='y') # ax = plt.gca() # for label in ax.get_xticklabels(): # label.set_visible(False) # for label in ax.get_xticklabels()[0:1]: # label.set_visible(True) # for label in ax.get_xticklabels()[-1:]: # label.set_visible(True) # plt.legend() fn = get_repo() + 'nature/web/static/value_all.jpg' plt.savefig(fn) plt.cla() send_email(dss, 'value', '', [fn]) except Exception as e: s = traceback.format_exc() to_log(s)
def stare_hold(): print('stare_hold begin... ') loaded = False codes = () mailed = [] while True: time.sleep(30) if is_price_time(): # 读入codes if not loaded: b1 = Book(dss) codes = b1.get_codes() loaded = True for code in codes: try: time.sleep(1) df = ts.get_realtime_quotes(code) name = df.at[0, 'name'] price = float(df.at[0, 'price']) pre_close = float(df.at[0, 'pre_close']) #print(code, price, pre_close) if code not in mailed: if price / pre_close - 1 > 0.05: send_email(dss, 'up_warn', str(code + ' ' + name)) #print('up_warn', str(code+' '+name)) mailed.append(code) if price / pre_close - 1 < -0.05: send_email(dss, 'down_warn', str(code + ' ' + name)) #print('down_warn', str(code+' '+name)) mailed.append(code) except Exception as e: print('error') print(e) else: loaded = False codes = () mailed = [] time.sleep(300)
def mail_log(): try: now = datetime.datetime.now() preday = now - datetime.timedelta(days=1) preday = preday.strftime('%Y-%m-%d %H:%M:%S') weekday = int(now.strftime('%w')) r = [] logfile = dss + 'log/autotrade.log' #df = pd.read_csv(logfile,sep='$',header=None,encoding='ansi') df = pd.read_csv(logfile, sep='$', header=None, encoding='utf-8') df['datetime'] = df[0] + ' ' + df[1] df = df[df['datetime'] >= preday] if len(df) > 0: df = df.sort_values('datetime', ascending=False) del df['datetime'] for i, row in df.iterrows(): s = str(list(row)[:7]) r.append(s) send_email(dss, 'show log', '\n'.join(r)) except Exception as e: print(now, '-' * 30) traceback.print_exc()
def mail_1815(): to_log('in mail_1815') try: now = datetime.now() weekday = int(now.strftime('%w')) if 1 <= weekday <= 5: print('\n' + str(now) + " mail_factor begin...") r = has_factor(dss) if r == []: send_email(dss, 'no factor', '') else: send_email(dss, 'has factor', '\n'.join(r)) print('\n' + str(now) + " mail_stk_report begin...") r = stk_report(dss) send_email(dss, 'show stk_report', '\n'.join(r)) except Exception as e: print('error') print(e)
def worker_1450(self): """盘中推送bar""" to_log('in TradeEngine.worker_1450') print('begin worker_1450') r, dt = self.is_trade_day() if r == False: return self.currentDt = dt for vtSymbol in self.vtSymbolList: #print(vtSymbol) df = None i = 0 while df is None and i < 3: try: i += 1 df = ts.get_realtime_quotes(vtSymbol) except Exception as e: print('error get_realtime_quotes') print(e) time.sleep(1) if df is None: continue code = vtSymbol df1 = None i = 0 while df1 is None and i < 3: try: i += 1 df1 = get_adj_factor(self.dss, code) except Exception as e: print('error adj_factor') print(e) time.sleep(1) if df1 is None: continue factor = float(df1.at[0, 'adj_factor']) d = df.loc[0, :] bar = VtBarData() bar.vtSymbol = vtSymbol bar.symbol = vtSymbol bar.open = float(d['open']) * factor bar.high = float(d['high']) * factor bar.low = float(d['low']) * factor bar.close = float(d['price']) * factor bar.close_bfq = float(d['price']) date = d['date'].split('-') #去掉字符串中间的'-' date = ''.join(date) bar.date = date bar.time = '00:00:00' bar.datetime = datetime.strptime(bar.date + ' ' + bar.time, '%Y%m%d %H:%M:%S') bar.volume = float(d['volume']) barDict = self.dataDict.setdefault(bar.datetime, OrderedDict()) barDict[bar.vtSymbol] = bar self.portfolio.onBar(bar) send_email(self.dss, 'worker_1450处理完毕', '')
def _bc_sendOrder(self, dt, code, direction, offset, price, volume, portfolio): filename = get_dss() + 'gateway_closed.csv' if os.path.exists(filename): return if self.state == 'CLOSE': print('gateway closed') return pz = get_contract(code).pz if portfolio in self.pf_dict: pz_list = self.pf_dict[portfolio].split(',') if (pz in pz_list) or ('*' in pz_list): print(portfolio, ' ', pz, ' send order here!') else: print(portfolio, ' ', pz, ' just test order here!') return else: print(portfolio, ' ', pz, ' just test order here!') return exchangeID = get_exchangeID(code) if exchangeID == '': return try: now = datetime.now() now = now.strftime('%H:%M') if now in ['10:14', '10:15', '10:16' ] and code[:2] not in ['IF', 'IO']: time.sleep(960) self.lock.acquire() # 对价格四舍五入 priceTick = get_contract(code).price_tick price = int(round(price / priceTick, 0)) * priceTick r = [[dt, code, direction, offset, price, volume]] print(str(r)) c = [ 'datetime', 'symbol', 'direction', 'offset', 'price', 'volume' ] df = pd.DataFrame(r, columns=c) filename = get_dss() + 'fut/engine/gateway_order.csv' if os.path.exists(filename): df.to_csv(filename, index=False, mode='a', header=False) else: df.to_csv(filename, index=False) if direction == DIRECTION_LONG and offset == 'Open': self.t.ReqOrderInsert(code, DirectType.Buy, OffsetType.Open, price, volume, exchangeID) if direction == DIRECTION_SHORT and offset == 'Open': self.t.ReqOrderInsert(code, DirectType.Sell, OffsetType.Open, price, volume, exchangeID) if direction == DIRECTION_LONG and offset == 'Close': self.t.ReqOrderInsert(code, DirectType.Buy, OffsetType.Close, price, volume, exchangeID) if direction == DIRECTION_SHORT and offset == 'Close': self.t.ReqOrderInsert(code, DirectType.Sell, OffsetType.Close, price, volume, exchangeID) send_email( get_dss(), '引擎下单:' + code + ' ' + str(direction) + ' ' + str(offset), '') except Exception as e: s = traceback.format_exc() to_log(s) send_email(get_dss(), '交易路由出错', s) # 流控 time.sleep(0.5) print('流控') self.lock.release()
def on_qry_account(self, pTradingAccount, pRspInfo, nRequestID, bIsLast): self.t.OnAccount(pTradingAccount, pRspInfo, nRequestID, bIsLast) risk = round(float(self.t.account.Risk), 2) if self.state == 'OPEN': send_email(get_dss(), 'Risk: ' + str(risk), ' ')
def calculateIndicator(self): """计算技术指标""" # 记录数据 r = [[self.bar.date, self.bar.time, self.bar.close]] df = pd.DataFrame(r) filename = get_dss( ) + 'fut/engine/owl/bar_owl_' + self.type + '_' + self.vtSymbol + '.csv' if os.path.exists(filename): df.to_csv(filename, index=False, mode='a', header=False) else: df.to_csv(filename, index=False) r = [] fn = get_dss( ) + 'fut/engine/owl/signal_owl_' + self.type + '_var_' + self.vtSymbol + '.csv' if os.path.exists(fn): df = pd.read_csv(fn) for i, row in df.iterrows(): self.can_buy = False self.can_sell = False self.can_short = False self.can_cover = False ins = row['ins'] price = float(row['price']) self.fixedSize = int(row['num']) # print(ins, price, self.fixedSize) if ins == 'up_buy' and self.bar.close >= price: self.can_buy = True elif ins == 'down_buy' and self.bar.close <= price: self.can_buy = True elif ins == 'up_sell' and self.bar.close >= price: self.can_sell = True elif ins == 'down_sell' and self.bar.close <= price: self.can_sell = True elif ins == 'up_short' and self.bar.close >= price: self.can_short = True elif ins == 'down_short' and self.bar.close <= price: self.can_short = True elif ins == 'up_cover' and self.bar.close >= price: self.can_cover = True elif ins == 'down_cover' and self.bar.close <= price: self.can_cover = True elif ins == 'up_warn' and self.bar.close >= price: send_email(get_dss(), self.bar.vtSymbol + ' up_warn: ' + str(price), '') elif ins == 'down_warn' and self.bar.close <= price: send_email(get_dss(), self.bar.vtSymbol + ' down_warn: ' + str(price), '') else: r.append([row.ins, row.price, row.num]) self.generateSignal(self.bar) # 触发信号,产生交易指令 fn = get_dss() + 'fut/engine/owl/history.csv' df = pd.read_csv(fn) df1 = df[(df.code == self.bar.vtSymbol) & (df.got == 'no')] if len(df1) > 0: for i, row in df1.iterrows(): r.append([row.ins, row.price, row.num]) df.at[i, 'got'] = 'yes' df.to_csv(fn, index=False) fn = get_dss( ) + 'fut/engine/owl/signal_owl_' + self.type + '_var_' + self.vtSymbol + '.csv' df = pd.DataFrame(r, columns=['ins', 'price', 'num']) df.to_csv(fn, index=False)
def worker_1450(self): """盘中推送bar""" to_log('in TradeEngine.worker_1450') for p in self.portfolio_list: for vtSymbol in p.vtSymbolList: #print(vtSymbol) df = None i = 0 while df is None and i < 2: try: i += 1 df = ts.get_realtime_quotes(vtSymbol) except Exception as e: print('error get_realtime_quotes') print(e) time.sleep(0.1) if df is None: to_log('ignore ' + vtSymbol) continue adj_factor = None df1 = None i = 0 while df1 is None and i < 2: try: i += 1 df1 = get_adj_factor(self.dss, vtSymbol) adj_factor = float(df1.at[0, 'adj_factor']) except Exception as e: print('error adj_factor ' + vtSymbol) print(e) time.sleep(0.1) if df1 is None: to_log('ignore ' + vtSymbol) continue hfq_factor = get_hfq_factor(self.dss, vtSymbol) factor = hfq_factor if adj_factor is not None: if abs((adj_factor - hfq_factor) / adj_factor) > 0.01: # 差异大,今天有除权 factor = adj_factor d = df.loc[0, :] bar = VtBarData() bar.vtSymbol = vtSymbol bar.symbol = vtSymbol bar.open = float(d['open']) * factor bar.high = float(d['high']) * factor bar.low = float(d['low']) * factor bar.close = float(d['price']) * factor bar.close_bfq = float(d['price']) date = d['date'].split('-') #去掉字符串中间的'-' date = ''.join(date) bar.date = date bar.time = '00:00:00' bar.datetime = datetime.strptime(bar.date + ' ' + bar.time, '%Y%m%d %H:%M:%S') bar.volume = float(d['volume']) #to_log(vtSymbol+' '+d['price']+' * '+str(factor)+' = '+str(bar.close)) p.onBar(bar) send_email(self.dss, 'worker_1450处理完毕', '')
def die(self): r = [] tm = self.tm now = datetime.now() today = now.strftime('%Y-%m-%d') # 获取期权的到期日 fn = get_dss() + 'fut/cfg/opt_mature.csv' df2 = pd.read_csv(fn) df2 = df2[df2.flag == df2.flag] # 筛选出不为空的记录 df2 = df2.set_index('symbol') mature_dict = dict(df2.mature) for basic in self.slice_dict.keys(): if basic not in mature_dict: continue date_mature = mature_dict[ basic ] date_mature = datetime.strptime(date_mature, '%Y-%m-%d') td = datetime.strptime(today, '%Y-%m-%d') T = round(float((date_mature - td).days) / 365, 4) # 剩余期限 if T >= 0.2: continue strike_list = [] v = self.slice_dict[basic] for row in v: # if basic == 'm2105': # print(row) symbol = row[0] if get_contract(symbol).be_opt: strike_list.append( get_contract(symbol).strike ) strike_list = sorted(set(strike_list)) n = len(strike_list) for gap in [1,2,3]: for i in range(n-2*gap): try: s1 = strike_list[i] s2 = strike_list[i+gap] s3 = strike_list[i+2*gap] if s2 -s1 != s3 -s2: continue c1 = self.get_rec_from_slice(basic+get_contract(basic).opt_flag_C+str(s1))[2] # AskPrice c2 = self.get_rec_from_slice(basic+get_contract(basic).opt_flag_C+str(s2))[3] # BidPrice c3 = self.get_rec_from_slice(basic+get_contract(basic).opt_flag_C+str(s3))[2] # AskPrice if c1 == 0 or c2 == 0 or c3 == 0 or c1 != c1 or c2 != c2 or c3 != c3: pass else: cost = round(c1 - 2*c2 + c3, 2) if cost <= 0: self.id += 1 seq = today[-5:-3] + today[-2:] + str(self.id) r.append( [seq, today, tm, 'die', ['forward', basic, 'C', s1, c1, s2, c2, s3, c3, cost]] ) p1 = self.get_rec_from_slice(basic+get_contract(basic).opt_flag_P+str(s1))[2] # AskPrice p2 = self.get_rec_from_slice(basic+get_contract(basic).opt_flag_P+str(s2))[3] # BidPrice p3 = self.get_rec_from_slice(basic+get_contract(basic).opt_flag_P+str(s3))[2] # AskPrice if p1 == 0 or p2 == 0 or p3 == 0 or p1 != p1 or p2 != p2 or p3 != p3: pass else: cost = round(p1 - 2*p2 + p3, 2) if cost <= 0: self.id += 1 seq = today[-5:-3] + today[-2:] + str(self.id) r.append( [seq, today, tm, 'die', ['forward', basic, 'P', s1, p1, s2, p2, s3, p3, cost]] ) except: pass # s = traceback.format_exc() # to_log(s) fn = get_dss() + 'fut/engine/arbitrage/portfolio_arbitrage_chance.csv' df = pd.read_csv(fn) df = df[(df.date== today) & (df.type=='die')] result = [] for rr in r: rec = rr[4] for i, row in df.iterrows(): c = eval(row['content']) if c[1] == rec[1] and c[2] == rec[2] and c[3] == rec[3] and c[5] == rec[5] and c[7] == rec[7]: pass else: result.append(rec) if result != []: df = pd.DataFrame(result, columns=['seq', 'date', 'time', 'type', 'content']) df.to_csv(fn, index=False, mode='a', header=False) if tm > '09:00:00' and tm < '15:00:00': send_email(get_dss(), '无风险套利机会'+' '+today+' '+tm, '', [], '*****@*****.**')
def pcp(self): """ 将行情切片整理成k_dict,其以basic+strike为键, 以[basic, strike, c_ask_price, c_bid_price, p_ask_price, p_bid_price, obj_ask_price, obj_bid_price, tm]为值 """ k_dict = {} tm = '00:00:00' now = datetime.now() today = now.strftime('%Y-%m-%d') # 获取期权的到期日 fn = get_dss() + 'fut/cfg/opt_mature.csv' df2 = pd.read_csv(fn) df2 = df2[df2.flag == df2.flag] # 筛选出不为空的记录 df2 = df2.set_index('symbol') mature_dict = dict(df2.mature) for basic in self.slice_dict.keys(): # print(pz) v = self.slice_dict[basic] for row in v: # if basic == 'm2105': # print(row) symbol = row[0] tm = row[1] ask_price = row[2] bid_price = row[3] opt_flag = get_contract(symbol).opt_flag strike = get_contract(symbol).strike if basic[:2] == 'IO': symbol_obj = 'IF' + basic[2:] else: symbol_obj = basic # 当键值出现时,一次性将认购和认沽合约都处理了 if basic+str(strike) not in k_dict.keys(): if opt_flag == 'C': symbol_p = basic + get_contract(symbol).opt_flag_P + str(strike) rec_p = self.get_rec_from_slice(symbol_p) rec_obj = self.get_rec_from_slice(symbol_obj) if rec_p is not None and rec_obj is not None: k_dict[basic+str(strike)] = [basic, strike, ask_price, bid_price, rec_p[2], rec_p[3], rec_obj[2], rec_obj[3], tm] if opt_flag == 'P': symbol_c = basic + get_contract(symbol).opt_flag_C + str(strike) rec_c = self.get_rec_from_slice(symbol_c) rec_obj = self.get_rec_from_slice(symbol_obj) if rec_c is not None and rec_obj is not None: k_dict[basic+str(strike)] = [basic, strike, rec_c[2], rec_c[3], ask_price, bid_price, rec_obj[2], rec_obj[3], tm] r = [] # 逐条记录验证pcp规则 for k in k_dict.keys(): rec = k_dict[k] term = rec[0] x = rec[1] tm = rec[8] date_mature = mature_dict[ term ] date_mature = datetime.strptime(date_mature, '%Y-%m-%d') td = datetime.strptime(today, '%Y-%m-%d') T = round(float((date_mature - td).days) / 365, 4) # 剩余期限 if T == 0 or T >= 0.3: continue # 正向套利 S = rec[6] cb = rec[3] pa = rec[4] if cb > 1E8 or cb == 0 or cb != cb or pa > 1E8 or pa == 0 or pa != pa: pass else: pSc_forward = int( pa + S - cb ) diff_forward = float(x) - pSc_forward rt_forward = round( diff_forward/(S*2*0.15)/T, 2 ) if rt_forward >= 0.12 and diff_forward >= 3: self.id += 1 seq = today[-5:-3] + today[-2:] + str(self.id) r.append( [seq, today, tm, 'pcp', ['forward', term, S, cb, pa, T, x, pSc_forward, diff_forward, rt_forward]] ) # to_log( 'pcp: ' + str([today, 'forward', term, x, S, cb, pa, pSc_forward, T, diff_forward, rt_forward]) ) # 反向套利 S = rec[7] ca = rec[2] pb = rec[5] if ca > 1E8 or ca == 0 or ca != ca or pb > 1E8 or pb == 0 or pb != pb: pass else: pSc_back = int( pb + S - ca ) diff_back = pSc_back - float(x) rt_back = round( diff_back/(S*2*0.15)/T, 2 ) if rt_back >= 0.12 and diff_back >= 3: self.id += 1 seq = today[-5:-3] + today[-2:] + str(self.id) r.append( [seq, today, tm, 'pcp', ['back', term, S, ca, pb, T, x, pSc_back, diff_back, rt_back]] ) fn = get_dss() + 'fut/engine/arbitrage/portfolio_arbitrage_chance.csv' df = pd.read_csv(fn) df = df[(df.date== today) & (df.type=='pcp')] result = [] for rr in r: rec = rr[4] for i, row in df.iterrows(): c = eval(row['content']) if c[1] == rec[1] and c[2] == rec[2] and c[3] == rec[3] and c[5] == rec[5] and c[7] == rec[7]: pass else: result.append(rec) if result != []: df = pd.DataFrame(result, columns=['seq', 'date', 'time', 'type', 'content']) df.to_csv(fn, index=False, mode='a', header=False) if tm > '09:00:00' and tm < '15:00:00': send_email(get_dss(), '无风险套利机会'+' '+today+' '+tm, '', [], '*****@*****.**')
def control_in_p(self, bar): if (bar.time > '09:31:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] in ['IF','IO']) or \ (bar.time > '13:01:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] in ['IF','IO']) or \ (bar.time > '21:01:00' and bar.time < '24:00:00' and bar.vtSymbol[:2] in ['al']) or \ (bar.time > '00:00:00' and bar.time < '01:00:00' and bar.vtSymbol[:2] in ['al']) or \ (bar.time > '09:01:00' and bar.time < '11:27:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \ (bar.time > '13:31:00' and bar.time < '14:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) or \ (bar.time > '21:01:00' and bar.time < '22:57:00' and bar.vtSymbol[:2] not in ['IF','IO']) : # 因第一根K线的价格为0 cols = [ 'date', 'basic_m0', 'basic_m1', 'strike', 'fixed_size', 'hold_m0', 'hold_m1', 'price_c_m0', 'price_p_m0', 'price_c_m1', 'price_p_m1', 'd_low_open', 'd_high_open', 'd_max', 'dida_max', 'd_min', 'dida_min', 'profit', 'state', 'source', 'profit_m0', 'profit_m1', 'profit_o' ] fn = get_dss() + 'fut/engine/sdiffer/portfolio_sdiffer_param.csv' # while get_file_lock(fn) == False: # time.sleep(0.01) cols_straddle = [ 'tm', 'basic_c', 'strike_c', 'basic_p', 'strike_p', 'num_c', 'num_p', 'direction', 'hold_c', 'hold_p', 'profit', 'state', 'source', 'price_c', 'price_p', 'profit_c', 'profit_p', 'profit_o', 'date' ] fn_straddle = get_dss( ) + 'fut/engine/straddle/portfolio_straddle_param.csv' # while get_file_lock(fn_straddle) == False: # time.sleep(0.01) df = pd.read_csv(fn) df_straddle = pd.read_csv(fn_straddle) symbol_got_list = [] # 先确定当日要交易的合约,生成当日交易记录 if self.symbol_obj is None: try: temp1 = 'IF' + self.basic_m0[2:] # print(temp1) if self.got_dict[temp1]: self.symbol_obj = temp1 # 临近到期日,暂停自动交易,否则,发出条件单 if self.stop == False: s_obj = self.signalDict[self.symbol_obj][0] obj = s_obj.bar.close gap = 50 atm = int( round( round(obj * (100 / gap) / 1E4, 2) * 1E4 / (100 / gap), 0)) # 获得平值 r = [[bar.date, self.basic_m0, self.basic_m1, atm, 1, \ 0, 0, '','','','', \ self.d_low_open, self.d_high_open, 0.0,0,0.0,0, \ 13,self.be_run,'sdiffer','','',''] ] df2 = pd.DataFrame(r, columns=cols) df = pd.concat([df, df2], sort=False) # print(df) except Exception as e: s = traceback.format_exc() to_log(s) else: for i, row in df.iterrows(): try: r = [] if row.state == 'stop': continue symbol_c_m0 = row.basic_m0 + '-C-' + str(row.strike) symbol_p_m0 = row.basic_m0 + '-P-' + str(row.strike) symbol_c_m1 = row.basic_m1 + '-C-' + str(row.strike) symbol_p_m1 = row.basic_m1 + '-P-' + str(row.strike) if symbol_c_m0 not in self.got_dict or symbol_p_m0 not in self.got_dict or symbol_c_m1 not in self.got_dict or symbol_p_m1 not in self.got_dict: continue if self.got_dict[symbol_c_m0] == False or self.got_dict[ symbol_p_m0] == False or self.got_dict[ symbol_c_m1] == False or self.got_dict[ symbol_p_m1] == False: continue else: symbol_got_list.append(symbol_c_m0) symbol_got_list.append(symbol_p_m0) symbol_got_list.append(symbol_c_m1) symbol_got_list.append(symbol_p_m1) s_c_m0 = self.signalDict[symbol_c_m0][0] s_p_m0 = self.signalDict[symbol_p_m0][0] s_c_m1 = self.signalDict[symbol_c_m1][0] s_p_m1 = self.signalDict[symbol_p_m1][0] d_base_m0 = self.d_base_dict[row.basic_m0 + '_' + str(row.strike)] d_base_m1 = self.d_base_dict[row.basic_m1 + '_' + str(row.strike)] # 开仓 if row.hold_m0 == 0 and row.hold_m1 == 0: diff_m0 = 0.5 * ( s_c_m0.bar.AskPrice + s_c_m0.bar.BidPrice ) + 0.5 * (s_p_m0.bar.AskPrice + s_p_m0.bar.BidPrice) - d_base_m0 diff_m1 = 0.5 * ( s_c_m1.bar.AskPrice + s_c_m1.bar.BidPrice ) + 0.5 * (s_p_m1.bar.AskPrice + s_p_m1.bar.BidPrice) - d_base_m1 differ = diff_m1 - diff_m0 print('differ: ', differ) if differ <= self.d_low_mail and self.mailed_low == False: self.mailed_low = True send_email(get_dss(), 'differ: ' + str(differ), '') if differ >= self.d_high_mail and self.mailed_high == False: self.mailed_high = True send_email(get_dss(), 'differ: ' + str(differ), '') if differ >= row.d_max: df.at[i, 'd_max'] = differ df.at[i, 'dida_max'] = 0 else: df.at[i, 'dida_max'] = row.dida_max + 1 # print(df.at[i, 'dida_max'], row.dida_max) if differ <= row.d_min: df.at[i, 'd_min'] = differ df.at[i, 'dida_min'] = 0 else: df.at[i, 'dida_min'] = row.dida_min + 1 # print(df.at[i, 'dida_min'], row.dida_min) # 做多 # if differ < 9: if df.at[ i, 'd_min'] <= row.d_low_open and differ >= row.d_low_open and df.at[ i, 'dida_min'] > 0: r.append([ '00:00:00', row.basic_m0, row.strike, row.basic_m0, row.strike, 1, 1, 'kong', 0, 0, 1000, 'run', 'sdiffer', '', '', '', '', '', bar.date ]) r.append([ '00:00:00', row.basic_m1, row.strike, row.basic_m1, row.strike, 1, 1, 'duo', 0, 0, 1000, 'run', 'sdiffer', '', '', '', '', '', bar.date ]) df.at[i, 'hold_m0'] = -1 df.at[i, 'hold_m1'] = 1 df.at[i, 'price_c_m0'] = s_c_m0.bar.BidPrice df.at[i, 'price_p_m0'] = s_p_m0.bar.BidPrice df.at[i, 'price_c_m1'] = s_c_m1.bar.AskPrice df.at[i, 'price_p_m1'] = s_p_m1.bar.AskPrice # 做空 # if differ > 9: if df.at[ i, 'd_max'] >= row.d_high_open and differ <= row.d_high_open and df.at[ i, 'dida_max'] > 0: r.append([ '00:00:00', row.basic_m1, row.strike, row.basic_m1, row.strike, 1, 1, 'kong', 0, 0, 1000, 'run', 'sdiffer', '', '', '', '', '', bar.date ]) r.append([ '00:00:00', row.basic_m0, row.strike, row.basic_m0, row.strike, 1, 1, 'duo', 0, 0, 1000, 'run', 'sdiffer', '', '', '', '', '', bar.date ]) df.at[i, 'hold_m0'] = 1 df.at[i, 'hold_m1'] = -1 df.at[i, 'price_c_m0'] = s_c_m0.bar.AskPrice df.at[i, 'price_p_m0'] = s_p_m0.bar.AskPrice df.at[i, 'price_c_m1'] = s_c_m1.bar.BidPrice df.at[i, 'price_p_m1'] = s_p_m1.bar.BidPrice df2_straddle = pd.DataFrame( r, columns=cols_straddle) df_straddle = pd.concat( [df_straddle, df2_straddle], sort=False) # 多单获利平仓 elif row.hold_m0 == -1 and row.hold_m1 == 1: df.at[i, 'profit_m0'] = round( (row.price_c_m0 + row.price_p_m0) - (s_c_m0.bar.AskPrice + s_p_m0.bar.AskPrice), 2) df.at[i, 'profit_m1'] = round( (s_c_m1.bar.BidPrice + s_p_m1.bar.BidPrice) - (row.price_c_m1 + row.price_p_m1), 2) df.at[i, 'profit_o'] = round( df.at[i, 'profit_m0'] + df.at[i, 'profit_m1'], 2) if df.at[i, 'profit_o'] >= row.profit: df.at[i, 'hold_m0'] = 0 df.at[i, 'hold_m1'] = 0 df.at[i, 'state'] = 'stop' for j, jow in df_straddle.iterrows(): if jow.basic == row.basic_m0 and jow.strike == row.strike and jow.direction == 'kong' and jow.source == 'sdiffer': df_straddle.at[j, 'profit'] = -1000 if jow.basic == row.basic_m1 and jow.strike == row.strike and jow.direction == 'duo' and jow.source == 'sdiffer': df_straddle.at[j, 'profit'] = -1000 # 空单获利平仓 elif row.hold_m0 == 1 and row.hold_m1 == -1: df.at[i, 'profit_m0'] = round( (s_c_m0.bar.BidPrice + s_p_m0.bar.BidPrice) - (row.price_c_m0 + row.price_p_m0), 2) df.at[i, 'profit_m1'] = round( (row.price_c_m1 + row.price_p_m1) - (s_c_m1.bar.AskPrice + s_p_m1.bar.AskPrice), 2) df.at[i, 'profit_o'] = round( df.at[i, 'profit_m0'] + df.at[i, 'profit_m1'], 2) if df.at[i, 'profit_o'] >= row.profit: df.at[i, 'hold_m0'] = 0 df.at[i, 'hold_m1'] = 0 df.at[i, 'state'] = 'stop' for j, jow in df_straddle.iterrows(): if jow.basic == row.basic_m0 and jow.strike == row.strike and jow.direction == 'duo' and jow.source == 'sdiffer': df_straddle.at[j, 'profit'] = -1000 if jow.basic == row.basic_m1 and jow.strike == row.strike and jow.direction == 'kong' and jow.source == 'sdiffer': df_straddle.at[j, 'profit'] = -1000 except Exception as e: s = traceback.format_exc() to_log(s) df_straddle.to_csv(fn_straddle, index=False) # release_file_lock(fn_straddle) df.to_csv(fn, index=False) # release_file_lock(fn) for symbol in symbol_got_list: self.got_dict[symbol] = False