- Square
- 复杂看盘图表测试版
复杂看盘图表测试版
Author:
qq89520, Date: 2020-06-30 16:04:38
Tags:
ChartPython
'''backtest
start: 2020-03-11 00:00:00
end: 2020-04-09 23:59:00
period: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''
import pandas as pd
import numpy as np
import re
preBarTime_1=0
'''
shortChart = {
"__isStock" : True,
"extension" : {
"layout" : "group", #single不参于分组,单独显示, 默认为分组 'group'
"height" : 300,
},
"title" : {"text": 'rb888' + '__15M交易信号图'},
"xAxis" : {"type" : "datetime"}, # 时间序列轴
"yAxis" : [{"labels": {
"align": 'right',
"x": -3
},
"title": {
"text": '盘口'
},
"height": "45%", # 相对宽度大小
"resize": {
"enabled": True # 是否启用重置宽度
},
"opposite": True, # 是否将轴显示在对面 默认左
"offset": 0, # 坐标轴偏移 正右 负左
"lineWidth": 2 # 线宽
}, {"labels": {
"align": 'right',
"x": -3
},
"title": {
"text": 'RSI'
},
"top": '45%',
"height": '25%',
"opposite": True,
"offset": 0,
"lineWidth": 2
}, {"labels": {
"align": 'right',
"x": -3
},
"title": {
"text": 'MACD_5'
},
"top": '70%',
"height": '30%',
"opposite": True,
"offset": 0,
"lineWidth": 2
}
],
"tooltip":{
"split": False, # 原生js??
"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"
},
"series" : [{'type': 'candlestick',
'name': 'k线',
#'color': 'green',
#'lineColor': 'green', # 默认显示color的设置,非null这按照这里的设置显示
#'upColor': 'red',
#'upLineColor': 'red',
"data" : [],
}, {
"type" : "line",
"name" : "rsi",
"data" : [],
"yAxis": 1 # 相对位置
}
, {
"type" : "line",
"name" : "diff",
"data" : [],
"yAxis": 2 # 相对位置
}, {
"type" : "line",
"name" : "dea",
"data" : [],
"yAxis": 2 # 相对位置
}, {
"type" : "column",
"name" : "macd",
"data" : [],
"yAxis": 2 # 相对位置
}
]
}
'''
"""
shortChart = {
"__isStock" : True,
"extension" : {
"layout" : "single", #single不参于分组,单独显示, 默认为分组 'group'
"height" : 300,
},
"title" : {"text": 'rb888' + '__15M交易信号图'},
"xAxis" : {"type" : "datetime"}, # 时间序列轴
"yAxis" : {"labels": {
"align": 'right',
"x": -3
},
"title": {
"text": '盘口'
},
#"height": "45%", # 相对宽度大小
#"resize": {
# "enabled": True # 是否启用重置宽度
"opposite": True, # 是否将轴显示在对面 默认左
"offset": 0, # 坐标轴偏移 正右 负左
"lineWidth": 2 # 线宽
},
"tooltip" : {
"split": false, # 原生js??
"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"
},
"series" : {'type': 'candlestick',
'name': 'k线',
#'color': 'green',
#'lineColor': 'green', # 默认显示color的设置,非null这按照这里的设置显示
#'upColor': 'red',
#'upLineColor': 'red',
"data" : [],
}
}
"""
shortChart = {
"__isStock" : True,
"extension" : {
"layout" : "single", #single不参于分组,单独显示, 默认为分组 'group'
#"height" : 500,
},
'legend': {
'enabled': true # 图例 true开启
},
'title' : {
'text' : '柱形K线'
},
"xAxis" : {
"type" : "datetime",
#'dashStyle': 'dash' # 准心线样式 虚线
}, # 时间序列轴
'yAxis' : [{
'labels':{
'align':'right',
'x':-3
},
'height':"40%",
'lineWidth':2,
#'crosshair': true, # 准心线
'resize':{
'enabled':true
}
},{
'labels':{
'align':'right',
'x':-3
},
'title':{
'text' : 'Volume'
},
'top':'40%',
'height':'15%',
'offset':0,
#'crosshair': true,
'lineWidth':2
},{"labels": {
"align": 'right',
"x":-3
},
"title": {
"text": 'RSI'
},
"top": '55%',
"height": '20%',
"opposite": True,
"offset": 0,
#'crosshair': true,
"lineWidth": 2,
'plotLines': [{
'value': 75, # 值大小
'color': 'green', # 颜色
'dashStyle': 'shortdash', # 线条样式
'width': 0.5,
#'label': {
# 'text': '多头止盈线'
#}
},{
'value': 25,
'color': 'red',
'dashStyle': 'shortdash',
'width': 0.5,
#'label': {
# 'text': '空头止盈线'
#}
}
]
}, {"labels": {
"align": 'right',
"x":-3
},
"title": {
"text": 'MACD'
},
"top": '75%',
"height": '25%',
"opposite": True,
"offset": 0,
"lineWidth": 2
}
],
'tooltip':{
#'shared': true, # 是否开启提示标签共享,多图下效果基本等同split
"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A",
'shared': true,
'crosshairs': true,
'valueDecimals':2, # 保留小数
#'split':true, # 提示框分开
#'distance': 30,
#'padding': 5
#'positioner': {
# 'x':150,
# 'y':150
#},
#'shadow': false,
#'borderWidth': 0,
#'backgroundColor': 'rgba(255,255,255,0.8)'
},
'series':[{
'type':'candlestick',
'animationLimit':'Infinity',
'color': 'green',
'lineColor': 'green', # 默认显示color的设置,非null这按照这里的设置显示
'upColor': 'red',
'upLineColor': 'red',
'name':'appl',
'data':[]
},{
'type':'column',
'name':'Volume',
'data':[],
'yAxis':1
},{
"type" : "line",
"name" : "rsi",
"data" : [],
"yAxis": 2 # 相对位置
},{
"type" : "line",
"name" : "diff",
"data" : [],
"yAxis": 3 # 相对位置
},{
"type" : "line",
"name" : "dea",
"data" : [],
"yAxis": 3 # 相对位置
},{
"type" : "column",
"name" : "macd",
"data" : [],
'maxPointWidth':2, # 量柱最大宽度
"yAxis": 3 # 相对位置
}
]
}
longChart = {
"__isStock" : True,
"extension" : {
"layout" : "group",
#"height" : 300,
},
'rangeSelector':{
'selected' : 0
},
'chart': { # 主配置项
#'height': 630, # 高度,平台不支持配置
'type': 'line',
'zoomType': 'x', # 缩放
#'selectionMarkerFill':'rgba(51,92,223,0.25)', # 缩放框背景色
#'panning': true, # 开启平移
#'panKey': 'shift' # 平移
'borderColor': '#EBBA95', # 外框配置项
'borderWidth': 2, ##
'borderRadius': 10, ##
},
"rangeSelector" : {
"buttons" : [{
"type" : "hour",
"count" : 1,
"text" : "1h",
}, {
"type" : 'hour',
"count" : 3,
"text" : "3h"
}, {
"type" : "day",
"count" : 1,
"text" : "1d"
}, {
"type" : "week",
"count" : 1,
"text" : "1w"
}, {
"type" : "year",
"count" : 1,
"text" : "1Y"
}, {
"type" : "all",
"text" : "All"
}],
"selected" : 1,
"inputEnabled" : True
},
'legend': {
'enabled': true # 图例 true开启
},
'title' : {
'text' : '15'
},
'subtitle': {
'text': '湘水看盘图表', #'当前价格:'+str(records_5[-1]['Close'] if records_5[-1]['Close'] is not None else **)+' || '+'当前时间:'+str(Time_5 if Time_5 is not None else **)
},
"xAxis" : {
"type" : "datetime",
#'dashStyle': 'dash' # 准心线样式 虚线
}, # 时间序列轴
"xAxis" : {"type" : "datetime"},
"yAxis" : [{
"title": {
"text": 'Kline'
},
"height": "60%", # 相对宽度大小
"offset": 0, # 坐标轴偏移 正右 负左
"lineWidth": 2 # 线宽
},{
"title": {
"text": 'MACD'
},
"top": '62%',
"height": '38%',
"offset": 0,
"lineWidth": 2
}
],
"series" : [
{
"type" : "candlestick",
"name" : "k_15",
"id" : "k",
"data" : [],
"yAxis": 0 # 相对位置
},{
"type" : "column",
"name" : "macd_15",
"data" : [],
"yAxis": 1 # 相对位置
}
]
}
chart0 = {
"__isStock" : True,
"extension" : {
"layout" : "group",
#"height" : 300,
},
'title' : { 'text' : '日K线图'},
'xAxis': { 'type': 'datetime'},
'series' : [
{
'type': 'candlestick',
'name': 'r',
'id': 'r',
'data': []
}, {
'type': 'column',
'name': 'vol',
'data': [],
}
]
}
chart1 = {
"__isStock" : True,
"extension" : {
"layout" : "group",
#"height" : 300,
},
'title' : { 'text' : 'ris'},
'xAxis': { 'type': 'datetime'},
'yAxis' : {
'title': {'text': 'rsi'},
'opposite': false
},
'series' :
{
'type': 'line',
#'yAxis': 1,
'name': 'rsi',
'data': []
},
}
chart2 = {
"__isStock" : True,
"extension" : {
"layout" : "group",
#"height" : 300,
},
'title' : { 'text' : 'macd'},
'xAxis': { 'type': 'datetime'},
'yAxis' : {
'title': {'text': 'macd'},
'opposite': false
},
'series' : [
{
'type': 'line',
#'yAxis': 1,
'name': 'dif',
'data': []
},{
'type': 'line',
#'yAxis': 1,
'name': 'eda',
'data': []
},{
'type': 'line',
#'yAxis': 1,
'name': 'macd',
'data': []
},
]
}
hart1 = {
"__isStock" : True,
"extension" : {
"layout" : "group",
#"height" : 300,
},
'title' : { 'text' : 'MACD_5'},
'xAxis': { 'type': 'datetime'},
'series' : [
{
'type': 'candlestick',
'name': 'k',
'id': 'r1',
'data': []
}, {
'type': 'column',
'name': 'macd_15',
'data': [],
}
]
}
macd_15 = []
runTime = {}
runTime['preBarTime_1'] = [0,0]
runTime['arrKIndex'] = []
_5_lengh = 50
_15_lengh = 50
def ticks_(records, k):
if len(records) == 0:
return []
if isinstance(records[0], int) or isinstance(records[0], float):
return records
ticks = [None] * len(records)
for i in range(len(records)):
ticks[i] = records[i][k]
return ticks
def plot(arr,_5_lengh,_15_lengh,index_2,runTime,chart):
for x,symbol in enumerate(arr):
#Log(symbol,_D(),)
runTime['arrKIndex'] = [index_2[x],index_2[x]+7] # [0,7] [8,15]
#Log(symbol)
exchange.SetContractType(symbol)
#Log(symbol,_D())
records_5 = _C(exchange.GetRecords,PERIOD_M5) # 返回列表型字典
records_15 = _C(exchange.GetRecords,PERIOD_M15)
r = records_5
m = records_15
Time_5 = records_5[-1]['Time']
Time_5_list = pd.Series(ticks_(records_5,'Time')) # 小周期开盘时间数组
#Open_5 = records_5['Open']
#High_5 = records_5['High']
#Low_5 = records_5['Low']
Close_5 = pd.Series(ticks_(records_5,'Close')) # 小周期收盘价数组
Time_15 = records_15[-1]['Time']
Time_15_list = pd.Series(ticks_(records_15,'Time')) # 小周期开盘时间数组
#Open_5 = records_5['Open']
#High_5 = records_5['High']
#Low_5 = records_5['Low']
Close_15 = pd.Series(ticks_(records_15,'Close')) # 小周期收盘价数组
#Log(2)
'''
nowdea_15 = dea_15[-1]
nowdiff_15 = diff_15[-1]
nowmacd_15 = macd_15[-1]
'''
'''
predea_15 = dea_15[-2]
prediff_15 = diff_15[-2]
premacd_15 = macd_15[-2]
'''
#index_1 += 5
if not r or not m:
return
#Log(3,len(r))
if len(r) < _5_lengh: # 过滤K线过短情况
return
#Log(4)
Macd_5 = TA.MACD(r, fastEMA = fastEMA, slowEMA=slowEMA, signalEMA=signalEMA)
diff_5 = Macd_5[0]
dea_5 = Macd_5[1]
macd_5 = pd.Series(Macd_5[2]).fillna(0)
macd_5 = macd_5.values*2 # TA的macd算法未乘以2
Macd_15 = TA.MACD(r, fastEMA = fastEMA, slowEMA=slowEMA, signalEMA=signalEMA)
diff_15 = Macd_15[0]
dea_15 = Macd_15[1]
macd_15 = pd.Series(Macd_15[2]).fillna(0)
macd_15 = macd_15.values*2 # TA的macd算法未乘以2
RSI = TA.RSI(records_5, period = rsi_period)
nowdea_5 = dea_5[-1]
nowdiff_5 = diff_5[-1]
nowmacd_5 = macd_5[-1]
if len(macd_15) > 2:
nowmacd_15 = macd_15[-1]
nowrsi = RSI[-1]
predea_5 = dea_5[-2]
prediff_5 = diff_5[-2]
premacd_5 = macd_5[-2]
if len(macd_15) > 2:
premacd_15 = macd_15[-2]
prersi = RSI[-2]
#Log('K线长度',len(r),'dea_5',len(dea_5),'rsi',len(RSI),preBarTime_1)
if len(macd_15)>0:
#Log(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(records_5[-1]['Time'])/1000)),_D(),macd_15[-1])
pass
#r = records_5
#m = records_15
arr_ = [r,m]
#Log(index_2)
index_2 = index_2.copy()
#index_2 = index_2.tolist()
for i in range(len(arr_)): # i 是k线周期循环
#Log(runTime['arrKIndex'])
for j in range(len(arr_[i])): # 时间周期循环
#Log(arr_[i][j]["Time"],runTime['preBarTime_1'][i])
if arr_[i][j]["Time"] == runTime['preBarTime_1'][i]: # preBarTime初始为0
if i == 0: #5分钟 #index_2 0 8
chart.add(int(index_2[x]), [arr_[i][j]["Time"], arr_[i][j]["Open"], arr_[i][j]["High"], arr_[i][j]["Low"], arr_[i][j]["Close"]], -1) # 选出不同周期K线的index
#Log(1,int(index_2[i]))
if i == 0 and len(arr_[i]) > _5_lengh:
#Log(2)
if j == len(arr_[i]) - 2:
#Log(3)
chart.add(int(index_2[x]) + 1, [arr_[i][j]["Time"], arr_[i][j]["Volume"]],-1)
chart.add(int(index_2[x]) + 2, [arr_[i][j]["Time"], prersi], -1) # 快线
chart.add(int(index_2[x]) + 3, [arr_[i][j]["Time"], prediff_5], -1) # 慢线
chart.add(int(index_2[x]) + 4, [arr_[i][j]["Time"], predea_5], -1)
chart.add(int(index_2[x]) + 5, [arr_[i][j]["Time"], premacd_5], -1)
elif j == len(arr_[i]) - 1:
#Log(4,int(index_2[i]))
chart.add(int(index_2[x]) + 1, [arr_[i][j]["Time"], arr_[i][j]["Volume"]],-1)
#Log(4.1)
chart.add(int(index_2[x]) + 2, [arr_[i][j]["Time"], nowrsi], -1) # 快线
#Log(4.2)
chart.add(int(index_2[x]) + 3, [arr_[i][j]["Time"], nowdiff_5], -1) # 慢线
#Log(4.3)
chart.add(int(index_2[x]) + 4, [arr_[i][j]["Time"], nowdea_5], -1)
#Log(4.4)
chart.add(int(index_2[x]) + 5, [arr_[i][j]["Time"], nowmacd_5], -1)
#Log(4.5)
'''
if i == 1 and len(arr_[i]) > _15_lengh:
if j == len(arr_[i]) - 2:
chart.add(index_2 + 8, [arr_[i][j]["Time"], premacd_15], -1) # 快线
elif j == len(arr_[i]) - 2:
chart.add(index_2 + 8, [arr_[i][j]["Time"], nowmacd_15], -1) # 快线
'''
elif arr_[i][j]["Time"] > runTime['preBarTime_1'][i]: # 初始运行此处 每个5,15分钟运行两次
if i ==1:
pass
#Log(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(arr_[i][j]["Time"])/1000)),time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(runTime['preBarTime_1'][i])/1000)),'//',i)
runTime['preBarTime_1'][i] = arr_[i][j]["Time"] # K线时间赋值给preBarTime
Log(runTime['preBarTime_1'][0],runTime['preBarTime_1'][1])
# 0 7 8 15
chart.add(int(runTime['arrKIndex'][x]), [arr_[i][j]["Time"], arr_[i][j]["Open"], arr_[i][j]["High"], arr_[i][j]["Low"], arr_[i][j]["Close"]])
if i ==0 and len(arr_[i]) > _5_lengh:
#Log('i=0',int(runTime['arrKIndex'][x]))
if j == len(arr_[i]) - 1:
chart.add(int(index_2[x]) + 1, [arr_[i][j]["Time"], arr_[i][j]["Volume"]])
chart.add(int(index_2[x]) + 2, [arr_[i][j]["Time"], nowrsi])
chart.add(int(index_2[x]) + 3, [arr_[i][j]["Time"], nowdiff_5])
chart.add(int(index_2[x]) + 4, [arr_[i][j]["Time"], nowdea_5])
chart.add(int(index_2[x]) + 5, [arr_[i][j]["Time"], nowmacd_5])
if i == 1 and len(arr_[i]) > _15_lengh:
Log('i=1',int(index_2[x]) + 7)
if j == len(arr_[i]) - 1:
chart.add(int(index_2[x]) + 7, [arr_[i][j]["Time"], nowmacd_5])
def main():
"""
"""
global preBarTime_1,macd_15,runTime,_5_lengh,_15_lengh,shortChart,longChart,chart0,chart1,chart2,hart1
if exchange.GetName().find("CTP") == -1:
raise Exception("只支持商品期货CTP")
SetErrorFilter("login|ready|流控|连接失败|初始|Timeout")
mode = exchange.IO("mode", 0)
if mode is None:
raise Exception("切换模式失败,请更新到最新托管者!")
while not exchange.IO("status"):
Sleep(3000)
LogStatus("正在等待与交易服务器连接," + _D())
positions = _C(exchange.GetPosition) # 获取当前持仓信息字典
if len(positions) > 0:
Log("检测到当前持有仓位,系统将开始尝试恢复进度...")
Log("持仓信息:", positions)
tts = [] #
arrChart_1 = [] # 图表数组
arrChart_2 = []
index_ = 0 #
index_2 = []
arrKIndex = []
a = []
b = []
c = []
d = []
#while True:
#Log(1)
symbolFilter = {} # 过滤用数组
arr = Instruments.split(",") # 合约列表
for i in range(len(arr)): # 遍历合约列表
symbol = re.sub(r'/\s+$/g', "", re.sub(r'/^\s+/g', "", arr[i])) # 规整合约字符串
if symbol in symbolFilter.keys(): # 如果 在过滤数组中 存在 名为 symbol的属性,则显示信息 并跳过。
raise Exception(symbol + "已经存在,请检查参数!")
symbolFilter[symbol] = True # 给过滤数组 添加 名为 symbol 的 keys,下次 同样的 合约代码 会被过滤 保证每个合约只对Manager类方法传入一次参数
hasPosition = False # 初始化 hasPosition 变量 false 代表没有持仓
for j in range(len(positions)): # 遍历 获取到的持仓信息
if positions[j]["ContractType"] == symbol: # 如果持仓中有合约名等于symbol
Log('cc')
hasPosition = True # 标记 True 持仓
break # 跳出
#fastPeriod = int(arrFastPeriod[i]) # 规整为数值型
#slowPeriod = int(arrSlowPeriod[i])
Log(123)
obj_1 = shortChart # 实例化Manager类
obj_2 = longChart
index_2.append(index_) # 0 8
index_ += 8 # 长周期的图表index
#tts.append(obj) # tts列表传入 最终根据合约列表 ,生成了若干个品种的 控制对象储存在tts数组
#Log(obj)
arrChart_1.append(obj_1) # 在for循环中 依次把图表信息字典传入图表数组
#arrChart_2.append(obj_2)
a.append(chart0)
b.append(chart1)
c.append(chart2)
d.append(hart1)
Log(len(arrChart_1))
Log(111 if arrChart_1[0]==shortChart else 000)
#arrChart_2.append(obj.longChart)
# 创建图表对象
#chart = Chart([arrChart_1, arrChart_2]) # __isStock" : True表示是highstock图,False表示是highcharts图 使用多图表对象,转为二维数组
#chart = Chart([arrChart_1,arrChart_2])
chart = Chart([a,b,c,d])
#Log(len(arrChart_1),len(arrChart_2))
index_2 = np.array(index_2)
chart.reset() # 清空上次轮询的图表数据
while True:
#c = Chart(shortChart)
preTicker = None
#while True:
#Log(1)
if exchange.IO('status'):
LogStatus(_D(),'已经连接')
#t = exchange.GetTicker()
plot(arr,_5_lengh,_15_lengh,index_2,runTime,chart)
Sleep(1000)
'''
if i ==0:
if signals['buy_sell_sig'+str(trueSymbol)] ==1:
Log(1)
#ext.PlotFlag(r[-2]['Time'],'开多','L','circlepin','K')
chart.add(index_2 + 6, [arr_[i][j]["Time"], {'X':arr_[i][j]["Time"],'title':'L','text':'开多'}])
signals['buy_sell_sig'+str(trueSymbol)] =0
if signals['buy_sell_sig'+str(trueSymbol)] ==2:
Log(2)
#ext.PlotFlag(r[-2]['Time'],'开空','S','circlepin','K')
chart.add(index_2 + 6, [arr_[i][j]["Time"], {'X':arr_[i][j]["Time"],'title':'S','text':'开空'}])
signals['buy_sell_sig'+str(trueSymbol)] =0
if signals['buy_sell_sig'+str(trueSymbol)] ==3:
Log(3)
#ext.PlotFlag(r[-2]['Time'],'平多','UL','circlepin','K')
chart.add(index_2 + 6, [arr_[i][j]["Time"], {'X':arr_[i][j]["Time"],'title':'UL','text':'平多'}])
signals['buy_sell_sig'+str(trueSymbol)] =0
if signals['buy_sell_sig'+str(trueSymbol)] ==4:
Log(4)
#ext.PlotFlag(r[-2]['Time'],'平空','US','circlepin','K')
chart.add(index_2 + 6, [arr_[i][j]["Time"], {'X':arr_[i][j]["Time"],'title':'US','text':'平空'}])
signals['buy_sell_sig'+str(trueSymbol)] =0
'''
#index_1 += 9 # 短周期的图表index
template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6