添加CCI上下界;添加POC,poc计算显示区域最新的k线相比poc的收益 poc_range_profit%
This commit is contained in:
90
chart.py
90
chart.py
@@ -2,11 +2,14 @@ import pandas as pd
|
||||
from db_config import DatabaseManager, DatabaseConfig
|
||||
from loguru import logger
|
||||
import talib as ta
|
||||
import numpy as np
|
||||
from lightweight_charts import Chart
|
||||
|
||||
|
||||
import random
|
||||
|
||||
horizontal_lines = {}
|
||||
|
||||
|
||||
def get_fixed_color_based_on_period(period):
|
||||
# 使用周期值作为随机种子,确保相同周期生成相同颜色
|
||||
@@ -30,7 +33,9 @@ def add_ema(df, chart, period: int = 50):
|
||||
name = f"EMA {period}"
|
||||
df[name] = ta.EMA(df["close"], timeperiod=period)
|
||||
color = get_fixed_color_based_on_period(period)
|
||||
line = chart.create_line(name, color=color, width=2)
|
||||
line = chart.create_line(
|
||||
name, color=color, width=2, price_label=False, price_line=False
|
||||
)
|
||||
line.set(df[["time", name]])
|
||||
|
||||
|
||||
@@ -46,6 +51,27 @@ def add_cci(df, chart, period: int = 14, height: float = 0.1, position: str = "b
|
||||
cci_chart.time_scale(visible=False)
|
||||
cci_line = cci_chart.create_line(name="cci", color="#FF0000", width=2)
|
||||
cci_line.set(df[["time", "cci"]])
|
||||
df = df[["time"]].copy()
|
||||
df["h"] = 100
|
||||
df["l"] = -100
|
||||
cci_line = cci_chart.create_line(
|
||||
name="h",
|
||||
color="#D4C21C",
|
||||
width=1,
|
||||
style="dashed",
|
||||
price_label=False,
|
||||
price_line=False,
|
||||
)
|
||||
cci_line.set(df[["time", "h"]])
|
||||
cci_line = cci_chart.create_line(
|
||||
name="l",
|
||||
color="#D4C21C",
|
||||
width=1,
|
||||
style="dashed",
|
||||
price_label=False,
|
||||
price_line=False,
|
||||
)
|
||||
cci_line.set(df[["time", "l"]])
|
||||
|
||||
|
||||
def add_macd(df, chart, height: float = 0.1, position: str = "bottom"):
|
||||
@@ -70,9 +96,13 @@ def add_macd(df, chart, height: float = 0.1, position: str = "bottom"):
|
||||
)
|
||||
histogram.set(hist_data)
|
||||
|
||||
macd_line = macd_chart.create_line(name="macd", color="#2962FF", width=2)
|
||||
macd_line = macd_chart.create_line(
|
||||
name="macd", color="#2962FF", width=2, price_label=False, price_line=False
|
||||
)
|
||||
macd_line.set(df[["time", "macd"]])
|
||||
signal_line = macd_chart.create_line(name="signal", color="#FF0000", width=2)
|
||||
signal_line = macd_chart.create_line(
|
||||
name="signal", color="#FF0000", width=2, price_label=False, price_line=False
|
||||
)
|
||||
signal_line.set(df[["time", "signal"]])
|
||||
|
||||
|
||||
@@ -229,13 +259,64 @@ def resample_data(df: pd.DataFrame, timeframe: str) -> pd.DataFrame:
|
||||
return resampled
|
||||
|
||||
|
||||
def POC(df, bins: int = 50):
|
||||
low, high = df["low"].min(), df["high"].max()
|
||||
edges = np.linspace(low, high, bins + 1)
|
||||
# 为每根K线生成 bins 个均匀价格点,并分配等量成交量
|
||||
prices = np.concatenate(
|
||||
[np.linspace(r["low"], r["high"], bins) for _, r in df.iterrows()]
|
||||
)
|
||||
volumes = np.repeat(df["volume"].values / bins, bins)
|
||||
# 分箱求和
|
||||
vol_profile, _ = np.histogram(prices, bins=edges, weights=volumes)
|
||||
# 返回最大成交量区间的中点
|
||||
idx = np.argmax(vol_profile)
|
||||
poc = (edges[idx] + edges[idx + 1]) / 2
|
||||
return poc
|
||||
|
||||
|
||||
def on_range_change_poc(chart, bars_before, bars_after):
|
||||
df = chart.candle_data
|
||||
if df is None or df.empty:
|
||||
return
|
||||
|
||||
total_bars = len(df)
|
||||
if bars_after < 0:
|
||||
start_idx = max(0, int(bars_before))
|
||||
end_idx = total_bars
|
||||
else:
|
||||
start_idx = int(bars_before)
|
||||
end_idx = max(0, int(total_bars - bars_after))
|
||||
df_range = df.iloc[start_idx:end_idx]
|
||||
# logger.info(
|
||||
# f"Calculating POC for bars {start_idx} to {end_idx}, total_bars={total_bars}, bars_before={bars_before}, bars_after={bars_after}"
|
||||
# )
|
||||
# logger.info(f"df_range_len: {len(df_range)}")
|
||||
poc = POC(df_range)
|
||||
poc_line_name = "POC"
|
||||
if poc_line_name in horizontal_lines:
|
||||
horizontal_lines[poc_line_name].delete()
|
||||
# 添加新的 POC 水平线
|
||||
latest_close = df_range["close"].iloc[-1]
|
||||
profit = (latest_close - poc) / poc * 100
|
||||
poc_line = chart.horizontal_line(
|
||||
price=poc, color="#FF0000", width=4, style="solid", text=f"{poc:.2f}"
|
||||
)
|
||||
chart.legend(
|
||||
visible=True,
|
||||
text=f"POC: {poc:.2f}, poc_range_profit%: {profit:.1f}%, tf_cnt: {len(df_range)}",
|
||||
)
|
||||
|
||||
horizontal_lines[poc_line_name] = poc_line
|
||||
|
||||
|
||||
def plot_chart(df, symbol: str, name: str, timeframe: str):
|
||||
"""
|
||||
df: DataFrame
|
||||
time, open, high, low, close, volume, [buy, sell]可选 buy=1 买入信号, sell=1 卖出信号
|
||||
|
||||
"""
|
||||
chart = Chart(toolbox=True, inner_height=0.6, maximize=True)
|
||||
chart = Chart(toolbox=True, inner_height=0.8, maximize=True)
|
||||
|
||||
chart.topbar.textbox("symbol", symbol)
|
||||
chart.topbar.textbox("name", name)
|
||||
@@ -246,6 +327,7 @@ def plot_chart(df, symbol: str, name: str, timeframe: str):
|
||||
)
|
||||
|
||||
chart.set(df)
|
||||
chart.events.range_change += on_range_change_poc
|
||||
add_ema(df, chart, period=10)
|
||||
add_ema(df, chart, period=20)
|
||||
add_ema(df, chart, period=30)
|
||||
|
||||
Reference in New Issue
Block a user