如何将tbquant上的策略转换成python代码

怎么把tbquant上的策略给转换成python代码啊?有大神能详细指点一下吗?生成出来的回测曲线一直跟软件上的完全不符,卡在这里好久了😭

老代码转换成tbquant的
TBQuant连接python python调试代码就报错
如何将Numeric或者是Integer类型转换成String类型
Python
关于Python直接交易的代码
TBQuant的Python安装包tbpy从哪里下载
请问如何将原旗舰版公式转换为TBQuant的公式
有懂python的吗, 求大神帮我把下面这个指标代码,完全转换成TB的公式代码, 求解答,这个指标我很喜欢用,但是不懂python,所以我自己复制不出来tb这里
python 和tbquant 通讯
如何将最新价转换成对手价
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

class VolumeWeightedMomentumSys:
    def __init__(self, data, mom_len=5, avg_len=20, atr_len=5, atr_pcnt=0.5, setup_len=5, fixed_size=1):
        self.data = data
        self.mom_len = mom_len
        self.avg_len = avg_len
        self.atr_len = atr_len
        self.atr_pcnt = atr_pcnt
        self.setup_len = setup_len
        self.fixed_size = fixed_size
        
        # Variables to track
        self.vwm = None  # 成交量加权动量
        self.atr = None  # ATR
        self.se_price = 0  # 当前价格通道
        self.ssetup = 0  # 条件计数器
        self.intra_trade_high = 0
        self.intra_trade_low = 0
        self.position = 0  # 持仓:0为无仓,-1为空单
        self.profits = []  # 用于存储交易盈亏
        self.capital_curve = []  # 资金曲线
        self.current_capital = 100000  # 初始资本
        self.dates = []  # 保存完整的日期
        
        self.init_indicators()  # 初始化指标
        
    def init_indicators(self):
        """初始化指标计算"""
        # 计算动量
        momentum = self.data['close'].diff(self.mom_len)
        # 计算成交量加权动量 (VWM)
        vol_momentum = self.data['vol'] * momentum
        self.vwm = vol_momentum.rolling(window=self.avg_len).mean()
        # 计算ATR
        high_low = self.data['high'] - self.data['low']
        high_close = (self.data['high'] - self.data['close'].shift()).abs()
        low_close = (self.data['low'] - self.data['close'].shift()).abs()
        true_range = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
        self.atr = true_range.rolling(window=self.atr_len).mean()
    
    def on_bar(self, bar_index):
        """逐根K线回测逻辑"""
        # 检查是否足够数据初始化
        if bar_index < max(self.avg_len, self.atr_len):
            # 保持资金和日期不变
            self.capital_curve.append(self.current_capital)
            self.dates.append(self.data.index[bar_index])
            return
        
        # 获取当前K线数据
        bar = self.data.iloc[bar_index]
        
        # 检查是否有持仓
        if self.position == 0:
            self.intra_trade_high = bar['high']
            self.intra_trade_low = bar['low']
            
            # 判断空头势
            if self.vwm.iloc[bar_index] < 0:
                self.ssetup = 0
                self.se_price = bar['close']
            else:
                self.ssetup += 1

            # 入场条件
            if self.ssetup <= self.setup_len and self.ssetup >= 1:
                entry_price = self.se_price - (self.atr.iloc[bar_index] * self.atr_pcnt)
                if bar['low'] <= entry_price:
                    # 做空
                    self.position = -1
                    self.entry_price = entry_price
                    self.intra_trade_high = bar['high']
                    print(f"Sell short at {entry_price} on {bar.name}")
                    
        elif self.position == -1:
            # 更新最高价格
            self.intra_trade_high = max(self.intra_trade_high, bar['high'])
            
            # 出场条件
            if self.vwm.iloc[bar_index] > 0:
                exit_price = bar['open']  # 平仓价为开盘价
                profit = (self.entry_price - exit_price) * self.fixed_size
                self.current_capital += profit  # 更新资金
                self.profits.append(profit)
                self.position = 0
                print(f"Buy to cover at {exit_price} on {bar.name}. Profit: {profit}")
        
        # 记录资金曲线和日期
        self.capital_curve.append(self.current_capital)
        self.dates.append(bar.name)
    
    def backtest(self):
        """运行回测"""
        for i in range(len(self.data)):
            self.on_bar(i)
        
        # 打印总盈亏
        total_profit = sum(self.profits)
        print(f"Total profit: {total_profit}")
        return self.capital_curve, self.dates

# 加载数据
open_data = pd.read_csv(r'C:\Users\User\Desktop\data(min5)\open.csv', index_col=0, parse_dates=True)
close_data = pd.read_csv(r'C:\Users\User\Desktop\data(min5)\close.csv', index_col=0, parse_dates=True)
high_data = pd.read_csv(r'C:\Users\User\Desktop\data(min5)\high.csv', index_col=0, parse_dates=True)
low_data = pd.read_csv(r'C:\Users\User\Desktop\data(min5)\low.csv', index_col=0, parse_dates=True)
vol_data = pd.read_csv(r'C:\Users\User\Desktop\data(min5)\vol.csv', index_col=0, parse_dates=True)

# 将数据合并成一个DataFrame
data = pd.DataFrame({
    'open': open_data['ag'],
    'close': close_data['ag'],
    'high': high_data['ag'],
    'low': low_data['ag'],
    'vol': vol_data['ag'],
}, index=open_data.index)

# 初始化策略
strategy = VolumeWeightedMomentumSys(data)

# 回测
profits, dates = strategy.backtest()

# 绘制资金曲线
plt.figure(figsize=(12, 6))
plt.plot(dates, np.cumsum(profits), label='Cumulative Profit')  # 累积盈亏
plt.xlabel('Date')
plt.ylabel('Profit')
plt.title('Capital Curve Over Time')
plt.legend()
plt.grid()
plt.show()


//------------------------------------------------------------------------
// 简称: VolumeWeightedMomentumSys_S
// 名称: 成交量加权动量交易系统 空
// 类别: 策略应用
// 类型: 内建应用
// 输出:
// 策略说明:
//            基于动量系统, 通过交易量加权进行判断
//             
// 系统要素:
//             1. 用UWM下穿零轴判断空头趋势
// 入场条件:
//             1. 价格低于UWM下穿零轴时价格通道,在SetupLen的BAR数目内,做空
//             
// 出场条件: 
//             1. 多头势空单出场
//         注: 
//----------------------------------------------------------------------//
Params 
    Numeric MomLen(5);                                                 //UWM参数
    Numeric AvgLen(20);                                             //UWM参数
    Numeric ATRLen(5);                                                 //ATR参数
    Numeric ATRPcnt(0.5);                                             //入场价格波动率参数
    Numeric SetupLen(5);                                            //条件持续有效K线数
Vars
    Series<Numeric> VWM(0); 
    Series<Numeric> AATR(0);  
    Series<Numeric> SEPrice(0);  
    Series<Bool> BullSetup(False); 
    Series<Bool> BearSetup(False); 
    Series<Numeric> SSetup(0);
Events
    OnBar(ArrayRef<Integer> indexs)
    {
        
        
        VWM = XAverage(Vol * Momentum(Close, MomLen), AvgLen);            //定义UWM
        AATR = AvgTrueRange(ATRLen);                                    //ATR
        BullSetup = CrossOver(VWM,0);                                    //UWM上穿零轴定义多头势
        BearSetup = CrossUnder(VWM,0);                                    //UWM下穿零轴定义空头势
        If (BearSetup )                                                 //空头势开始计数并记录当前价格
        {
            SSetup = 0;
            SEPrice = Close;
        }
        Else    SSetup = SSetup[1] + 1;                                        //每过一根BAR计数    
        //系统入场
        If (CurrentBar > AvgLen And MarketPosition == 0 ) //当空头势满足并且在SetupLen的BAR数目内,当价格达到入场价格后,做空
        {
            If( Low <=SEPrice[1] - (ATRPcnt * AATR[1]) And SSetup[1] <= SetupLen And SSetup >= 1 And Vol > 0) 
            {
                SellShort(0, Min(Open,SEPrice[1] - (ATRPcnt * AATR[1]))) ;
            }
        }
        //系统出场
        If (MarketPosition == -1 And  BarsSinceEntry > 0 And Vol > 0)  //多头势平掉空单
        {
            If( BullSetup[1] == True )
            {
                Buytocover(0,Open);
            }
        }
    }
//------------------------------------------------------------------------
// 编译版本    GS2014.10.25
// 版权所有    TradeBlazer Software 2003-2025
// 更改声明    TradeBlazer Software保留对TradeBlazer平
//            台每一版本的TradeBlazer公式修改和重写的权利
//------------------------------------------------------------------------


python每次跑出来的曲线都差不多长这样的,跟tb上完全不一样😭