根据前面文章“低门槛搭建个人量化平台 — 第五天:自定义功能和指标”(在【1】中),不仅可以在自已的量化平台上修改K线图形及各式设置,在图表上显示一些自定义数据或指标,而且还可以随心所欲增加自己感兴趣的个性化扩展定制内容。
本篇简要介绍,怎样将自己的实盘交易操作信息,同步记录并显示在K线图上。
一个图例如下:白糖SR2109合约的小时K线图上,B代表买入,S代表卖出。当鼠标移动到圆圈上浮动显示具体信息,包含当时交易买卖的时间、手数、价格、手续费等。这样结合日志功能,方便自己复盘分析。
来源: adog.net.cn
下面是通过 tradingView GET /marks 方法实现的,说明如下:
Request:GET /marks?symbol=<ticker_name>&from=<unix_timestamp>&to=<unix_timestamp>&resolution=<resolution>
symbol: symbol name or ticker.
from: unix timestamp (UTC) or leftmost visible bar
to: unix timestamp (UTC) or rightmost visible bar
resolution: string
Response: 响应预期是一个对象,下面列出了一些属性。此对象与JS API中的respective response相似,但每个属性都被视为表的列,如上所述。
{
id: [array of ids],
time: [array of times],
color: [array of colors],
text: [array of texts],
label: [array of labels],
labelFontColor: [array of label font colors],
minSize: [array of minSizes],
}
Remark: 备注:如果您的datafeed在传输的配置数据中发送了supports_marks:true,则会调用此方法。
在下面的 marks(request) 方法中,将数据获取后,根据15、30、60分钟及日、周周期对交易数量、交易金额、交易手续费等进行聚合统计,以满足K线图在不同时间周期下的调用和显示。
def marks(request):
def getDataByFreq(code,dx,freqx):
dx[&#39;dt&#39;]=pd.to_datetime(dx[&#39;dtime&#39;])
dx.set_index(&#39;dt&#39;,inplace=True)
cheshu=max(dx[&#39;cheshu&#39;])
d_hands=dx.hands.resample(freqx).agg({&#39;hands&#39;: &#39;sum&#39;}).unstack().T
d_amount=dx.amount.resample(freqx).agg({&#39;amount&#39;: &#39;sum&#39;}).unstack().T.round(1)
d_fee=dx[&#39;手续费&#39;].resample(freqx).agg({&#39;手续费&#39;: &#39;sum&#39;}).unstack().T.round(1)
df=d_hands.join(d_amount).join(d_fee)
hands&#39;]!=0.0)&(df[&#39;amount&#39;]!=0.0)&(df[&#39;手续费&#39;]!=0.0)]
df=df[(df[&#39;hands&#39;]!=0.0)]
df.reset_index(drop=False,inplace=True)
df[&#39;dt&#39;]=df[&#39;dt&#39;].astype(str)
df[&#39;avgPrice&#39;]=df.apply(lambda d: 0. if d.hands==0. else d.amount/d.hands/cheshu,axis=1).round(1)
if &#39;D&#39; in freqx or &#39;W&#39; in freqx:
df[&#39;time&#39;]=df.apply(lambda d: xtool.timeString2timeLong(d[&#39;dt&#39;],format=&#39;day&#39;),axis=1)
elif &#39;min&#39; in freqx:
df[&#39;time&#39;]=df.apply(lambda d: xtool.timeString2timeLong(d[&#39;dt&#39;],format=&#39;sec&#39;),axis=1)
df[&#39;color&#39;]=df.apply(lambda d: \
{ &#39;border&#39;: &#39;#d2a99d&#39;, &#39;background&#39;: &#39;#d2a99d&#39; } if d[&#39;hands&#39;]>=0 \
else { &#39;border&#39;: &#39;#94becc&#39;, &#39;background&#39;: &#39;#94becc&#39; },axis=1)
df[&#39;label&#39;]=df.apply(lambda d: &#39;Buy&#39; if d[&#39;hands&#39;]>=0 else &#39;Sell&#39;,axis=1)
df[&#39;text&#39;]= df.apply(lambda d: &#39;%s <br>%s <br> %s: %s hand<br>avg Price:%s <br> amount: %s <br> fee: %s&#39;%(d[&#39;dt&#39;],
code,
d[&#39;label&#39;],
d[&#39;hands&#39;],
d[&#39;avgPrice&#39;],
d[&#39;amount&#39;],
d[&#39;手续费&#39;]
),axis=1)
df[&#39;labelFontColor&#39;]=&#39;#5a533a&#39;
df[&#39;minSize&#39;]=20
#df=df.round(1)
df[&#39;id&#39;]=df.index
df=df[[&#39;id&#39;,&#39;time&#39;,&#39;color&#39;,&#39;text&#39;,&#39;label&#39;,&#39;labelFontColor&#39;,&#39;minSize&#39;]]
return df
code = request.GET.get(&#34;symbol&#34;,&#34;A8888&#34;).upper()
freq = request.GET.get(&#34;resolution&#34;,&#34;1D&#34;).upper()
code=xtool.code_jq2wxy(code, broker=None)
sql_cmffc=&#39;select acc,合约,实际成交日期,成交时间,买卖,开平,手数,成交价,成交额,手续费,平仓盈亏 from acc.deal_fut_cfmmc where 合约 = &#34;%s&#34; order by 实际成交日期,成交时间&#39;%(code)
data=dbcom.select_tuple_dict(sql_cmffc)
data=pd.DataFrame(data)
sql_wxy=&#39;select InvestorID acc,InstrumentID 合约,TradingDay 实际成交日期,TradeTime 成交时间,IF(Direction=&#34;0&#34;,&#34;买&#34;,&#34;卖&#34;) 买卖,IF(TradeType=&#34;0&#34;,&#34;开&#34;,&#34;平&#34;) 开平,TradeVolume 手数,TradePrice 成交价,TradeAmnt 成交额,UsedFee 手续费,CloseProfit 平仓盈亏 from acc.XS_Trade where InstrumentID = &#34;%s&#34; order by TradingDay,TradeTime&#39;%(code)
data_wxy=dbcom.select_tuple_dict(sql_wxy)
data_wxy=pd.DataFrame(data_wxy)
if len(data_wxy)>0:
data_wxy[&#39;实际成交日期&#39;]=data_wxy.apply(lambda df: TD.getBefAftTradeDay(df[&#39;实际成交日期&#39;][:4]+&#34;-&#34;+df[&#39;实际成交日期&#39;][4:6]+&#34;-&#34;+df[&#39;实际成交日期&#39;][6:],-1,verbose=False) \
if df[&#39;成交时间&#39;]>=&#39;21:00:00&#39; else df[&#39;实际成交日期&#39;][:4]+&#34;-&#34;+df[&#39;实际成交日期&#39;][4:6]+&#34;-&#34;+df[&#39;实际成交日期&#39;][6:],axis=1)
data=data.append(data_wxy)
if data is not None and len(data)>0:
data[&#39;平仓盈亏&#39;]=data.apply(lambda df: &#39;0.&#39; if df[&#39;平仓盈亏&#39;]==&#39;--&#39; else df[&#39;平仓盈亏&#39;],axis=1)
data[[&#39;手数&#39;,&#39;成交价&#39;,&#39;成交额&#39;,&#39;手续费&#39;,&#39;平仓盈亏&#39;]]=data[[&#39;手数&#39;,&#39;成交价&#39;,&#39;成交额&#39;,&#39;手续费&#39;,&#39;平仓盈亏&#39;]].astype(float)
data[&#39;dtime&#39;]=data[&#39;实际成交日期&#39;]+&#39; &#39;+data[&#39;成交时间&#39;]
data[&#39;hands&#39;]=data.apply(lambda df: df[&#39;手数&#39;] if df[&#39;买卖&#39;]==&#39;买&#39; else -df[&#39;手数&#39;],axis=1)
cheshu=int(max(max(data[&#39;成交额&#39;]/data[&#39;成交价&#39;]),1))
data[&#39;cheshu&#39;]=cheshu
data[&#39;amount&#39;]=data.apply(lambda df: df[&#39;成交价&#39;]*df[&#39;手数&#39;]*df[&#39;cheshu&#39;]-df[&#39;手续费&#39;]+df[&#39;平仓盈亏&#39;] if df[&#39;买卖&#39;]==&#39;买&#39; else -(df[&#39;成交价&#39;]*df[&#39;手数&#39;]*df[&#39;cheshu&#39;]-df[&#39;手续费&#39;]+df[&#39;平仓盈亏&#39;]),axis=1)
if freq==&#39;1D&#39;:
data=getDataByFreq(code,data,&#39;1D&#39;)
elif freq==&#39;1W&#39; or freq==&#39;W&#39;:
data=getDataByFreq(code,data,&#39;1W&#39;)
elif freq==&#39;15&#39; or freq==&#39;30&#39;:
data=getDataByFreq(code,data,freq+&#39;min&#39;)
elif freq==&#39;60&#39; or freq==&#39;1H&#39; or freq==&#39;1h&#39;:
data=getDataByFreq(code,data,&#39;60min&#39;)
dict=data.to_dict(&#39;list&#39;)
return dict
同时别忘记在总配置 config() 中,将 &#34;supports_marks&#34; 设为 True。
def config():
dict= {
&#34;supports_search&#34;:True,
&#34;supports_group_request&#34;:False,
&#34;supports_marks&#34;:True,
...
仅两步,步骤不复杂。但需要提前准备好自己的实时或历史行情数据和交易数据(【2】)。
请点赞支持。如有疑问,可以到我的知识星球详细讨论或下载源码。
参考:
- 【1】阿岛格专栏:低门槛搭建个人量化平台
- 【2】阿岛格:低门槛搭建个人量化平台 — 第四天:实时数据
- 【3】阿岛格专栏:基于人工智能的量化投资
|
|