量化交易之vnpy篇 - 重构多账户登录模块(gateway_accounts_login.py)

该代码实现了一个自动化登录期货交易接口的功能,使用了vn.py框架。它检查交易时段并根据设定的账户信息启动子进程进行登录。同时,它还包含了账户数据的管理和更新,确保只有在交易时间内账户保持登录状态。代码支持CtpGateway、EpiGateway、jeesGateway和RohonGateway等期货接口的多账户登录。
摘要由CSDN通过智能技术生成
import multiprocessing
import sys
import os
from time import sleep
from datetime import datetime, time
from logging import INFO
from typing import Type

from vnpy.event import EventEngine
from vnpy.trader.setting import SETTINGS
from vnpy.trader.engine import MainEngine

from vnpy.app.position_manager import PositionManagerApp
from vnpy.app.cta_strategy.base import EVENT_CTA_LOG

from vnpy.trader.gateway import BaseGateway
# from vnpy.gateway.ctp import CtpGateway

from vnpy.app.position_manager.tools.position_operator.position_operator import TQZJsonOperator
from vnpy.app.position_manager.tools.file_path_operator.file_path_operator import TQZFilePathOperator

from vnpy.trader.constant import TQZGatewaySettingKey


SETTINGS["log.active"] = True
SETTINGS["log.level"] = INFO
SETTINGS["log.console"] = True


class TQZGatewayLogin:
    # Chinese futures market trading period (day/night)
    __day_start_time = time(8, 45)
    __day_end_time = time(19, 45)

    __night_start_time = time(20, 45)
    __night_end_time = time(2, 35)

    __accounts_data_fold_path = TQZFilePathOperator.grandfather_path(
            source_path=TQZFilePathOperator.current_file_father_path(
                file=__file__
            )
        ) + f"/.vntrader/accounts_data"

    __accounts_data_jsonfile_path = __accounts_data_fold_path + "/accounts_data.json"

    def __init__(self, gateway: Type[BaseGateway]):

        self.gateway = gateway
        self.gateway_name = gateway(event_engine=None).gateway_name


    def tqz_login_accounts(self):
        """
        Logining all accounts in the same gateway
        """

        gateway_settings = self.__get_gateway_settings(gateway_name_lower=self.gateway_name.lower())

        ACCOUNT_NAME = TQZGatewaySettingKey.ACCOUNT_NAME.value

        accounts_child_process: {str: None} = {}
        for gateway_setting in gateway_settings:
            accounts_child_process[gateway_setting[ACCOUNT_NAME]] = None

        while True:
            trading = self.__check_trading_period()

            for gateway_setting in gateway_settings:
                # Start child process in trading period
                if trading and accounts_child_process[gateway_setting[ACCOUNT_NAME]] is None:
                    accounts_child_process[gateway_setting[ACCOUNT_NAME]] = multiprocessing.Process(
                        target=self._run_account,
                        args=(gateway_setting, )
                    )
                    accounts_child_process[gateway_setting[ACCOUNT_NAME]].start()

                if not trading and accounts_child_process[gateway_setting[ACCOUNT_NAME]] is not None:
                    if not accounts_child_process[gateway_setting[ACCOUNT_NAME]].is_alive():
                        accounts_child_process[gateway_setting[ACCOUNT_NAME]] = None

                sleep(5)


    def _run_account(self, gateway_setting):
        """
        Running all accounts in the same gateway.
        """

        SETTINGS["log.file"] = True

        event_engine = EventEngine()
        main_engine = MainEngine(event_engine)
        main_engine.add_gateway(gateway_class=self.gateway)

        positionManager_engine = main_engine.add_app(PositionManagerApp)

        log_engine = main_engine.get_engine("log")
        event_engine.register(EVENT_CTA_LOG, log_engine.process_log_event)

        main_engine.connect(gateway_setting, gateway_name=self.gateway_name)
        main_engine.write_log("连接" + self.gateway_name + "接口")

        sleep(60)
        positionManager_engine.init_engine()

        while True:
            sleep(10)
            trading = self.__check_trading_period()
            if not trading:
                main_engine.close()
                sys.exit(0)


    # -- private part ---
    def __check_trading_period(self):
        """ """
        current_time = datetime.now().time()

        trading = False

        if (
            (self.__day_start_time <= current_time <= self.__day_end_time)
            or (current_time >= self.__night_start_time)
            or (current_time <= self.__night_end_time)
        ):
            trading = True

        return trading


    @classmethod
    def __get_gateway_settings(cls, gateway_name_lower: str):

        cls.__tqz_update_accounts_data_jsonfile()

        target_file_path = cls.__accounts_data_fold_path + f"/{gateway_name_lower.lower()}_settings.json"
        if os.path.exists(path=target_file_path):
            gateway_settings = TQZJsonOperator.tqz_load_jsonfile(jsonfile=target_file_path)
        else:
            gateway_settings = {}

        return gateway_settings

    @classmethod
    def __tqz_update_accounts_data_jsonfile(cls):
        if not os.path.exists(path=cls.__accounts_data_fold_path):
            os.makedirs(cls.__accounts_data_fold_path)
            TQZJsonOperator.tqz_write_jsonfile(content={}, target_jsonfile=cls.__accounts_data_jsonfile_path)

        # separate gateway_settings.json and others...
        all_gateway_settings_content_list = []
        current_accounts_data = {}
        for base_path, folder_list, file_list in os.walk(cls.__accounts_data_fold_path):
            for file_name in file_list:
                full_path = cls.__accounts_data_fold_path + '/' + file_name

                if file_name.split(".")[0].endswith("settings"):
                    all_gateway_settings_content_list.append(
                        TQZJsonOperator.tqz_load_jsonfile(jsonfile=full_path)
                    )
                else:
                    if os.path.exists(path=cls.__accounts_data_jsonfile_path):
                        current_accounts_data = TQZJsonOperator.tqz_load_jsonfile(jsonfile=cls.__accounts_data_jsonfile_path)

        current_source_accounts_names = []
        for gateway_settings in all_gateway_settings_content_list:
            for gateway_setting in gateway_settings:
                current_source_accounts_names.append(gateway_setting[TQZGatewaySettingKey.ACCOUNT_NAME.value])

        should_remove_account_list = []
        for current_account in current_accounts_data.keys():
            if current_account not in current_source_accounts_names:
                should_remove_account_list.append(current_account)

        if len(should_remove_account_list) is 0:
            return
        else:
            for should_remove_acccount in should_remove_account_list:
                del current_accounts_data[should_remove_acccount]
            TQZJsonOperator.tqz_write_jsonfile(content=current_accounts_data, target_jsonfile=cls.__accounts_data_jsonfile_path)


if __name__ == "__main__":
    # TQZGatewayLogin(gateway=CtpGateway).tqz_login_accounts()
    pass
# ctp_gateway 的 多账户登录
from vnpy.gateway.ctp import CtpGateway

from vnpy.trader.gateway_accounts_login import TQZGatewayLogin

if __name__ == '__main__':
    TQZGatewayLogin(gateway=CtpGateway).tqz_login_accounts()
# epi_gateway 的 多账户登录
from vnpy.gateway.epi import EpiGateway

from vnpy.trader.gateway_accounts_login import TQZGatewayLogin

if __name__ == '__main__':
    TQZGatewayLogin(gateway=EpiGateway).tqz_login_accounts()
# jees_gateway 的 多账户登录
from vnpy.gateway.jees import jeesGateway

from vnpy.trader.gateway_accounts_login import TQZGatewayLogin

if __name__ == '__main__':
    TQZGatewayLogin(gateway=jeesGateway).tqz_login_accounts()
# rohon_gateway 的 多账户登录
from vnpy.gateway.rohon import RohonGateway

from vnpy.trader.gateway_accounts_login import TQZGatewayLogin

if __name__ == '__main__':
    TQZGatewayLogin(gateway=RohonGateway).tqz_login_accounts()

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
优化sql:SELECT we.organization_id ,we.wip_entity_id ,case when wl.line_id is null then we.wip_entity_name else '' end wip_entity_name ,we.primary_item_id ,mtt.transaction_type_name ,mmt.transaction_date ,bd.department_code ,mmt.inventory_item_id ,mmt.subinventory_code ,mta.reference_account ,br.resource_code ,lu2.meaning as line_type_name ,mta.base_transaction_value ,mta.cost_element_id ,flv.meaning as cost_element ,wdj.class_code job_type_code ,ml.meaning job_type_name FROM (select * from gerp.mtl_material_transactions where substr(transaction_date,1,7) >= '2023-06' and transaction_source_type_id = 5) mmt inner join gerp.wip_entities we on mmt.organization_id = we.organization_id inner join gerp.mtl_transaction_accounts mta on mta.transaction_source_id = we.wip_entity_id and mta.transaction_id = mmt.transaction_id and mta.transaction_source_type_id = 5 inner join gerp.mtl_transaction_types mtt on mtt.transaction_type_id = mmt.transaction_type_id inner join mfg_lookups lu2 on lu2.lookup_code = mta.accounting_line_type and lu2.lookup_type = 'CST_ACCOUNTING_LINE_TYPE' inner join gerp.mtl_system_items_b msi on msi.inventory_item_id = mmt.inventory_item_id and msi.organization_id = mta.organization_id left join gerp.bom_departments bd on bd.department_id = mmt.department_id left join gerp.bom_resources br on br.resource_id = mta.resource_id left join gerp.wip_lines wl on wl.line_id = mmt.repetitive_line_id left join gerp.wip_discrete_jobs wdj on wdj.wip_entity_id = mta.transaction_source_id left join gerp.fnd_lookup_values_vl flv on cast(mta.cost_element_id as string) = flv.lookup_code and flv.lookup_type = 'CST_COST_CODE_TYPE' left join mfg_lookups ml on ml.lookup_code = wdj.job_type and ml.lookup_type = 'WIP_DISCRETE_JOB' 。其中mmt,we,mta,msi,wdj数据量很大
最新发布
06-10
针对这个SQL语句,可以优化的地方有: 1. 使用JOIN语句时,可以根据数据量大小,将数据量大的表放在后面,这样可以避免在连接时出现性能问题。 2. 使用子查询时,可以在子查询中添加条件筛选,减少返回的数据量。 3. 可以对查询中的日期条件进行优化,例如使用日期范围查询时,可以使用BETWEEN关键字代替大于等于和小于等于的运算符。 4. 可以对大表进行分区或分片,以加快查询速度。 5. 可以对JOIN语句中的字段添加索引,以提高查询效率。 下面是对原SQL语句的优化: ``` SELECT we.organization_id, we.wip_entity_id, CASE WHEN wl.line_id is null THEN we.wip_entity_name ELSE '' END wip_entity_name, we.primary_item_id, mtt.transaction_type_name, mmt.transaction_date, bd.department_code, mmt.inventory_item_id, mmt.subinventory_code, mta.reference_account, br.resource_code, lu2.meaning as line_type_name, mta.base_transaction_value, mta.cost_element_id, flv.meaning as cost_element, wdj.class_code job_type_code, ml.meaning job_type_name FROM gerp.wip_entities we INNER JOIN ( SELECT * FROM gerp.mtl_material_transactions WHERE transaction_date BETWEEN '2023-06-01' AND '2023-06-30' AND transaction_source_type_id = 5 ) mmt ON mmt.organization_id = we.organization_id INNER JOIN gerp.mtl_transaction_accounts mta ON mta.transaction_source_id = we.wip_entity_id AND mta.transaction_id = mmt.transaction_id AND mta.transaction_source_type_id = 5 INNER JOIN gerp.mtl_transaction_types mtt ON mtt.transaction_type_id = mmt.transaction_type_id INNER JOIN mfg_lookups lu2 ON lu2.lookup_code = mta.accounting_line_type AND lu2.lookup_type = 'CST_ACCOUNTING_LINE_TYPE' INNER JOIN gerp.mtl_system_items_b msi ON msi.inventory_item_id = mmt.inventory_item_id AND msi.organization_id = mta.organization_id LEFT JOIN gerp.bom_departments bd ON bd.department_id = mmt.department_id LEFT JOIN gerp.bom_resources br ON br.resource_id = mta.resource_id LEFT JOIN gerp.wip_lines wl ON wl.line_id = mmt.repetitive_line_id LEFT JOIN gerp.wip_discrete_jobs wdj ON wdj.wip_entity_id = mta.transaction_source_id LEFT JOIN gerp.fnd_lookup_values_vl flv ON cast(mta.cost_element_id as string) = flv.lookup_code AND flv.lookup_type = 'CST_COST_CODE_TYPE' LEFT JOIN mfg_lookups ml ON ml.lookup_code = wdj.job_type AND ml.lookup_type = 'WIP_DISCRETE_JOB'; ``` 在优化后的SQL语句中,将子查询中的日期范围查询放在了WHERE语句中,将数据量较大的表放在了后面,左连接的表也放在了后面。同时,可以根据具体情况对需要添加索引的字段进行索引优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值