feat(settings): add settings route and API updates\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This commit is contained in:
2026-05-16 20:19:35 +02:00
parent 9b63d981b0
commit 0ee89cf052
38 changed files with 1426 additions and 562 deletions
+13 -10
View File
@@ -42,16 +42,17 @@ Based on all the information above, make a trading decision. Respond with JSON c
- confidence: a number between 0 and 1
- reasoning: brief explanation
If the action is "sell", also include an "executionPlan" object with:
- amount: number (shares to sell)
If the action is "buy" or "sell", also include an "executionPlan" object with:
- amount: number (shares to trade)
- riskManagement: object (e.g., { maxLossPercent: 2 })
- takeProfit: number (target take-profit price)
- stopLoss: number (stop-loss price or absolute value)
Format your response as JSON with these fields.`;
const response = await this.client.createChatCompletion(
[
{ role: "system", content: "You are a trading agent that makes buy/sell/hold decisions and provides execution guidance when selling." },
{ role: "system", content: "You are a trading agent that makes buy/sell/hold decisions and provides execution guidance for buy and sell actions." },
{ role: "user", content: prompt },
],
this.model
@@ -86,13 +87,15 @@ Format your response as JSON with these fields.`;
executionPlan = JSON.parse(execMatch[1]);
} catch (err) {
// fallback: try to extract primitive fields
const amountMatch = content.match(/"amount"\s*:\s*([0-9.]+)/);
const takeProfitMatch = content.match(/"takeProfit"\s*:\s*([0-9.]+)/);
const maxLossMatch = content.match(/"maxLossPercent"\s*:\s*([0-9.]+)/);
const methodMatch = content.match(/"method"\s*:\s*"([^"]+)"/);
const amountMatch = content.match(/(?:"amount"|\bamount\b)\s*:\s*([0-9.]+)/);
const takeProfitMatch = content.match(/(?:"takeProfit"|\btakeProfit\b)\s*:\s*([0-9.]+)/);
const stopLossMatch = content.match(/(?:"stopLoss"|\bstopLoss\b)\s*:\s*([0-9.]+)/);
const maxLossMatch = content.match(/(?:"maxLossPercent"|\bmaxLossPercent\b)\s*:\s*([0-9.]+)/);
const methodMatch = content.match(/(?:"method"|\bmethod\b)\s*:\s*"([^"]+)"/);
executionPlan = {} as any;
if (amountMatch) executionPlan.amount = parseFloat(amountMatch[1]);
if (takeProfitMatch) executionPlan.takeProfit = parseFloat(takeProfitMatch[1]);
if (stopLossMatch) executionPlan.stopLoss = parseFloat(stopLossMatch[1]);
executionPlan.riskManagement = {};
if (maxLossMatch) executionPlan.riskManagement.maxLossPercent = parseFloat(maxLossMatch[1]);
if (methodMatch) executionPlan.riskManagement.method = methodMatch[1];
@@ -101,8 +104,8 @@ Format your response as JSON with these fields.`;
// Additional fallback: if executionPlan parsed but missing nested riskManagement fields, try to extract them
if (executionPlan && executionPlan.riskManagement == null) {
const maxLossMatch2 = content.match(/"maxLossPercent"\s*:\s*([0-9.]+)/);
const methodMatch2 = content.match(/"method"\s*:\s*"([^"]+)"/);
const maxLossMatch2 = content.match(/(?:"maxLossPercent"|\bmaxLossPercent\b)\s*:\s*([0-9.]+)/);
const methodMatch2 = content.match(/(?:"method"|\bmethod\b)\s*:\s*"([^"]+)"/);
if (maxLossMatch2 || methodMatch2) {
executionPlan.riskManagement = executionPlan.riskManagement || {};
if (maxLossMatch2) executionPlan.riskManagement.maxLossPercent = parseFloat(maxLossMatch2[1]);
@@ -118,7 +121,7 @@ Format your response as JSON with these fields.`;
debateRounds: debates,
};
if (action === 'sell' && executionPlan) {
if ((action === 'sell' || action === 'buy') && executionPlan) {
decision.executionPlan = executionPlan;
}