Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fixed the problem of vnpy_futu in the prod env #8

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

linwaiwai
Copy link

When querying historical data, the all_data parameter was set but not used. As a result, when the data size exceeds 1000, only 1000 records are returned, which affects both the visual chart and the strategy.

@linwaiwai linwaiwai changed the title fix: 修复查询历史超1000条缺漏分页问题 fix: Fixed the problem of missing pagination when query history exceeds 1,000 items Mar 3, 2025
@linwaiwai
Copy link
Author

when there are multiple postion with the same symbol in futu. The positions show in the ui
is wrong . In this pull request , I try to merge all position with the same symbol.

@linwaiwai linwaiwai changed the title fix: Fixed the problem of missing pagination when query history exceeds 1,000 items fix: Fixed the problem of vnpy_futu in the prod env Mar 5, 2025
@linwaiwai
Copy link
Author

linwaiwai commented Mar 5, 2025

There are problems still in the backtest when trading the us stock market
1、The comission should supports expression as the caculate rule isn't according the rate .
2、When shorting some stock, there are short interest which should be caculated.
3、The simulate env of futu didn't return all trades. So when you want to connnect the simulate env, the order status will not be changed without notification. I figured out that the trade notification should work. Base this, I added some code after on_stop_order to accept the notification of order in the simulate env. It works!

Refers: Backtesting.py

    def calculate_pnl(
        self,
        pre_close: float,
        start_pos: float,
        size: int,
        rate: float,
        slippage: float
    ) -> None:
        """"""
        # If no pre_close provided on the first day,
        # use value 1 to avoid zero division error
        if pre_close:
            self.pre_close = pre_close
        else:
            self.pre_close = 1

        # Holding pnl is the pnl from holding position at day start
        self.start_pos = start_pos
        self.end_pos = start_pos

        self.holding_pnl = self.start_pos * (self.close_price - self.pre_close) * size

        # Trading pnl is the pnl from new trade during the day
        self.trade_count = len(self.trades)

        for trade in self.trades:
            if trade.direction == Direction.LONG:
                pos_change = trade.volume
            else:
                pos_change = -trade.volume

            self.end_pos += pos_change

            
            self.trading_pnl += pos_change * \
                (self.close_price - trade.price) * size
            self.slippage += trade.price * trade.volume * size * slippage

            turnover: float = trade.volume * size * trade.price
            self.turnover += turnover

            turnover: float = trade.volume * size * trade.price
            commission = min(max(0.0049 * trade.volume * size, 0.99), 0.005 * turnover)  # 佣金
            platform_fee = min(max(0.005 * trade.volume * size, 1), 0.005 * turnover)  # 平台使用费
            transaction_fee = 0.003 * trade.volume * size  # 交收费
            
            total_fee = commission + platform_fee + transaction_fee
            if trade.direction == Direction.LONG:
                # 计算买入时的手续费
                
                self.commission += total_fee  # 更新手续费
            else:
               # 计算卖出时的手续费
                regulatory_fee = max(0.0000278 * turnover, 0.01)  # 证监会规费
                activity_fee = min(max(0.000166 * trade.volume * size, 0.01), 8.3)  # 交易活动费
                
                total_fee = total_fee + regulatory_fee + activity_fee  # 只计算卖出时的手续费
                self.commission +=  total_fee  # 更新手续费  

        # 计算融券隔夜利息
        if self.end_pos < 0:  # 如果是空头持仓
            short_value = abs(self.end_pos) * self.close_price * size  # 计算空头市值
            self.short_interest = short_value * 0.06 / 365  # 年化6%的融券利率

        # 修改净盈亏计算,加入融券利息成本
        self.total_pnl = self.trading_pnl + self.holding_pnl
        self.net_pnl = self.total_pnl - self.commission - self.slippage - self.short_interest

@linwaiwai
Copy link
Author

linwaiwai commented Mar 7, 2025

Vnpy cta strategies can't use in prod for the reason that after booting stragies , in the trading time, the low price in the first coming bar sometims is zero , which will let you broken if you don't correct it. So I am extremely sure that all these cta strategies were not used ever. All these just make a notice for the guys like me who want to use it in prod env.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant