forked from QuantConnect/Lean
-
Notifications
You must be signed in to change notification settings - Fork 0
/
run_docker.sh
executable file
·164 lines (143 loc) · 5.49 KB
/
run_docker.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/env bash
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# allow script to be called from anywhere
cd "$(dirname "$0")/" || exit
DEFAULT_IMAGE=quantconnect/lean:latest
DEFAULT_DATA_DIR=./Data
DEFAULT_RESULTS_DIR=./Results
DEFAULT_CONFIG=./Launcher/config.json
DEFAULT_PYTHON_DIR=./Algorithm.Python/
CSHARP_DLL=./Launcher/bin/Debug/QuantConnect.Algorithm.CSharp.dll
CSHARP_PDB=./Launcher/bin/Debug/QuantConnect.Algorithm.CSharp.pdb
CONTAINER_NAME=LeanEngine
yes_or_no() {
while true; do
read -p "$* [y/n]: " yn
case $yn in
[Yy]*) return 0 ;;
[Nn]*)
echo "Aborted"
return 1
;;
esac
done
}
# Realpath polyfill, notably absent macOS and some debian distros
absolute_path() {
echo "$(cd "$(dirname "${1}")" && pwd)/$(basename "${1}")"
}
# If arg is a file process the key values
if [ -f "$1" ]; then
IFS="="
while read -r key value; do
eval "$key='$value'"
done <"$1"
# If there are in line args, process them
elif [ -n "$*" ]; then
for arg in "$@"; do
eval "$arg"
done
# Else query user for settings
else
read -p "Docker image [default: $DEFAULT_IMAGE]: " IMAGE
read -p "Path to Lean config.json [default: $DEFAULT_CONFIG]: " CONFIG_FILE
read -p "Path to Data directory [default: $DEFAULT_DATA_DIR]: " DATA_DIR
read -p "Path to Results directory [default: $DEFAULT_RESULTS_DIR]: " RESULTS_DIR
read -p "Path to Python directory [default: $DEFAULT_PYTHON_DIR]: " PYTHON_DIR
read -p "Would you like to debug C#? (Requires mono debugger attachment) [default: N]: " DEBUGGING
read -p "Would you like to update the Docker Image? [default: Y]: " UPDATE
fi
# Have to reset IFS for cfg files to work properly
IFS=" "
# Fall back to defaults on empty input without
CONFIG_FILE=${CONFIG_FILE:-$DEFAULT_CONFIG}
DATA_DIR=${DATA_DIR:-$DEFAULT_DATA_DIR}
RESULTS_DIR=${RESULTS_DIR:-$DEFAULT_RESULTS_DIR}
IMAGE=${IMAGE:-$DEFAULT_IMAGE}
PYTHON_DIR=${PYTHON_DIR:-$DEFAULT_PYTHON_DIR}
UPDATE=${UPDATE:-Y}
# Convert to absolute paths
CONFIG_FILE=$(absolute_path "${CONFIG_FILE}")
PYTHON_DIR=$(absolute_path "${PYTHON_DIR}")
DATA_DIR=$(absolute_path "${DATA_DIR}")
RESULTS_DIR=$(absolute_path "${RESULTS_DIR}")
CSHARP_DLL=$(absolute_path "${CSHARP_DLL}")
CSHARP_PDB=$(absolute_path "${CSHARP_PDB}")
if [ ! -f "$CONFIG_FILE" ]; then
echo "Lean config file $CONFIG_FILE does not exist"
exit 1
fi
if [ ! -d "$DATA_DIR" ]; then
echo "Data directory $DATA_DIR does not exist"
exit 1
fi
if [ ! -d "$RESULTS_DIR" ]; then
echo "Results directory $RESULTS_DIR does not exist; creating it now"
mkdir $RESULTS_DIR
fi
# First part of the docker COMMAND that is static, then we build the rest
COMMAND="docker run --rm \
--mount type=bind,source=$CONFIG_FILE,target=/Lean/Launcher/config.json,readonly \
-v $DATA_DIR:/Data:ro \
-v $RESULTS_DIR:/Results \
--name $CONTAINER_NAME \
-p 5678:5678 \
--expose 6000 "
# If the csharp dll and pdb are present, mount them
if [ ! -f "$CSHARP_DLL" ]; then
echo "Csharp file at '$CSHARP_DLL' does not exist; no CSharp files will be mounted"
else
COMMAND+="--mount type=bind,source=$CSHARP_DLL,target=/Lean/Launcher/bin/Debug/QuantConnect.Algorithm.CSharp.dll \
--mount type=bind,source=$CSHARP_PDB,target=/Lean/Launcher/bin/Debug/QuantConnect.Algorithm.CSharp.pdb "
fi
# If python algorithms are present, mount them
if [ ! -d "$PYTHON_DIR" ]; then
echo "No Python Algorithm location found at '$PYTHON_DIR'; no Python files will be mounted"
else
COMMAND+="-v $PYTHON_DIR:/Lean/Algorithm.Python "
fi
# If DEBUGGING is set then set the entrypoint to run mono with a debugger server
shopt -s nocasematch
if [[ "$DEBUGGING" == "y" ]]; then
COMMAND+="-p 55555:55555 \
--entrypoint mono \
$IMAGE --debug --debugger-agent=transport=dt_socket,server=y,address=0.0.0.0:55555,suspend=y \
QuantConnect.Lean.Launcher.exe --data-folder /Data --results-destination-folder /Results --config /Lean/Launcher/config.json"
echo "Docker container starting, attach to Mono process at localhost:55555 to begin"
else
COMMAND+="$IMAGE --data-folder /Data --results-destination-folder /Results --config /Lean/Launcher/config.json"
fi
SUDO=""
# Verify if user has docker permissions
if ! touch /var/run/docker.sock &>/dev/null; then
sudo -v
SUDO="sudo"
COMMAND="$SUDO $COMMAND"
fi
if [ "$($SUDO docker container inspect -f '{{.State.Running}}' $CONTAINER_NAME)" == "true" ]; then
yes_or_no "A Lean container is already running. Stop and recreate with this configuration?" &&
$SUDO docker stop $CONTAINER_NAME
elif $SUDO docker ps -a | grep -q $CONTAINER_NAME; then
yes_or_no "A Lean container is halted and will be removed. Continue?" &&
$SUDO docker rm $CONTAINER_NAME
fi
# Pull the image if we want to update
if [[ "$UPDATE" == "y" ]]; then
echo "Pulling Docker image: $IMAGE"
$SUDO docker pull $IMAGE
fi
echo -e "Launching LeanEngine with command: "
echo -e "$COMMAND"
#Run built docker COMMAND;
eval "$COMMAND"