Skip to content

Commit d70fa09

Browse files
committed
Trading hours implementation + Fixes
1 parent e4ac5d3 commit d70fa09

File tree

7 files changed

+116
-33
lines changed

7 files changed

+116
-33
lines changed

install

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ else
2121
mkdir -p /usr/local/bin
2222
BOT_SCRIPT_DESTINATION_PATH="/usr/local/bin/bot"
2323
fi
24-
curl -sSL -o ${BOT_SCRIPT_DESTINATION_PATH} https://raw.githubusercontent.com/Ph3nol/Trading-Bot/master/bot
24+
curl -sSL -o ${BOT_SCRIPT_DESTINATION_PATH} https://raw.githubusercontent.com/Ph3nol/Trading-Bot/master/bot && chmod +x ${BOT_SCRIPT_DESTINATION_PATH}
2525

2626
echo "▶️ Downloading needed Trading Bot scripts..."
2727
GITHUB_LAST_RELEASE_ENDPOINT="https://api.github.com/repos/Ph3nol/Trading-Bot/releases/latest"

src/Manager/App/InstanceHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public static function init(Instance $instance)
2525
}
2626

2727
$data = InstanceFilesystem::initInstance($instance);
28-
$instance->setParameters($data['parameters']);
28+
$instance->mergeParameters($data['parameters']);
2929

3030
$handler = new static($instance);
3131
$handler->updateConfigApiServiceCors();

src/Manager/App/Manager.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ private function populateInstances(array $instancesPayloads): self
8888
$commonPayload['config'] ?? [],
8989
$instancePayload['config'] ?? []
9090
);
91+
$instanceParameters = array_replace_recursive(
92+
$this->getDefaultParametersFromInstance(),
93+
$commonPayload['parameters'] ?? [],
94+
$instancePayload['parameters'] ?? []
95+
);
9196

9297
$instanceBehaviours = $instancePayload['behaviours'] ?? [];
9398
$instanceBehaviours = array_map(function ($behaviourData): array {
@@ -98,7 +103,8 @@ private function populateInstances(array $instancesPayloads): self
98103
$instanceSlug,
99104
$instancePayload['strategy'],
100105
$instanceConfig,
101-
$instanceBehaviours
106+
$instanceBehaviours,
107+
$instanceParameters
102108
);
103109

104110
$instance->config['bot_name'] = sprintf('TB.%s', (string) $instance);
@@ -126,6 +132,13 @@ private function getBaseConfigurationDataFromInstancePayload(array $instancePayl
126132
return json_decode($configContent, true);
127133
}
128134

135+
private function getDefaultParametersFromInstance(): array
136+
{
137+
return [
138+
'tradingHours' => [],
139+
];
140+
}
141+
129142
private function initBehaviours(): self
130143
{
131144
$finder = new Finder();

src/Manager/Domain/Instance.php

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ class Instance
2424
public string $strategy;
2525
public array $config;
2626
public array $behaviours;
27-
2827
public array $parameters = [];
28+
2929
public array $directories = [];
3030
public array $files = [];
3131

@@ -35,14 +35,16 @@ public function __construct(
3535
string $label,
3636
string $strategy,
3737
array $config,
38-
array $behaviours
38+
array $behaviours = [],
39+
array $parameters = []
3940
) {
4041
$this->uuid = $uuid;
4142
$this->slug = $slug;
4243
$this->label = $label;
4344
$this->strategy = $strategy;
4445
$this->config = $config;
4546
$this->behaviours = $behaviours;
47+
$this->parameters = $parameters;
4648

4749
$this->initDirectoriesAndFiles();
4850
}
@@ -51,12 +53,13 @@ public static function create(
5153
string $slug = null,
5254
string $strategy,
5355
array $config,
54-
array $behaviours
56+
array $behaviours = [],
57+
array $parameters = []
5558
): self {
5659
$uuid = Uuid::uuid4();
5760
$label = $slug ? strtoupper($slug) : (string) $uuid;
5861

59-
return new static($uuid, $slug, $label, $strategy, $config, $behaviours);
62+
return new static($uuid, $slug, $label, $strategy, $config, $behaviours, $parameters);
6063
}
6164

6265
public function __toString(): string
@@ -141,9 +144,9 @@ public function isUIRunning(): bool
141144
return self::STATUS_RUNNING === $this->getUIStatus();
142145
}
143146

144-
public function setParameters(array $parameters): self
147+
public function mergeParameters(array $parameters): self
145148
{
146-
$this->parameters = $parameters;
149+
$this->parameters = array_replace_recursive($this->parameters, $parameters);
147150

148151
return $this;
149152
}
@@ -168,6 +171,30 @@ public function getBehaviourConfig(BehaviourInterface $behaviour): array
168171
return $this->hasBehaviour($behaviour) ? $this->behaviours[$behaviour->getSlug()] : [];
169172
}
170173

174+
public function isOutOfTradingHours(): bool
175+
{
176+
if (!$tradingHours = $this->parameters['tradingHours']) {
177+
return false;
178+
}
179+
180+
$outOfHours = true;
181+
$nowDateTime = new \DateTime;
182+
foreach ($tradingHours as $tradingHour) {
183+
list($from, $to) = explode('-', $tradingHour);
184+
$fromString = sprintf('%s %s:00', (new \DateTime)->format('Y-m-d'), $from);
185+
$toString = sprintf('%s %s:00', (new \DateTime)->format('Y-m-d'), $to);
186+
$fromDateTime = new \DateTime($fromString);
187+
$toDateTime = new \DateTime($toString);
188+
189+
if ($nowDateTime >= $fromDateTime && $nowDateTime <= $toDateTime) {
190+
$outOfHours = false;
191+
break;
192+
}
193+
}
194+
195+
return $outOfHours;
196+
}
197+
171198
private function initDirectoriesAndFiles(): void
172199
{
173200
$baseDirectory = MANAGER_INSTANCES_DIRECTORY . '/' . $this->slug;

src/Manager/UI/Console/BaseCommand.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,10 @@ private function getInstanceContainers(Instance $instance): array
154154

155155
$containers = [];
156156
$containers[] = sprintf(
157-
'%s Core%s',
157+
'%s Core%s %s',
158158
$instance->isRunning() ? '<info>▇</info>' : '<danger>▇</danger>',
159-
($instance->isRunning() && $instance->uptime) ? sprintf(' (%s)', $instance->uptime) : ''
159+
($instance->isRunning() && $instance->uptime) ? sprintf(' (%s)', $instance->uptime) : '',
160+
$instance->isOutOfTradingHours() ? '<comment>⌚︎</comment>' : ''
160161
);
161162
$containers[] = sprintf(
162163
'%s <href=http://%s:%d/trade>UI</>%s',

src/Manager/UI/Console/CronCommand.php

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ protected function execute(InputInterface $input, OutputInterface $output)
3333
{
3434
parent::execute($input, $output);
3535

36-
$manager = Manager::fromFile(MANAGER_DIRECTORY . '/manager.yaml');
3736
$forceUpdates = false !== $input->getOption('force');
37+
$onlyInstances = false !== $input->getOption('only-instances');
38+
39+
$manager = Manager::fromFile(MANAGER_DIRECTORY . '/manager.yaml');
3840

3941
if (false !== $input->getOption('crontab')) {
4042
$output->writeln('This line is to add to your crontabs, in order to run periodic tasks needed by your instances and their behaviours.');
@@ -48,13 +50,48 @@ protected function execute(InputInterface $input, OutputInterface $output)
4850
return Command::SUCCESS;
4951
}
5052

51-
$instancesToRestart = [];
53+
$output->writeln('⚙️ Applying Instances trading hours limitations...');
54+
$this->applyTradingHours($manager, $output);
55+
56+
$output->writeln('');
57+
$output->writeln('⚙️ Updating behaviours...');
58+
$updatedInstances = $this->updateBehaviours($manager, $output, $forceUpdates, $onlyInstances);
59+
60+
$this->restartInstances($updatedInstances, $output);
61+
62+
$output->writeln('');
63+
$output->writeln('🎉 <info>Done!</info>');
64+
65+
return Command::SUCCESS;
66+
}
67+
68+
private function applyTradingHours(Manager $manager, OutputInterface $output): void
69+
{
70+
foreach ($manager->getInstances() as $instance) {
71+
$handler = InstanceHandler::init($instance);
72+
73+
if ($instance->isRunning() && true === $instance->isOutOfTradingHours()) {
74+
$output->write(sprintf(' <comment>[%s]</comment> Out of trading hours -> Stopping... ', (string) $instance));
75+
$handler->stop();
76+
$output->writeln('');
77+
} else {
78+
$output->writeln(sprintf(' <comment>[%s]</comment> ⏺', (string) $instance));
79+
}
80+
}
81+
}
82+
83+
private function updateBehaviours(
84+
Manager $manager,
85+
OutputInterface $output,
86+
bool $forceUpdates = false,
87+
bool $onlyInstances = false
88+
): array {
89+
$updatedInstances = [];
5290

53-
$output->writeln('⚙️ Updating...');
5491
foreach ($manager->getBehaviours() as $behaviour) {
5592
$behaviourName = ucfirst($behaviour->getSlug());
5693

57-
if ($forceUpdates || false === $input->getOption('only-instances')) {
94+
if ($forceUpdates || false === $onlyInstances) {
5895
$output->write(sprintf(' <comment>[%s]</comment> Main update... ', $behaviourName));
5996
if ($forceUpdates || $behaviour->needsCronUpdate()) {
6097
$behaviour->updateCron();
@@ -80,7 +117,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
80117
if ($forceUpdates || $behaviour->needsInstanceUpdate($instance)) {
81118
$behaviour->updateInstanceFromCron($instance);
82119
InstanceFilesystem::writeInstanceConfig($instance);
83-
$instancesToRestart[] = $instance;
120+
$updatedInstances[] = $instance;
84121
$output->writeln('');
85122
} else {
86123
$output->writeln('');
@@ -90,27 +127,32 @@ protected function execute(InputInterface $input, OutputInterface $output)
90127
$behaviour->write();
91128
}
92129

93-
if ($instancesToRestart) {
94-
$output->writeln('');
95-
$output->writeln('⚙️ Restarting updated running instances...');
96-
foreach ($instancesToRestart as $instance) {
97-
$handler = InstanceHandler::init($instance);
130+
return $updatedInstances;
131+
}
98132

99-
if ($instance->isRunning()) {
100-
$output->write(sprintf(
101-
' <comment>[%s]</comment> Restarting instance `%s`... ',
102-
$behaviourName,
103-
(string) $instance
104-
));
105-
$handler->restart(false);
106-
$output->writeln('');
107-
}
108-
}
133+
private function restartInstances(array $updatedInstances, OutputInterface $output): void
134+
{
135+
$instancesToRestart = array_filter($updatedInstances, function (Instance $instance): bool {
136+
return $instance->isRunning();
137+
});
138+
139+
if (!$instancesToRestart) {
140+
return ;
109141
}
110142

111143
$output->writeln('');
112-
$output->writeln('🎉 <info>Done!</info>');
144+
$output->writeln('⚙️ Restarting updated running instances...');
145+
foreach ($instancesToRestart as $instance) {
146+
$handler = InstanceHandler::init($instance);
113147

114-
return Command::SUCCESS;
148+
if ($instance->isRunning()) {
149+
$output->write(sprintf(
150+
' <comment>[%s]</comment> Restarting... ',
151+
(string) $instance
152+
));
153+
$handler->restart(false);
154+
$output->writeln('');
155+
}
156+
}
115157
}
116158
}

0 commit comments

Comments
 (0)