量化交易之Python篇 - 亏损持仓周期(pandas) - lossClose_holdPositions_period_api.py

import re
import os
import pandas

from typing import List

from tools_part.file_path_operator.file_path_operator import TQZFilePathOperator
from tools_part.pandas_operator.pandas_operator import TQZPandas
from tools_part.split_dataframe_operator.split_dataframe_operator import TQZSplitDataframeOperator

from constants_part.tqz_constant import (
    TQZFunctionModuleType,
    TQZClosePositionsDetailColumnType,
    TQZDefaultKey,
    TQZHoldPositionsPeriodKey
)


TQZPandas.pre_set()


class TQZLossCloseHoldPositionsPeriodApi:

    __datas_part_fold = TQZFilePathOperator.current_file_grandfather_path(
        file=__file__
    ) + f'/source_datas_part'

    @classmethod
    def tqz_lossClose_hold_positions_period(cls, account_names: List):
        """
        Api of get loss-hold-positions-period of account, return a value(type of dictionary).
        """

        account_lossHoldPositionsPeriod_dictionary = {}
        for datas_part_file in os.listdir(path=cls.__datas_part_fold):  # one datas_part_file is one account

            account_name = re.search(r'^[a-zA-Z0-9]+', datas_part_file).group()
            if account_name not in account_names:
                continue

            current_account_trade_record_fold = f'{cls.__datas_part_fold}/{datas_part_file}/交易记录'
            last_day_lossHold_positions_period_dataframe = cls.__get_last_day_lossClose_hold_positions_period_dataframe(
                current_account_trade_record_fold=current_account_trade_record_fold
            )

            account_lossHoldPositionsPeriod_dictionary[account_name] = last_day_lossHold_positions_period_dataframe
            print("last_day_lossHold_positions_period_dataframe: " + str(last_day_lossHold_positions_period_dataframe))

        return account_lossHoldPositionsPeriod_dictionary


    # --- loss close positions private part ---
    @classmethod
    def __get_today_open_hold_close_lossClose_positions_dataframes(cls, trade_record_all_path):
        """
        Get today_open_positions_dataframe & today_hold_positions_dataframe & today_close_positions_dataframe & today_lossClose_positions_dataframe with trade_record_all_path.
        """

        # today open
        today_open_positions_dataframe = TQZSplitDataframeOperator.get_open_positions_detail_format_dataframe(
            trade_record_all_path=trade_record_all_path
        )

        # today hold
        today_hold_positions_dataframe = TQZSplitDataframeOperator.get_hold_positions_detail_format_dataframe(
            trade_record_all_path=trade_record_all_path
        )

        # today close
        today_close_positions_dataframe = TQZSplitDataframeOperator.get_close_positions_detail_format_dataframe(
            trade_record_all_path=trade_record_all_path
        )

        # today loss close
        today_lossClose_positions_dataframe = TQZSplitDataframeOperator.get_lossClose_positions_detail_format_dataframe(
            trade_record_all_path=trade_record_all_path
        )

        return today_open_positions_dataframe, today_hold_positions_dataframe, today_close_positions_dataframe, today_lossClose_positions_dataframe

    @classmethod
    def __calculate_todayLossClose_hold_positions_period(cls, today_lossClose_positions_dataframe, yesterday_hold_positions_dataframe):
        """
        Calculate today-loss-close-positions-period, last-day-lossHold-positions-period-dataframe
        """

        today_lossClose_yesterdayHold_positions_dataframe = pandas.merge(
            today_lossClose_positions_dataframe,
            yesterday_hold_positions_dataframe,
            how=TQZDefaultKey.LEFT.value,
            on=[TQZClosePositionsDetailColumnType.CONTRACT.value, TQZClosePositionsDetailColumnType.BUY_SELL.value]
        )
        today_lossClose_yesterdayHold_positions_dataframe.fillna(0, inplace=True)
        today_lossClose_yesterdayHold_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOT.value
        ] = today_lossClose_yesterdayHold_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOT_X.value
        ] - today_lossClose_yesterdayHold_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOT_Y.value
        ]
        today_lossClose_yesterdayHold_positions_dataframe.rename(
            columns={
                TQZHoldPositionsPeriodKey.LOT_X.value: TQZHoldPositionsPeriodKey.TODAY_CLOSE.value,
                TQZHoldPositionsPeriodKey.LOT_Y.value: TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value,
                TQZHoldPositionsPeriodKey.LOT.value: TQZHoldPositionsPeriodKey.TODAY_CLOSE_SUB_YESTERDAY_HOLD.value
            },
            inplace=True
        )
        today_lossClose_yesterdayHold_positions_dataframe.loc[
            today_lossClose_yesterdayHold_positions_dataframe[
                TQZHoldPositionsPeriodKey.TODAY_CLOSE_SUB_YESTERDAY_HOLD.value
            ] <= 0,
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ] = yesterday_hold_positions_dataframe[
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ]
        today_lossClose_yesterdayHold_positions_dataframe.loc[
            today_lossClose_yesterdayHold_positions_dataframe[
                TQZHoldPositionsPeriodKey.TODAY_CLOSE_SUB_YESTERDAY_HOLD.value
            ] >= 0, TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ] = round(
            (today_lossClose_yesterdayHold_positions_dataframe[
                 TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value
             ] / today_lossClose_yesterdayHold_positions_dataframe[
                 TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
             ]) * yesterday_hold_positions_dataframe[
                TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
            ],
            5
        )

        today_lossHold_positions_period_dataframe = pandas.DataFrame()
        today_lossHold_positions_period_dataframe[
            TQZHoldPositionsPeriodKey.CONTRACT.value
        ] = today_lossClose_yesterdayHold_positions_dataframe[
            TQZHoldPositionsPeriodKey.CONTRACT.value
        ]
        today_lossHold_positions_period_dataframe[
            TQZHoldPositionsPeriodKey.BUY_SELL.value
        ] = today_lossClose_yesterdayHold_positions_dataframe[
            TQZHoldPositionsPeriodKey.BUY_SELL.value
        ]
        today_lossHold_positions_period_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
        ] = today_lossClose_yesterdayHold_positions_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
        ]
        today_lossHold_positions_period_dataframe[
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ] = today_lossClose_yesterdayHold_positions_dataframe[
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ]
        today_lossHold_positions_period_dataframe.sort_values(
            TQZHoldPositionsPeriodKey.CONTRACT.value,
            inplace=True
        )
        today_lossHold_positions_period_dataframe.reset_index(inplace=True)
        del today_lossHold_positions_period_dataframe[TQZDefaultKey.INDEX.value]

        today_lossHold_positions_period_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_BUY.value
        ] = today_lossHold_positions_period_dataframe.loc[
            today_lossHold_positions_period_dataframe[
                TQZHoldPositionsPeriodKey.BUY_SELL.value
            ] == TQZHoldPositionsPeriodKey.BUY.value,
            TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
        ]
        today_lossHold_positions_period_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_SELL.value
        ] = today_lossHold_positions_period_dataframe.loc[
            today_lossHold_positions_period_dataframe[
                TQZHoldPositionsPeriodKey.BUY_SELL.value
            ] == TQZHoldPositionsPeriodKey.SELL.value,
            TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
        ]
        today_lossHold_positions_period_dataframe[
            TQZHoldPositionsPeriodKey.BUY_LOSS_HOLD_POSITION_PERIOD.value
        ] = today_lossHold_positions_period_dataframe.loc[
            today_lossHold_positions_period_dataframe[
                TQZHoldPositionsPeriodKey.BUY_SELL.value
            ] == TQZHoldPositionsPeriodKey.BUY.value,
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ]
        today_lossHold_positions_period_dataframe[
            TQZHoldPositionsPeriodKey.SELL_LOSS_HOLD_POSITION_PERIOD.value
        ] = today_lossHold_positions_period_dataframe.loc[
            today_lossHold_positions_period_dataframe[
                TQZHoldPositionsPeriodKey.BUY_SELL.value
            ] == TQZHoldPositionsPeriodKey.SELL.value,
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ]
        today_lossHold_positions_period_dataframe.fillna(0, inplace=True)
        today_lossHold_positions_period_dataframe = today_lossHold_positions_period_dataframe.groupby(
            [TQZHoldPositionsPeriodKey.CONTRACT.value]
        ).sum()
        today_lossHold_positions_period_dataframe.reset_index(inplace=True)
        del today_lossHold_positions_period_dataframe[TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value]

        today_lossHold_positions_period_dataframe[
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ] = round(
            (today_lossHold_positions_period_dataframe[TQZHoldPositionsPeriodKey.TODAY_BUY.value] /
             today_lossHold_positions_period_dataframe[TQZHoldPositionsPeriodKey.TODAY_CLOSE.value]) *
            today_lossHold_positions_period_dataframe[
                TQZHoldPositionsPeriodKey.BUY_LOSS_HOLD_POSITION_PERIOD.value] + (
                    today_lossHold_positions_period_dataframe[TQZHoldPositionsPeriodKey.TODAY_SELL.value] /
                    today_lossHold_positions_period_dataframe[TQZHoldPositionsPeriodKey.TODAY_CLOSE.value]) *
            today_lossHold_positions_period_dataframe[
                TQZHoldPositionsPeriodKey.SELL_LOSS_HOLD_POSITION_PERIOD.value],
            5
        )
        today_lossHold_positions_period_dataframe = today_lossHold_positions_period_dataframe.loc[:, [TQZHoldPositionsPeriodKey.CONTRACT.value, TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value]]
        today_lossHold_positions_period_dataframe[
            TQZHoldPositionsPeriodKey.CONTRACT.value
        ] = today_lossHold_positions_period_dataframe.apply(
            lambda x: cls.__tqz_get_sym(x, TQZHoldPositionsPeriodKey.CONTRACT.value),
            axis=1
        )
        last_day_lossHold_positions_period_dataframe = today_lossHold_positions_period_dataframe

        return last_day_lossHold_positions_period_dataframe, today_lossHold_positions_period_dataframe

    @classmethod
    def __get_last_day_lossClose_hold_positions_period_dataframe(cls, current_account_trade_record_fold):
        """
        Get last_day_lossHold_positions_period_dataframe.
        """

        yesterday_hold_positions_dataframe = pandas.DataFrame()
        last_day_lossHold_positions_period_dataframe = pandas.DataFrame()
        for trade_record in os.listdir(path=current_account_trade_record_fold):
            trade_record_all_path = f'{current_account_trade_record_fold}/{trade_record}'

            # get today_open & today_hold & today_close & today_lossClose
            today_open_positions_dataframe, today_hold_positions_dataframe, today_close_positions_dataframe, today_lossClose_positions_dataframe = cls.__get_today_open_hold_close_lossClose_positions_dataframes(
                trade_record_all_path=trade_record_all_path
            )

            if len(yesterday_hold_positions_dataframe) is 0:  # yesterday_hold_positions_dataframe have no position

                yesterday_hold_positions_dataframe = today_hold_positions_dataframe
                yesterday_hold_positions_dataframe[TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value] = 0

            else:  # yesterday_hold_positions_dataframe have position

                yesterday_hold_positions_dataframe[TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value] += 1

                # calculate today lossClose period
                last_day_lossHold_positions_period_dataframe, today_lossHold_positions_period_dataframe = cls.__calculate_todayLossClose_hold_positions_period(
                    today_lossClose_positions_dataframe=today_lossClose_positions_dataframe,
                    yesterday_hold_positions_dataframe=yesterday_hold_positions_dataframe
                )

                # update yesterday hold positions dataframe
                yesterday_hold_positions_dataframe = cls.__update_lossClose_yesterday_hold_positions_dataframe(
                    today_open_positions_dataframe=today_open_positions_dataframe,
                    today_hold_positions_dataframe=today_hold_positions_dataframe,
                    today_close_positions_dataframe=today_close_positions_dataframe,
                    yesterday_hold_positions_dataframe=yesterday_hold_positions_dataframe
                )

        last_day_lossHold_positions_period_dataframe[
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ] = round(
            last_day_lossHold_positions_period_dataframe[
                TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
            ]
        )

        last_day_lossHold_positions_period_dataframe[
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ] = last_day_lossHold_positions_period_dataframe[
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ].astype(int)

        return last_day_lossHold_positions_period_dataframe


    @classmethod
    def __update_lossClose_yesterday_hold_positions_dataframe(cls, today_open_positions_dataframe, today_hold_positions_dataframe, today_close_positions_dataframe, yesterday_hold_positions_dataframe):
        """
        Update yesterday-hold-positions-dataframe.
        """

        yesterday_hold_positions_dataframe.set_index([
            TQZHoldPositionsPeriodKey.CONTRACT.value,
            TQZHoldPositionsPeriodKey.BUY_SELL.value
        ], inplace=True)
        yesterday_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value
        ] = yesterday_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOT.value
        ]
        del yesterday_hold_positions_dataframe[TQZHoldPositionsPeriodKey.LOT.value]

        today_hold_positions_dataframe.set_index([
            TQZHoldPositionsPeriodKey.CONTRACT.value,
            TQZHoldPositionsPeriodKey.BUY_SELL.value
        ], inplace=True)
        today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_HOLD.value
        ] = today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOT.value
        ]
        del today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOT.value
        ]

        today_open_positions_dataframe.set_index([
            TQZHoldPositionsPeriodKey.CONTRACT.value,
            TQZHoldPositionsPeriodKey.BUY_SELL.value
        ], inplace=True)
        today_close_positions_dataframe.set_index([
            TQZHoldPositionsPeriodKey.CONTRACT.value,
            TQZHoldPositionsPeriodKey.BUY_SELL.value
        ], inplace=True)

        today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
        ] = today_close_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOT.value
        ]
        today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_OPEN.value
        ] = today_open_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOT.value
        ]
        today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value
        ] = yesterday_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value
        ]
        today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOSS_HOLD_POSITION_PERIOD_YESTERDAY.value
        ] = yesterday_hold_positions_dataframe[
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ]
        today_hold_positions_dataframe.fillna(0, inplace=True)

        today_hold_positions_dataframe.loc[
            today_hold_positions_dataframe[
                TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
            ] >= today_hold_positions_dataframe[
                TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value
            ],
            TQZHoldPositionsPeriodKey.YESTERDAY_POSITION.value
        ] = 0
        today_hold_positions_dataframe.loc[
            today_hold_positions_dataframe[
                TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
            ] >= today_hold_positions_dataframe[
                TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value
            ],
            TQZHoldPositionsPeriodKey.TODAY_POSITION.value
        ] = today_hold_positions_dataframe[TQZHoldPositionsPeriodKey.TODAY_HOLD.value]
        today_hold_positions_dataframe.loc[
            today_hold_positions_dataframe[
                TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
            ] < today_hold_positions_dataframe[
                TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value
            ],
            TQZHoldPositionsPeriodKey.YESTERDAY_POSITION.value
        ] = today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value
        ] - today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
        ]
        today_hold_positions_dataframe.loc[
            today_hold_positions_dataframe[
                TQZHoldPositionsPeriodKey.TODAY_CLOSE.value
            ] < today_hold_positions_dataframe[
                TQZHoldPositionsPeriodKey.YESTERDAY_HOLD.value
            ],
            TQZHoldPositionsPeriodKey.TODAY_POSITION.value
        ] = today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_HOLD.value
        ] - today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.YESTERDAY_POSITION.value
        ]
        today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOSS_HOLD_POSITION_PERIOD_TODAY.value
        ] = round(
            (today_hold_positions_dataframe[TQZHoldPositionsPeriodKey.YESTERDAY_POSITION.value] / today_hold_positions_dataframe[TQZHoldPositionsPeriodKey.TODAY_HOLD.value]) * today_hold_positions_dataframe[TQZHoldPositionsPeriodKey.LOSS_HOLD_POSITION_PERIOD_YESTERDAY.value],
            5
        )
        today_hold_positions_dataframe.reset_index(inplace=True)

        today_hold_positions_format_dataframe = pandas.DataFrame()
        today_hold_positions_format_dataframe[
            TQZHoldPositionsPeriodKey.CONTRACT.value
        ] = today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.CONTRACT.value
        ]
        today_hold_positions_format_dataframe[
            TQZHoldPositionsPeriodKey.BUY_SELL.value
        ] = today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.BUY_SELL.value
        ]
        today_hold_positions_format_dataframe[
            TQZHoldPositionsPeriodKey.LOT.value
        ] = today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.TODAY_HOLD.value
        ]
        today_hold_positions_format_dataframe[
            TQZFunctionModuleType.LOSS_HOLD_POSITION_PERIOD.value
        ] = today_hold_positions_dataframe[
            TQZHoldPositionsPeriodKey.LOSS_HOLD_POSITION_PERIOD_TODAY.value
        ]

        yesterday_hold_positions_dataframe = today_hold_positions_format_dataframe

        return yesterday_hold_positions_dataframe


    @classmethod
    def __tqz_get_sym(cls, source_dataframe, column):
        return re.match(r"^[a-zA-Z]{1,3}", source_dataframe[column]).group()


if __name__ == '__main__':
    TQZLossCloseHoldPositionsPeriodApi.tqz_lossClose_hold_positions_period(account_names=["JHcy0125"])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值