From 8c6a4a1b09fa3d62585b2824a27de4b1a2a0d810 Mon Sep 17 00:00:00 2001 From: Andrew <39019063+manhinhang@users.noreply.github.com> Date: Sat, 13 Apr 2024 21:29:09 +0800 Subject: [PATCH] chore: upgrade depends version (#73) --- .github/workflows/build-test.yml | 31 +--- Dockerfile | 12 +- README.md | 6 +- ibc/config.ini | 280 ++++++++++++++++++++++--------- ibc/jts.ini | 25 --- src/bootstrap.py | 2 +- src/ib_account.py | 52 +++--- 7 files changed, 237 insertions(+), 171 deletions(-) delete mode 100644 ibc/jts.ini diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 7d360ed..56bdabe 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -14,9 +14,9 @@ jobs: env: IMAGE_NAME: ib-gateway-docker steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@master - name: Setup python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 - name: Install dependencies run: | python -m pip install --upgrade pip @@ -48,29 +48,4 @@ jobs: TRADE_MODE: paper IB_ACCOUNT: ${{ secrets.IB_ACCOUNT }} IB_PASSWORD: ${{ secrets.IB_PASSWORD }} - - - uses: 'google-github-actions/setup-gcloud@v1' - with: - version: '>= 363.0.0' - project_id: ${{ secrets.GCP_PROJECT_ID }} - service_account_key: ${{ secrets.GCP_SA_KEY }} - export_default_credentials: true - - name: Run google clound example - run: | - docker run \ - --env GCP_SECRET=True \ - --env GCP_SECRET_IB_ACCOUNT=$GCP_SECRET_IB_ACCOUNT \ - --env GCP_SECRET_IB_PASSWORD=$GCP_SECRET_IB_PASSWORD \ - --env GCP_SECRET_IB_TRADE_MODE=$GCP_SECRET_IB_TRADE_MODE \ - --env GCP_PROJECT_ID=$GCP_PROJECT_ID \ - -e GOOGLE_APPLICATION_CREDENTIALS=/tmp/keys/credentials.json \ - -v $GOOGLE_APPLICATION_CREDENTIALS:/tmp/keys/credentials.json:ro \ - -d \ - $IMAGE_NAME; - sleep 30; - if [ -z "$(docker ps -a -q)" ]; then exit 1; fi - env: - GCP_SECRET_IB_ACCOUNT: ${{ secrets.GCP_SECRET_IB_ACCOUNT }} - GCP_SECRET_IB_PASSWORD: ${{ secrets.GCP_SECRET_IB_PASSWORD }} - GCP_SECRET_IB_TRADE_MODE: ${{ secrets.GCP_SECRET_IB_TRADE_MODE }} - GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + diff --git a/Dockerfile b/Dockerfile index a5d41e8..1567adb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ FROM python:3.11-slim -ARG IBC_VER="3.16.2" -ARG IB_INSYNC_VER="0.9.85" +# IBC Version : https://github.com/IbcAlpha/IBC/releases +ARG IBC_VER="3.18.0" +# ib_insync : https://pypi.org/project/ib-insync/#history +ARG IB_INSYNC_VER="0.9.86" # install dependencies RUN apt-get update \ @@ -18,7 +20,7 @@ RUN apt-get update \ procps \ xterm RUN apt install -y openjdk-17-jre -RUN pip install ib_insync==$IB_INSYNC_VER google-cloud-secret-manager==2.11.1 +RUN pip install ib_insync==$IB_INSYNC_VER # set environment variables ENV TWS_INSTALL_LOG=/root/Jts/tws_install.log \ @@ -38,7 +40,7 @@ RUN wget -q -O /tmp/ibgw.sh https://download2.interactivebrokers.com/installers/ RUN chmod +x /tmp/ibgw.sh # download IBC -RUN wget -q -O /tmp/IBC.zip https://github.com/IbcAlpha/IBC/releases/download/$IBC_VER/IBCLinux-$IBC_VER.zip +RUN wget -q -O /tmp/IBC.zip https://github.com/IbcAlpha/IBC/releases/download/$IBC_VER-Update.1/IBCLinux-$IBC_VER.zip RUN unzip /tmp/IBC.zip -d ${ibcPath} RUN chmod +x ${ibcPath}/*.sh ${ibcPath}/*/*.sh @@ -46,7 +48,6 @@ RUN chmod +x ${ibcPath}/*.sh ${ibcPath}/*/*.sh RUN touch $TWS_INSTALL_LOG COPY install_ibgw.exp /tmp/install_ibgw.exp RUN chmod +x /tmp/install_ibgw.exp -RUN cat /tmp/ibgw.sh RUN /tmp/install_ibgw.exp # remove downloaded files @@ -54,7 +55,6 @@ RUN rm /tmp/ibgw.sh /tmp/IBC.zip # copy IBC/Jts configs COPY ibc/config.ini ${ibcIni} -COPY ibc/jts.ini ${twsPath}/jts.ini # copy cmd script WORKDIR /root diff --git a/README.md b/README.md index 651726c..5810ff1 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ It's just pure `IB Gateway` and don't include any VNC service (for security reas This docker image just installed: -- [IB Gateway](https://www.interactivebrokers.com/en/index.php?f=16457) (10.19.1) +- [IB Gateway](https://www.interactivebrokers.com/en/index.php?f=16457) (10.19.2) -- [IBC](https://github.com/IbcAlpha/IBC) (3.16.2) +- [IBC](https://github.com/IbcAlpha/IBC) (3.18.0) -- [ib_insync](https://github.com/erdewit/ib_insync) (0.9.71) +- [ib_insync](https://github.com/erdewit/ib_insync) (0.9.86) - [google-cloud-secret-manager](https://github.com/googleapis/python-secret-manager) (2.11.1) diff --git a/ibc/config.ini b/ibc/config.ini index d593f1d..dd14747 100644 --- a/ibc/config.ini +++ b/ibc/config.ini @@ -142,7 +142,7 @@ ReloginAfterSecondFactorAuthenticationTimeout=no # after the user acknowledges the second factor authentication # alert at the IBKR Mobile app. If login has not completed after # this time, IBC terminates. -# The default value is 40. +# The default value is 60. SecondFactorAuthenticationExitInterval= @@ -166,7 +166,7 @@ SecondFactorAuthenticationTimeout=180 # app for second factor authentication, and you fail to complete the # process before the time limit imposed by IBKR, you can use this # setting to tell IBC to exit: arrangements can then be made to -# automatically restart IBC in order to initiate# the login sequence +# automatically restart IBC in order to initiate the login sequence # afresh. Otherwise, manual intervention at TWS's # Second Factor Authentication dialog is needed to complete the # login. @@ -183,12 +183,13 @@ ExitAfterSecondFactorAuthenticationTimeout=no # Trading Mode # ------------ # -# TWS 955 introduced a new Trading Mode combo box on its login -# dialog. This indicates whether the live account or the paper -# trading account corresponding to the supplied credentials is -# to be used. The allowed values are 'live' (the default) and -# 'paper'. For earlier versions of TWS this setting has no -# effect. +# This indicates whether the live account or the paper trading +# account corresponding to the supplied credentials is to be used. +# The allowed values are 'live' (the default) and 'paper'. +# +# If this is set to 'live', then the credentials for the live +# account must be supplied. If it is set to 'paper', then either +# the live or the paper-trading credentials may be supplied. TradingMode= @@ -253,7 +254,15 @@ LoginDialogDisplayTimeout=60 # but they are acceptable. # # The default is the current working directory when IBC is -# started. +# started, unless the TWS_SETTINGS_PATH setting in the relevant +# start script is set. +# +# If both this setting and TWS_SETTINGS_PATH are set, then this +# setting takes priority. Note that if they have different values, +# auto-restart will not work. +# +# NB: this setting is now DEPRECATED. You should use the +# TWS_SETTINGS_PATH setting in the relevant start script. IbDir= @@ -320,15 +329,32 @@ ExistingSessionDetectedAction=primary # Override TWS API Port Number # ---------------------------- # -# If OverrideTwsApiPort is set to an integer, IBC changes the -# 'Socket port' in TWS's API configuration to that number shortly -# after startup. Leaving the setting blank will make no change to -# the current setting. This setting is only intended for use in -# certain specialized situations where the port number needs to +# If OverrideTwsApiPort is set to an integer, IBC changes the +# 'Socket port' in TWS's API configuration to that number shortly +# after startup (but note that for the FIX Gateway, this setting is +# actually stored in jts.ini rather than the Gateway's settings +# file). Leaving the setting blank will make no change to +# the current setting. This setting is only intended for use in +# certain specialized situations where the port number needs to +# be set dynamically at run-time, and for the FIX Gateway: most +# non-FIX users will never need it, so don't use it unless you know +# you need it. + +OverrideTwsApiPort=4001 + + +# Override TWS Master Client ID +# ----------------------------- +# +# If OverrideTwsMasterClientID is set to an integer, IBC changes the +# 'Master Client ID' value in TWS's API configuration to that +# value shortly after startup. Leaving the setting blank will make +# no change to the current setting. This setting is only intended +# for use in certain specialized situations where the value needs to # be set dynamically at run-time: most users will never need it, # so don't use it unless you know you need it. -OverrideTwsApiPort=4001 +OverrideTwsMasterClientID= # Read-only Login @@ -367,6 +393,43 @@ ReadOnlyLogin=no ReadOnlyApi=no +# API Precautions +# --------------- +# +# These settings relate to the corresponding 'Precautions' checkboxes in the +# API section of the Global Configuration dialog. +# +# For all of these, the accepted values are: +# - 'yes' sets the checkbox +# - 'no' clears the checkbox +# - if not set, the existing TWS/Gateway configuration is unchanged +# +# NB: thess settings are really only supplied for the benefit of new TWS +# or Gateway instances that are being automatically installed and +# started without user intervention, or where user settings are not preserved +# between sessions (eg some Docker containers). Where a user is involved, they +# should use the Global Configuration to set the relevant checkboxes and not +# provide values for these settings. + +BypassOrderPrecautions= + +BypassBondWarning= + +BypassNegativeYieldToWorstConfirmation= + +BypassCalledBondWarning= + +BypassSameActionPairTradeWarning= + +BypassPriceBasedVolatilityRiskWarning= + +BypassUSStocksMarketDataInSharesWarning= + +BypassRedirectOrderWarning= + +BypassNoOverfillProtectionPrecaution= + + # Market data size for US stocks - lots or shares # ----------------------------------------------- # @@ -419,89 +482,145 @@ AcceptBidAskLastSizeDisplayUpdateNotification= SendMarketDataInLotsForUSstocks= - -# ============================================================================= -# 4. TWS Auto-Logoff -# ============================================================================= +# Trusted API Client IPs +# ---------------------- # -# TWS and Gateway log off and close down automatically every day. The normal -# way to configure the time at which this happens is via the Configuration -# dialog. Once this time has been configured in this way, the setting persists -# until the user changes it again. +# NB: THIS SETTING IS ONLY RELEVANT FOR THE GATEWAY, AND ONLY WHEN FIX=yes. +# In all other cases it is ignored. # -# However, there are situations where there is no user available to do this -# configuration, or where there is no persistent storage (for example some -# Docker images). In such cases, the auto-logoff time can be set whenever -# IBC starts with the setting below. +# This is a list of IP addresses separated by commas. API clients with IP +# addresses in this list are able to connect to the API without Gateway +# generating the 'Incoming connection' popup. # -# The value, if specified, must be a time in HH:MM AM/PM format, for example -# 08:00 AM or 10:00 PM. Note that there must be a single space between the -# two parts of this value. +# Note that 127.0.0.1 is always permitted to connect, so do not include it +# in this setting. + +TrustedTwsApiClientIPs= + + +# Reset Order ID Sequence +# ----------------------- # -# If no value is specified, the currently configured setting will apply. +# The setting resets the order id sequence for orders submitted via the API, so +# that the next invocation of the `NextValidId` API callback will return the +# value 1. The reset occurs when TWS starts. # -# Note that for a normal TWS/Gateway installation with persistent storage -# (for example on a desktop computer) the value will be persisted as if the -# user had set it via the configuration dialog. +# Note that order ids are reset for all API clients, except those that have +# outstanding (ie incomplete) orders: their order id sequence carries on as +# before. +# +# Valid values are 'yes', 'true', 'false' and 'no'. The default is 'no'. -AutoLogoffTime= +ResetOrderIdsAtStart= -# DEPRECATED SETTING -# ------------------ +# This setting specifies IBC's action when TWS displays the dialog asking for +# confirmation of a request to reset the API order id sequence. # -# IbAutoClosedown - THIS SETTING WILL BE REMOVED IN A FUTURE -# RELEASE +# Note that the Gateway never displays this dialog, so this setting is ignored +# for a Gateway session. # -# IMPORTANT NOTE: Starting with TWS 974, this setting no longer -# works properly, because IB have changed the way TWS handles its -# autologoff mechanism. +# Valid values consist of two strings separated by a solidus '/'. The first +# value specifies the action to take when the order id reset request resulted +# from setting ResetOrderIdsAtStart=yes. The second specifies the action to +# take when the order id reset request is a result of the user clicking the +# 'Reset API order ID sequence' button in the API configuration. Each value +# must be one of the following: # -# You should now configure the TWS autologoff time to something -# convenient for you, and restart IBC each day. +# 'confirm' +# order ids will be reset # -# Alternatively, discontinue use of IBC and use the auto-relogin -# mechanism within TWS 974 and later versions (note that the -# auto-relogin mechanism provided by IB is not available if you -# use IBC). - -# Set to yes or no (lower case). +# 'reject' +# order ids will not be reset # -# yes means allow TWS to shut down automatically at its -# specified shutdown time, which is set via the TWS -# configuration menu. +# 'ignore' +# IBC will ignore the dialog. The user must take action. # -# no means TWS never shuts down automatically. +# The default setting is ignore/ignore + +# Examples: # -# NB: IB recommends that you do not keep TWS running -# continuously. If you set this setting to 'no', you may -# experience incorrect TWS operation. +# 'confirm/reject' - confirm order id reset only if ResetOrderIdsAtStart=yes +# and reject any user-initiated requests # -# NB: the default for this setting is 'no'. Since this will -# only work properly with TWS versions earlier than 974, you -# should explicitly set this to 'yes' for version 974 and later. +# 'ignore/confirm' - user must decide what to do if ResetOrderIdsAtStart=yes +# and confirm user-initiated requests +# +# 'reject/ignore' - reject order id reset if ResetOrderIdsAtStart=yes but +# allow user to handle user-initiated requests -IbAutoClosedown=yes +ConfirmOrderIdReset= # ============================================================================= -# 5. TWS Tidy Closedown Time - DEPRECATED +# 4. TWS Auto-Logoff and Auto-Restart # ============================================================================= # -# DEPRECATED SETTING -# ------------------ +# TWS and Gateway insist on being restarted every day. Two alternative +# automatic options are offered: # -# ClosedownAt - THIS SETTING WILL BE REMOVED IN A FUTURE -# RELEASE +# - Auto-Logoff: at a specified time, TWS shuts down tidily, without +# restarting. +# +# - Auto-Restart: at a specified time, TWS shuts down and then restarts +# without the user having to re-autheticate. +# +# The normal way to configure the time at which this happens is via the Lock +# and Exit section of the Configuration dialog. Once this time has been +# configured in this way, the setting persists until the user changes it again. +# +# However, there are situations where there is no user available to do this +# configuration, or where there is no persistent storage (for example some +# Docker images). In such cases, the auto-restart or auto-logoff time can be +# set whenever IBC starts with the settings below. # -# NB: starting with TWS 974 this is no longer a useful option -# because both TWS and Gateway now have the same auto-logoff -# mechanism, and IBC can no longer avoid this. +# The value, if specified, must be a time in HH:MM AM/PM format, for example +# 08:00 AM or 10:00 PM. Note that there must be a single space between the +# two parts of this value; also that midnight is "12:00 AM" and midday is +# "12:00 PM". +# +# If no value is specified for either setting, the currently configured +# settings will apply. If a value is supplied for one setting, the other +# setting is cleared. If values are supplied for both settings, only the +# auto-restart time is set, and the auto-logoff time is cleared. +# +# Note that for a normal TWS/Gateway installation with persistent storage +# (for example on a desktop computer) the value will be persisted as if the +# user had set it via the configuration dialog. +# +# If you choose to auto-restart, you should take note of the considerations +# described at the link below. Note that where this information mentions +# 'manual authentication', restarting IBC will do the job (IBKR does not +# recognise the existence of IBC in its docuemntation). # -# Note that giving this setting a value does not change TWS's -# auto-logoff in any way: any setting will be additional to the -# TWS auto-logoff. +# https://www.interactivebrokers.com/en/software/tws/twsguide.htm#usersguidebook/configuretws/auto_restart_info.htm +# +# If you use the "RESTART" command via the IBC command server, and IBC is +# running any version of the Gateway (or a version of TWS earlier than 1018), +# note that this will set the Auto-Restart time in Gateway/TWS's configuration +# dialog to the time at which the restart actually happens (which may be up to +# a minute after the RESTART command is issued). To prevent future auto- +# restarts at this time, you must make sure you have set AutoLogoffTime or +# AutoRestartTime to your desired value before running IBC. NB: this does not +# apply to TWS from version 1018 onwards. + +AutoLogoffTime= + +AutoRestartTime= + + +# ============================================================================= +# 5. TWS Tidy Closedown Time +# ============================================================================= +# +# Specifies a time at which TWS will close down tidily, with no restart. +# +# There is little reason to use this setting. It is similar to AutoLogoffTime, +# but can include a day-of-the-week, whereas AutoLogoffTime and AutoRestartTime +# apply every day. So for example you could use ClosedownAt in conjunction with +# AutoRestartTime to shut down TWS on Friday evenings after the markets +# close, without it running on Saturday as well. # # To tell IBC to tidily close TWS at a specified time every # day, set this value to , for example: @@ -748,10 +867,10 @@ SuppressInfoMessages=yes # The LogStructureScope setting indicates which windows are # eligible for structure logging: # -# - if set to 'known', only windows that IBC recognizes -# are eligible - these are windows that IBC has some -# interest in monitoring, usually to take some action -# on the user's behalf; +# - (default value) if set to 'known', only windows that +# IBC recognizes are eligible - these are windows that +# IBC has some interest in monitoring, usually to take +# some action on the user's behalf; # # - if set to 'unknown', only windows that IBC does not # recognize are eligible. Most windows displayed by @@ -764,7 +883,6 @@ SuppressInfoMessages=yes # - if set to 'all', then every window displayed by TWS # is eligible. # -# The default value is 'known'. LogStructureScope=known @@ -785,10 +903,9 @@ LogStructureScope=known # - if set to 'activate', the structure is logged every # time an eligible window is made active; # -# - if set to 'never' or 'no' or 'false', structure -# information is never logged. +# - (default value) if set to 'never' or 'no' or 'false', +# structure information is never logged. # -# The default value is 'never'. LogStructureWhen=never @@ -805,6 +922,5 @@ LogStructureWhen=never # settings are ignored. The default is that the values # of LogStructureScope and LogStructureWhen are honoured. -LogComponents=never - +#LogComponents= diff --git a/ibc/jts.ini b/ibc/jts.ini deleted file mode 100644 index 1ad5b1c..0000000 --- a/ibc/jts.ini +++ /dev/null @@ -1,25 +0,0 @@ -[IBGateway] -WriteDebug=false -TrustedIPs=127.0.0.1 -MainWindow.Height=550 -RemoteHostOrderRouting=zdc1.ibllc.com -RemotePortOrderRouting=4000 -LocalServerPort=4000 -ApiOnly=true -MainWindow.Width=700 - -[Logon] -useRemoteSettings=false -TimeZone=Europe/Zurich -colorPalletName=dark -Steps=8 -Locale=en -SupportsSSL=gdc1.ibllc.com:4000,true,20191114,false -UseSSL=true -os_titlebar=false -s3store=true - -[Communication] -SettingsDir=/root/Jts -Peer=gdc1.ibllc.com:4001 -Region=ch diff --git a/src/bootstrap.py b/src/bootstrap.py index 44008a2..a03ce2b 100644 --- a/src/bootstrap.py +++ b/src/bootstrap.py @@ -9,7 +9,7 @@ logging.info('start ib gateway...') logging.info('---ib gateway info---') twsPath = os.environ['twsPath'] - logging.info('twsPath', twsPath) + logging.info(f'twsPath: {twsPath}') gatewayRootPath = "{}/ibgateway".format(twsPath) ib_gateway_version = int(os.listdir(gatewayRootPath)[0]) gatewayPath = "{}/{}".format(gatewayRootPath, ib_gateway_version) diff --git a/src/ib_account.py b/src/ib_account.py index 9cc08f2..c77baeb 100644 --- a/src/ib_account.py +++ b/src/ib_account.py @@ -1,44 +1,44 @@ import os -from distutils.util import strtobool -from google.cloud import secretmanager +# from distutils.util import strtobool +# from google.cloud import secretmanager class IBAccount(object): # Create the Secret Manager client. __client = None - @classmethod - def retrieve_secret(cls, secret_id): - if not cls.__client: - cls.__client = secretmanager.SecretManagerServiceClient() - gcp_project_id = os.environ['GCP_PROJECT_ID'] - name = cls.__client.secret_version_path(gcp_project_id, secret_id, 'latest') - response = cls.__client.access_secret_version(name=name) - payload = response.payload.data.decode('UTF-8') - return payload + # @classmethod + # def retrieve_secret(cls, secret_id): + # if not cls.__client: + # cls.__client = secretmanager.SecretManagerServiceClient() + # gcp_project_id = os.environ['GCP_PROJECT_ID'] + # name = cls.__client.secret_version_path(gcp_project_id, secret_id, 'latest') + # response = cls.__client.access_secret_version(name=name) + # payload = response.payload.data.decode('UTF-8') + # return payload - @staticmethod - def isEnabledGCPSecret(): - try: - return bool(strtobool(os.environ['GCP_SECRET'])) - except ValueError: - return False + # @staticmethod + # def isEnabledGCPSecret(): + # try: + # return bool(strtobool(os.environ['GCP_SECRET'])) + # except ValueError: + # return False @classmethod def account(cls): - if not cls.isEnabledGCPSecret(): - return os.environ['IB_ACCOUNT'] - return cls.retrieve_secret(os.environ['GCP_SECRET_IB_ACCOUNT']) + # if not cls.isEnabledGCPSecret(): + return os.environ['IB_ACCOUNT'] + # return cls.retrieve_secret(os.environ['GCP_SECRET_IB_ACCOUNT']) @classmethod def password(cls): - if not cls.isEnabledGCPSecret(): - return os.environ['IB_PASSWORD'] - return cls.retrieve_secret(os.environ['GCP_SECRET_IB_PASSWORD']) + # if not cls.isEnabledGCPSecret(): + return os.environ['IB_PASSWORD'] + # return cls.retrieve_secret(os.environ['GCP_SECRET_IB_PASSWORD']) @classmethod def trade_mode(cls): - if not cls.isEnabledGCPSecret(): - return os.environ['TRADE_MODE'] - return cls.retrieve_secret(os.environ['GCP_SECRET_IB_TRADE_MODE']) + # if not cls.isEnabledGCPSecret(): + return os.environ['TRADE_MODE'] + # return cls.retrieve_secret(os.environ['GCP_SECRET_IB_TRADE_MODE']) \ No newline at end of file