feat: include time-close result in hub sync and instance trade records
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1544,9 +1544,10 @@ TRADE_COMPLETED_RESULTS = (
|
|||||||
"手动平仓",
|
"手动平仓",
|
||||||
"强制清仓",
|
"强制清仓",
|
||||||
"外部平仓",
|
"外部平仓",
|
||||||
|
TIME_CLOSE_RESULT,
|
||||||
)
|
)
|
||||||
|
|
||||||
REVIEW_RESULT_OPTIONS = ("止盈", "止损", "保本止盈", "移动止盈", "手动平仓")
|
REVIEW_RESULT_OPTIONS = ("止盈", "止损", "保本止盈", "移动止盈", "手动平仓", TIME_CLOSE_RESULT)
|
||||||
|
|
||||||
|
|
||||||
def parse_dt_for_trading_day(s):
|
def parse_dt_for_trading_day(s):
|
||||||
|
|||||||
@@ -554,6 +554,7 @@
|
|||||||
{% set effective_result = r.effective_result %}
|
{% set effective_result = r.effective_result %}
|
||||||
{% if effective_result in ["止盈","保本止盈","移动止盈"] %}<span class="badge profit">{{ effective_result }}</span>
|
{% if effective_result in ["止盈","保本止盈","移动止盈"] %}<span class="badge profit">{{ effective_result }}</span>
|
||||||
{% elif effective_result in ["止损","强制清仓","手动平仓"] %}<span class="badge loss">{{ effective_result }}</span>
|
{% elif effective_result in ["止损","强制清仓","手动平仓"] %}<span class="badge loss">{{ effective_result }}</span>
|
||||||
|
{% elif effective_result == "时间平仓" %}<span class="badge miss">{{ effective_result }}</span>
|
||||||
{% else %}<span class="badge miss">{{ effective_result }}</span>{% endif %}
|
{% else %}<span class="badge miss">{{ effective_result }}</span>{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -987,7 +988,7 @@ function editTradeRecordReview(t){
|
|||||||
if(takeProfit === null) return;
|
if(takeProfit === null) return;
|
||||||
const pnl = prompt("最终盈亏(可手工核对后填写)", String(t.pnl_amount ?? ""));
|
const pnl = prompt("最终盈亏(可手工核对后填写)", String(t.pnl_amount ?? ""));
|
||||||
if(pnl === null) return;
|
if(pnl === null) return;
|
||||||
const result = prompt("结果(止盈/止损/保本止盈/移动止盈/手动平仓)", String(t.result || ""));
|
const result = prompt("结果(止盈/止损/保本止盈/移动止盈/手动平仓/时间平仓)", String(t.result || ""));
|
||||||
if(result === null) return;
|
if(result === null) return;
|
||||||
const note = prompt("备注(可空)", String(t.miss_reason || "")) ?? "";
|
const note = prompt("备注(可空)", String(t.miss_reason || "")) ?? "";
|
||||||
const entryHint = "开仓类型:五种固定整句、或自定义说明(2000字内;与复盘表单一致;留空=本次不改该项)";
|
const entryHint = "开仓类型:五种固定整句、或自定义说明(2000字内;与复盘表单一致;留空=本次不改该项)";
|
||||||
|
|||||||
@@ -1538,9 +1538,10 @@ TRADE_COMPLETED_RESULTS = (
|
|||||||
"手动平仓",
|
"手动平仓",
|
||||||
"强制清仓",
|
"强制清仓",
|
||||||
"外部平仓",
|
"外部平仓",
|
||||||
|
TIME_CLOSE_RESULT,
|
||||||
)
|
)
|
||||||
|
|
||||||
REVIEW_RESULT_OPTIONS = ("止盈", "止损", "保本止盈", "移动止盈", "手动平仓")
|
REVIEW_RESULT_OPTIONS = ("止盈", "止损", "保本止盈", "移动止盈", "手动平仓", TIME_CLOSE_RESULT)
|
||||||
|
|
||||||
|
|
||||||
def parse_dt_for_trading_day(s):
|
def parse_dt_for_trading_day(s):
|
||||||
|
|||||||
@@ -534,6 +534,7 @@
|
|||||||
{% set effective_result = r.effective_result %}
|
{% set effective_result = r.effective_result %}
|
||||||
{% if effective_result in ["止盈","保本止盈","移动止盈"] %}<span class="badge profit">{{ effective_result }}</span>
|
{% if effective_result in ["止盈","保本止盈","移动止盈"] %}<span class="badge profit">{{ effective_result }}</span>
|
||||||
{% elif effective_result in ["止损","强制清仓","手动平仓"] %}<span class="badge loss">{{ effective_result }}</span>
|
{% elif effective_result in ["止损","强制清仓","手动平仓"] %}<span class="badge loss">{{ effective_result }}</span>
|
||||||
|
{% elif effective_result == "时间平仓" %}<span class="badge miss">{{ effective_result }}</span>
|
||||||
{% else %}<span class="badge miss">{{ effective_result }}</span>{% endif %}
|
{% else %}<span class="badge miss">{{ effective_result }}</span>{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -967,7 +968,7 @@ function editTradeRecordReview(t){
|
|||||||
if(takeProfit === null) return;
|
if(takeProfit === null) return;
|
||||||
const pnl = prompt("最终盈亏(可手工核对后填写)", String(t.pnl_amount ?? ""));
|
const pnl = prompt("最终盈亏(可手工核对后填写)", String(t.pnl_amount ?? ""));
|
||||||
if(pnl === null) return;
|
if(pnl === null) return;
|
||||||
const result = prompt("结果(止盈/止损/保本止盈/移动止盈/手动平仓)", String(t.result || ""));
|
const result = prompt("结果(止盈/止损/保本止盈/移动止盈/手动平仓/时间平仓)", String(t.result || ""));
|
||||||
if(result === null) return;
|
if(result === null) return;
|
||||||
const note = prompt("备注(可空)", String(t.miss_reason || "")) ?? "";
|
const note = prompt("备注(可空)", String(t.miss_reason || "")) ?? "";
|
||||||
const entryHint = "开仓类型:五种固定整句、或自定义说明(2000字内;与复盘表单一致;留空=本次不改该项)";
|
const entryHint = "开仓类型:五种固定整句、或自定义说明(2000字内;与复盘表单一致;留空=本次不改该项)";
|
||||||
|
|||||||
@@ -1538,9 +1538,10 @@ TRADE_COMPLETED_RESULTS = (
|
|||||||
"手动平仓",
|
"手动平仓",
|
||||||
"强制清仓",
|
"强制清仓",
|
||||||
"外部平仓",
|
"外部平仓",
|
||||||
|
TIME_CLOSE_RESULT,
|
||||||
)
|
)
|
||||||
|
|
||||||
REVIEW_RESULT_OPTIONS = ("止盈", "止损", "保本止盈", "移动止盈", "手动平仓")
|
REVIEW_RESULT_OPTIONS = ("止盈", "止损", "保本止盈", "移动止盈", "手动平仓", TIME_CLOSE_RESULT)
|
||||||
|
|
||||||
|
|
||||||
def parse_dt_for_trading_day(s):
|
def parse_dt_for_trading_day(s):
|
||||||
|
|||||||
@@ -534,6 +534,7 @@
|
|||||||
{% set effective_result = r.effective_result %}
|
{% set effective_result = r.effective_result %}
|
||||||
{% if effective_result in ["止盈","保本止盈","移动止盈"] %}<span class="badge profit">{{ effective_result }}</span>
|
{% if effective_result in ["止盈","保本止盈","移动止盈"] %}<span class="badge profit">{{ effective_result }}</span>
|
||||||
{% elif effective_result in ["止损","强制清仓","手动平仓"] %}<span class="badge loss">{{ effective_result }}</span>
|
{% elif effective_result in ["止损","强制清仓","手动平仓"] %}<span class="badge loss">{{ effective_result }}</span>
|
||||||
|
{% elif effective_result == "时间平仓" %}<span class="badge miss">{{ effective_result }}</span>
|
||||||
{% else %}<span class="badge miss">{{ effective_result }}</span>{% endif %}
|
{% else %}<span class="badge miss">{{ effective_result }}</span>{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -967,7 +968,7 @@ function editTradeRecordReview(t){
|
|||||||
if(takeProfit === null) return;
|
if(takeProfit === null) return;
|
||||||
const pnl = prompt("最终盈亏(可手工核对后填写)", String(t.pnl_amount ?? ""));
|
const pnl = prompt("最终盈亏(可手工核对后填写)", String(t.pnl_amount ?? ""));
|
||||||
if(pnl === null) return;
|
if(pnl === null) return;
|
||||||
const result = prompt("结果(止盈/止损/保本止盈/移动止盈/手动平仓)", String(t.result || ""));
|
const result = prompt("结果(止盈/止损/保本止盈/移动止盈/手动平仓/时间平仓)", String(t.result || ""));
|
||||||
if(result === null) return;
|
if(result === null) return;
|
||||||
const note = prompt("备注(可空)", String(t.miss_reason || "")) ?? "";
|
const note = prompt("备注(可空)", String(t.miss_reason || "")) ?? "";
|
||||||
const entryHint = "开仓类型:五种固定整句、或自定义说明(2000字内;与复盘表单一致;留空=本次不改该项)";
|
const entryHint = "开仓类型:五种固定整句、或自定义说明(2000字内;与复盘表单一致;留空=本次不改该项)";
|
||||||
|
|||||||
@@ -1524,9 +1524,10 @@ TRADE_COMPLETED_RESULTS = (
|
|||||||
"手动平仓",
|
"手动平仓",
|
||||||
"强制清仓",
|
"强制清仓",
|
||||||
"外部平仓",
|
"外部平仓",
|
||||||
|
TIME_CLOSE_RESULT,
|
||||||
)
|
)
|
||||||
|
|
||||||
REVIEW_RESULT_OPTIONS = ("止盈", "止损", "保本止盈", "移动止盈", "手动平仓")
|
REVIEW_RESULT_OPTIONS = ("止盈", "止损", "保本止盈", "移动止盈", "手动平仓", TIME_CLOSE_RESULT)
|
||||||
|
|
||||||
|
|
||||||
def parse_dt_for_trading_day(s):
|
def parse_dt_for_trading_day(s):
|
||||||
|
|||||||
@@ -563,6 +563,7 @@
|
|||||||
{% set effective_result = r.effective_result %}
|
{% set effective_result = r.effective_result %}
|
||||||
{% if effective_result in ["止盈","保本止盈","移动止盈"] %}<span class="badge profit">{{ effective_result }}</span>
|
{% if effective_result in ["止盈","保本止盈","移动止盈"] %}<span class="badge profit">{{ effective_result }}</span>
|
||||||
{% elif effective_result in ["止损","强制清仓","手动平仓"] %}<span class="badge loss">{{ effective_result }}</span>
|
{% elif effective_result in ["止损","强制清仓","手动平仓"] %}<span class="badge loss">{{ effective_result }}</span>
|
||||||
|
{% elif effective_result == "时间平仓" %}<span class="badge miss">{{ effective_result }}</span>
|
||||||
{% else %}<span class="badge miss">{{ effective_result }}</span>{% endif %}
|
{% else %}<span class="badge miss">{{ effective_result }}</span>{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -996,7 +997,7 @@ function editTradeRecordReview(t){
|
|||||||
if(takeProfit === null) return;
|
if(takeProfit === null) return;
|
||||||
const pnl = prompt("最终盈亏(可手工核对后填写)", String(t.pnl_amount ?? ""));
|
const pnl = prompt("最终盈亏(可手工核对后填写)", String(t.pnl_amount ?? ""));
|
||||||
if(pnl === null) return;
|
if(pnl === null) return;
|
||||||
const result = prompt("结果(止盈/止损/保本止盈/移动止盈/手动平仓)", String(t.result || ""));
|
const result = prompt("结果(止盈/止损/保本止盈/移动止盈/手动平仓/时间平仓)", String(t.result || ""));
|
||||||
if(result === null) return;
|
if(result === null) return;
|
||||||
const note = prompt("备注(可空)", String(t.miss_reason || "")) ?? "";
|
const note = prompt("备注(可空)", String(t.miss_reason || "")) ?? "";
|
||||||
const entryHint = "开仓类型:五种固定整句、或自定义说明(2000字内;与复盘表单一致;留空=本次不改该项)";
|
const entryHint = "开仓类型:五种固定整句、或自定义说明(2000字内;与复盘表单一致;留空=本次不改该项)";
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from strategy_trade_labels import (
|
|||||||
MONITOR_TYPE_TREND_PULLBACK,
|
MONITOR_TYPE_TREND_PULLBACK,
|
||||||
entry_reason_for_monitor_type,
|
entry_reason_for_monitor_type,
|
||||||
)
|
)
|
||||||
|
from time_close_lib import TIME_CLOSE_RESULT
|
||||||
|
|
||||||
TRADE_COMPLETED_RESULTS = (
|
TRADE_COMPLETED_RESULTS = (
|
||||||
"止盈",
|
"止盈",
|
||||||
@@ -18,6 +19,7 @@ TRADE_COMPLETED_RESULTS = (
|
|||||||
"手动平仓",
|
"手动平仓",
|
||||||
"强制清仓",
|
"强制清仓",
|
||||||
"外部平仓",
|
"外部平仓",
|
||||||
|
TIME_CLOSE_RESULT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,47 @@ class HubTradesLibTest(unittest.TestCase):
|
|||||||
self.assertTrue(rows[0]["reviewed"])
|
self.assertTrue(rows[0]["reviewed"])
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
def test_time_close_result_included(self):
|
||||||
|
conn = sqlite3.connect(":memory:")
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
conn.execute(
|
||||||
|
"""CREATE TABLE trade_records (
|
||||||
|
symbol TEXT, direction TEXT, result TEXT, reviewed_result TEXT,
|
||||||
|
pnl_amount REAL, reviewed_pnl_amount REAL, exchange_realized_pnl REAL,
|
||||||
|
closed_at TEXT, reviewed_closed_at TEXT, opened_at TEXT, reviewed_opened_at TEXT,
|
||||||
|
created_at TEXT, monitor_type TEXT, actual_rr REAL, planned_rr REAL,
|
||||||
|
trade_style TEXT, entry_reason TEXT, reviewed_at TEXT
|
||||||
|
)"""
|
||||||
|
)
|
||||||
|
conn.execute(
|
||||||
|
"INSERT INTO trade_records VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
|
||||||
|
(
|
||||||
|
"BTC/USDT",
|
||||||
|
"long",
|
||||||
|
"时间平仓",
|
||||||
|
None,
|
||||||
|
1.2,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
"2026-06-06 12:00:00",
|
||||||
|
None,
|
||||||
|
"2026-06-06 08:00:00",
|
||||||
|
None,
|
||||||
|
"2026-06-06 12:00:00",
|
||||||
|
"趋势回调",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
"trend",
|
||||||
|
"",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
rows = fetch_trades_for_trading_day(conn, "2026-06-06")
|
||||||
|
self.assertEqual(len(rows), 1)
|
||||||
|
self.assertEqual(rows[0]["result"], "时间平仓")
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user