update 03-29 01:36
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
{"t":0,"agent":"system","event":"keyword_detected","keyword":"autopilot"}
|
||||
{"t":0,"agent":"system","event":"mode_change","mode_from":"none","mode_to":"autopilot"}
|
||||
{"t":0,"agent":"system","event":"skill_invoked","skill_name":"oh-my-claudecode:autopilot"}
|
||||
{"t":0,"agent":"a2823c2","agent_type":"Explore","event":"agent_start","parent_mode":"none"}
|
||||
{"t":0,"agent":"a5a8656","agent_type":"general-purpose","event":"agent_start","parent_mode":"none"}
|
||||
{"t":0,"agent":"a562974","agent_type":"general-purpose","event":"agent_start","parent_mode":"none"}
|
||||
{"t":0,"agent":"a2823c2","agent_type":"Explore","event":"agent_stop","success":true,"duration_ms":87491}
|
||||
{"t":0,"agent":"a5a8656","agent_type":"general-purpose","event":"agent_stop","success":true,"duration_ms":68289}
|
||||
{"t":0,"agent":"a562974","agent_type":"general-purpose","event":"agent_stop","success":true,"duration_ms":217576}
|
||||
{"t":0,"agent":"a4c4346","agent_type":"executor","event":"agent_start","parent_mode":"none"}
|
||||
{"t":0,"agent":"a67d07c","agent_type":"executor","event":"agent_start","parent_mode":"none"}
|
||||
{"t":0,"agent":"ac65b63","agent_type":"executor","event":"agent_start","parent_mode":"none"}
|
||||
{"t":0,"agent":"a4c4346","agent_type":"executor","event":"agent_stop","success":true,"duration_ms":46095}
|
||||
{"t":0,"agent":"ac65b63","agent_type":"executor","event":"agent_stop","success":true,"duration_ms":38984}
|
||||
{"t":0,"agent":"a67d07c","agent_type":"executor","event":"agent_stop","success":true,"duration_ms":83609}
|
||||
@@ -1 +1 @@
|
||||
{"session_id":"a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98","transcript_path":"C:\\Users\\User\\.claude\\projects\\D--PRJ-poly-company-dtr2-poly\\a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98.jsonl","cwd":"D:\\PRJ\\poly_company\\dtr2_poly\\polymarket-arb-bot","model":{"id":"claude-opus-4-6[1m]","display_name":"Opus 4.6 (1M context)"},"workspace":{"current_dir":"D:\\PRJ\\poly_company\\dtr2_poly\\polymarket-arb-bot","project_dir":"D:\\PRJ\\poly_company\\dtr2_poly","added_dirs":["D:/PRJ/poly_company/dtr2_poly"]},"version":"2.1.78","output_style":{"name":"default"},"cost":{"total_cost_usd":7.426863299999999,"total_duration_ms":1802055,"total_api_duration_ms":717171,"total_lines_added":126,"total_lines_removed":36},"context_window":{"total_input_tokens":166,"total_output_tokens":44526,"context_window_size":1000000,"current_usage":{"input_tokens":3,"output_tokens":125,"cache_creation_input_tokens":104255,"cache_read_input_tokens":24263},"used_percentage":13,"remaining_percentage":87},"exceeds_200k_tokens":false}
|
||||
{"session_id":"a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98","transcript_path":"C:\\Users\\User\\.claude\\projects\\D--PRJ-poly-company-dtr2-poly\\a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98.jsonl","cwd":"D:\\PRJ\\poly_company\\dtr2_poly\\polymarket-arb-bot","model":{"id":"claude-opus-4-6[1m]","display_name":"Opus 4.6 (1M context)"},"workspace":{"current_dir":"D:\\PRJ\\poly_company\\dtr2_poly\\polymarket-arb-bot","project_dir":"D:\\PRJ\\poly_company\\dtr2_poly","added_dirs":["D:/PRJ/poly_company/dtr2_poly"]},"version":"2.1.78","output_style":{"name":"default"},"cost":{"total_cost_usd":17.360554950000008,"total_duration_ms":52058270,"total_api_duration_ms":1692584,"total_lines_added":178,"total_lines_removed":76},"context_window":{"total_input_tokens":26490,"total_output_tokens":97675,"context_window_size":1000000,"current_usage":{"input_tokens":3,"output_tokens":522,"cache_creation_input_tokens":886,"cache_read_input_tokens":200200},"used_percentage":20,"remaining_percentage":80},"exceeds_200k_tokens":true}
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"lastSentAt": "2026-03-28T02:24:21.283Z"
|
||||
"lastSentAt": "2026-03-28T16:00:45.742Z"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"tool_name": "Bash",
|
||||
"tool_input_preview": "{\"command\":\".venv/Scripts/python.exe -c \\\"\\nimport sqlite3, tempfile, os\\nfrom pathlib import Path\\nimport pandas as pd\\nprint('=== Test 5: Dashboard query_db ===')\\n\\ndef query_db(db_path, sql):\\n ...",
|
||||
"error": "Exit code 1\nTraceback (most recent call last):\r\n File \u001b[35m\"<string>\"\u001b[0m, line \u001b[35m29\u001b[0m, in \u001b[35m<module>\u001b[0m\r\n \u001b[31mos.unlink\u001b[0m\u001b[1;31m(tmp_path)\u001b[0m\r\n \u001b[31m~~~~~~~~~\u001b[0m\u001b[1;31m^^^^^^^^^^\u001b[0m\r\n\u001b[1;35mPermissionError\u001b[0m: \u001b[35m[WinError 32] <20>ٸ<EFBFBD> <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>̱<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>: 'C:\\\\Users\\\\User\\\\AppData\\\\Local\\\\Temp\\\\tmpe_93w69z.db'\u001b[0m\r\n=== Test 5: Dashboard query_db ===\r\n Normal query OK\r\n Exception handling OK\r\n Nonexistent DB OK",
|
||||
"timestamp": "2026-03-28T02:23:24.339Z",
|
||||
"retry_count": 1
|
||||
"tool_input_preview": "{\"command\":\"ssh kakao@100.125.85.86 \\\"ps aux | grep streamlit | grep -v grep; echo '---'; ss -tlnp | grep 8503 2>/dev/null\\\"\",\"timeout\":10000,\"description\":\"Check current dashboard status\"}",
|
||||
"error": "Exit code 1\n---",
|
||||
"timestamp": "2026-03-28T16:00:08.546Z",
|
||||
"retry_count": 2
|
||||
}
|
||||
135
.omc/state/mission-state.json
Normal file
135
.omc/state/mission-state.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"updatedAt": "2026-03-28T16:32:51.357Z",
|
||||
"missions": [
|
||||
{
|
||||
"id": "session:a9e3d3e8-6b91-4c7a-9c52-a928a3b1fb98:none",
|
||||
"source": "session",
|
||||
"name": "none",
|
||||
"objective": "Session mission",
|
||||
"createdAt": "2026-03-28T16:26:16.914Z",
|
||||
"updatedAt": "2026-03-28T16:32:51.357Z",
|
||||
"status": "done",
|
||||
"workerCount": 6,
|
||||
"taskCounts": {
|
||||
"total": 6,
|
||||
"pending": 0,
|
||||
"blocked": 0,
|
||||
"inProgress": 0,
|
||||
"completed": 6,
|
||||
"failed": 0
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"name": "Explore:a2823c2",
|
||||
"role": "Explore",
|
||||
"ownership": "a2823c25be1f8b5ce",
|
||||
"status": "done",
|
||||
"currentStep": null,
|
||||
"latestUpdate": "completed",
|
||||
"completedSummary": null,
|
||||
"updatedAt": "2026-03-28T16:27:44.405Z"
|
||||
},
|
||||
{
|
||||
"name": "general-purpose:a5a8656",
|
||||
"role": "general-purpose",
|
||||
"ownership": "a5a8656ed974efc3b",
|
||||
"status": "done",
|
||||
"currentStep": null,
|
||||
"latestUpdate": "completed",
|
||||
"completedSummary": null,
|
||||
"updatedAt": "2026-03-28T16:27:44.789Z"
|
||||
},
|
||||
{
|
||||
"name": "general-purpose:a562974",
|
||||
"role": "general-purpose",
|
||||
"ownership": "a562974c694d29e8f",
|
||||
"status": "done",
|
||||
"currentStep": null,
|
||||
"latestUpdate": "completed",
|
||||
"completedSummary": null,
|
||||
"updatedAt": "2026-03-28T16:30:22.237Z"
|
||||
},
|
||||
{
|
||||
"name": "executor:a4c4346",
|
||||
"role": "executor",
|
||||
"ownership": "a4c4346f86c16a176",
|
||||
"status": "done",
|
||||
"currentStep": null,
|
||||
"latestUpdate": "completed",
|
||||
"completedSummary": null,
|
||||
"updatedAt": "2026-03-28T16:31:57.664Z"
|
||||
},
|
||||
{
|
||||
"name": "executor:a67d07c",
|
||||
"role": "executor",
|
||||
"ownership": "a67d07c795eb3ca16",
|
||||
"status": "done",
|
||||
"currentStep": null,
|
||||
"latestUpdate": "completed",
|
||||
"completedSummary": null,
|
||||
"updatedAt": "2026-03-28T16:32:51.357Z"
|
||||
},
|
||||
{
|
||||
"name": "executor:ac65b63",
|
||||
"role": "executor",
|
||||
"ownership": "ac65b630adcae3e6c",
|
||||
"status": "done",
|
||||
"currentStep": null,
|
||||
"latestUpdate": "completed",
|
||||
"completedSummary": null,
|
||||
"updatedAt": "2026-03-28T16:32:15.560Z"
|
||||
}
|
||||
],
|
||||
"timeline": [
|
||||
{
|
||||
"id": "session-start:a4c4346f86c16a176:2026-03-28T16:31:11.569Z",
|
||||
"at": "2026-03-28T16:31:11.569Z",
|
||||
"kind": "update",
|
||||
"agent": "executor:a4c4346",
|
||||
"detail": "started executor:a4c4346",
|
||||
"sourceKey": "session-start:a4c4346f86c16a176"
|
||||
},
|
||||
{
|
||||
"id": "session-start:a67d07c795eb3ca16:2026-03-28T16:31:27.748Z",
|
||||
"at": "2026-03-28T16:31:27.748Z",
|
||||
"kind": "update",
|
||||
"agent": "executor:a67d07c",
|
||||
"detail": "started executor:a67d07c",
|
||||
"sourceKey": "session-start:a67d07c795eb3ca16"
|
||||
},
|
||||
{
|
||||
"id": "session-start:ac65b630adcae3e6c:2026-03-28T16:31:36.576Z",
|
||||
"at": "2026-03-28T16:31:36.576Z",
|
||||
"kind": "update",
|
||||
"agent": "executor:ac65b63",
|
||||
"detail": "started executor:ac65b63",
|
||||
"sourceKey": "session-start:ac65b630adcae3e6c"
|
||||
},
|
||||
{
|
||||
"id": "session-stop:a4c4346f86c16a176:2026-03-28T16:31:57.664Z",
|
||||
"at": "2026-03-28T16:31:57.664Z",
|
||||
"kind": "completion",
|
||||
"agent": "executor:a4c4346",
|
||||
"detail": "completed",
|
||||
"sourceKey": "session-stop:a4c4346f86c16a176"
|
||||
},
|
||||
{
|
||||
"id": "session-stop:ac65b630adcae3e6c:2026-03-28T16:32:15.560Z",
|
||||
"at": "2026-03-28T16:32:15.560Z",
|
||||
"kind": "completion",
|
||||
"agent": "executor:ac65b63",
|
||||
"detail": "completed",
|
||||
"sourceKey": "session-stop:ac65b630adcae3e6c"
|
||||
},
|
||||
{
|
||||
"id": "session-stop:a67d07c795eb3ca16:2026-03-28T16:32:51.357Z",
|
||||
"at": "2026-03-28T16:32:51.357Z",
|
||||
"kind": "completion",
|
||||
"agent": "executor:a67d07c",
|
||||
"detail": "completed",
|
||||
"sourceKey": "session-stop:a67d07c795eb3ca16"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
62
.omc/state/subagent-tracking.json
Normal file
62
.omc/state/subagent-tracking.json
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"agents": [
|
||||
{
|
||||
"agent_id": "a2823c25be1f8b5ce",
|
||||
"agent_type": "Explore",
|
||||
"started_at": "2026-03-28T16:26:16.914Z",
|
||||
"parent_mode": "none",
|
||||
"status": "completed",
|
||||
"completed_at": "2026-03-28T16:27:44.405Z",
|
||||
"duration_ms": 87491
|
||||
},
|
||||
{
|
||||
"agent_id": "a5a8656ed974efc3b",
|
||||
"agent_type": "general-purpose",
|
||||
"started_at": "2026-03-28T16:26:36.500Z",
|
||||
"parent_mode": "none",
|
||||
"status": "completed",
|
||||
"completed_at": "2026-03-28T16:27:44.789Z",
|
||||
"duration_ms": 68289
|
||||
},
|
||||
{
|
||||
"agent_id": "a562974c694d29e8f",
|
||||
"agent_type": "general-purpose",
|
||||
"started_at": "2026-03-28T16:26:44.661Z",
|
||||
"parent_mode": "none",
|
||||
"status": "completed",
|
||||
"completed_at": "2026-03-28T16:30:22.237Z",
|
||||
"duration_ms": 217576
|
||||
},
|
||||
{
|
||||
"agent_id": "a4c4346f86c16a176",
|
||||
"agent_type": "oh-my-claudecode:executor",
|
||||
"started_at": "2026-03-28T16:31:11.569Z",
|
||||
"parent_mode": "none",
|
||||
"status": "completed",
|
||||
"completed_at": "2026-03-28T16:31:57.664Z",
|
||||
"duration_ms": 46095
|
||||
},
|
||||
{
|
||||
"agent_id": "a67d07c795eb3ca16",
|
||||
"agent_type": "oh-my-claudecode:executor",
|
||||
"started_at": "2026-03-28T16:31:27.748Z",
|
||||
"parent_mode": "none",
|
||||
"status": "completed",
|
||||
"completed_at": "2026-03-28T16:32:51.357Z",
|
||||
"duration_ms": 83609
|
||||
},
|
||||
{
|
||||
"agent_id": "ac65b630adcae3e6c",
|
||||
"agent_type": "oh-my-claudecode:executor",
|
||||
"started_at": "2026-03-28T16:31:36.576Z",
|
||||
"parent_mode": "none",
|
||||
"status": "completed",
|
||||
"completed_at": "2026-03-28T16:32:15.560Z",
|
||||
"duration_ms": 38984
|
||||
}
|
||||
],
|
||||
"total_spawned": 6,
|
||||
"total_completed": 6,
|
||||
"total_failed": 0,
|
||||
"last_updated": "2026-03-28T16:32:51.471Z"
|
||||
}
|
||||
30
backtest.py
30
backtest.py
@@ -194,15 +194,15 @@ class Backtester:
|
||||
|
||||
# Simulate Polymarket price (lagging behind reality)
|
||||
if abs(change_pct) > 0.05:
|
||||
lag_factor = 0.3 # Polymarket adjusts at 30% of actual
|
||||
lag_factor = 0.8 # Polymarket adjusts slowly behind CEX
|
||||
if change_pct > 0:
|
||||
sim_poly_up = 0.50 + abs(change_pct) * lag_factor * 10
|
||||
sim_poly_up = min(sim_poly_up, 0.75)
|
||||
sim_poly_down = max(0.25, 1.0 - sim_poly_up - rng.uniform(0, 0.04))
|
||||
sim_poly_up = 0.50 + abs(change_pct) * lag_factor
|
||||
sim_poly_up = min(sim_poly_up, 0.70)
|
||||
sim_poly_down = max(0.30, 1.0 - sim_poly_up - rng.uniform(0, 0.04))
|
||||
else:
|
||||
sim_poly_down = 0.50 + abs(change_pct) * lag_factor * 10
|
||||
sim_poly_down = min(sim_poly_down, 0.75)
|
||||
sim_poly_up = max(0.25, 1.0 - sim_poly_down - rng.uniform(0, 0.04))
|
||||
sim_poly_down = 0.50 + abs(change_pct) * lag_factor
|
||||
sim_poly_down = min(sim_poly_down, 0.70)
|
||||
sim_poly_up = max(0.30, 1.0 - sim_poly_down - rng.uniform(0, 0.04))
|
||||
else:
|
||||
sim_poly_up = 0.50 + rng.uniform(-0.02, 0.02)
|
||||
sim_poly_down = 0.50 + rng.uniform(-0.02, 0.02)
|
||||
@@ -370,17 +370,17 @@ class Backtester:
|
||||
change_pct = (mid_price - start_price) / start_price * 100
|
||||
|
||||
# Simulate Polymarket prices based on actual market behavior
|
||||
# More conservative lag simulation for historical
|
||||
# Conservative lag simulation for historical data
|
||||
if abs(change_pct) > 0.05:
|
||||
lag = 0.25 # Market adjusts at ~25% speed
|
||||
lag = 0.6 # Market adjusts at ~60% speed
|
||||
if change_pct > 0:
|
||||
poly_up = 0.50 + abs(change_pct) * lag * 8
|
||||
poly_up = min(poly_up, 0.72)
|
||||
poly_down = max(0.28, 1.0 - poly_up - 0.02)
|
||||
poly_up = 0.50 + abs(change_pct) * lag
|
||||
poly_up = min(poly_up, 0.68)
|
||||
poly_down = max(0.32, 1.0 - poly_up - 0.02)
|
||||
else:
|
||||
poly_down = 0.50 + abs(change_pct) * lag * 8
|
||||
poly_down = min(poly_down, 0.72)
|
||||
poly_up = max(0.28, 1.0 - poly_down - 0.02)
|
||||
poly_down = 0.50 + abs(change_pct) * lag
|
||||
poly_down = min(poly_down, 0.68)
|
||||
poly_up = max(0.32, 1.0 - poly_down - 0.02)
|
||||
else:
|
||||
poly_up = 0.50
|
||||
poly_down = 0.50
|
||||
|
||||
122
backtest_results.json
Normal file
122
backtest_results.json
Normal file
@@ -0,0 +1,122 @@
|
||||
[
|
||||
{
|
||||
"mode": "synthetic",
|
||||
"asset": "BTC",
|
||||
"timeframe": "5M",
|
||||
"total_windows": 1000,
|
||||
"total_trades": 204,
|
||||
"wins": 145,
|
||||
"losses": 59,
|
||||
"win_rate": 71.08,
|
||||
"total_pnl": 4756.79,
|
||||
"avg_pnl": 23.32,
|
||||
"total_fees": 168.6,
|
||||
"total_volume": 20340.62,
|
||||
"profit_factor": 1.81,
|
||||
"sharpe_ratio": 4.24,
|
||||
"max_drawdown": 715.02,
|
||||
"best_trade": 75.92,
|
||||
"worst_trade": -99.99,
|
||||
"max_consecutive_losses": 4
|
||||
},
|
||||
{
|
||||
"mode": "synthetic",
|
||||
"asset": "BTC",
|
||||
"timeframe": "15M",
|
||||
"total_windows": 1000,
|
||||
"total_trades": 204,
|
||||
"wins": 145,
|
||||
"losses": 59,
|
||||
"win_rate": 71.08,
|
||||
"total_pnl": 4601.16,
|
||||
"avg_pnl": 22.55,
|
||||
"total_fees": 324.22,
|
||||
"total_volume": 20340.62,
|
||||
"profit_factor": 1.78,
|
||||
"sharpe_ratio": 4.13,
|
||||
"max_drawdown": 727.9,
|
||||
"best_trade": 74.81,
|
||||
"worst_trade": -99.99,
|
||||
"max_consecutive_losses": 4
|
||||
},
|
||||
{
|
||||
"mode": "synthetic",
|
||||
"asset": "ETH",
|
||||
"timeframe": "5M",
|
||||
"total_windows": 1000,
|
||||
"total_trades": 157,
|
||||
"wins": 100,
|
||||
"losses": 57,
|
||||
"win_rate": 63.69,
|
||||
"total_pnl": 1671.74,
|
||||
"avg_pnl": 10.65,
|
||||
"total_fees": 116.56,
|
||||
"total_volume": 15652.7,
|
||||
"profit_factor": 1.29,
|
||||
"sharpe_ratio": 1.6,
|
||||
"max_drawdown": 532.2,
|
||||
"best_trade": 75.94,
|
||||
"worst_trade": -99.99,
|
||||
"max_consecutive_losses": 4
|
||||
},
|
||||
{
|
||||
"mode": "synthetic",
|
||||
"asset": "ETH",
|
||||
"timeframe": "15M",
|
||||
"total_windows": 1000,
|
||||
"total_trades": 157,
|
||||
"wins": 100,
|
||||
"losses": 57,
|
||||
"win_rate": 63.69,
|
||||
"total_pnl": 1564.15,
|
||||
"avg_pnl": 9.96,
|
||||
"total_fees": 224.15,
|
||||
"total_volume": 15652.7,
|
||||
"profit_factor": 1.28,
|
||||
"sharpe_ratio": 1.51,
|
||||
"max_drawdown": 537.54,
|
||||
"best_trade": 74.83,
|
||||
"worst_trade": -99.99,
|
||||
"max_consecutive_losses": 4
|
||||
},
|
||||
{
|
||||
"mode": "synthetic",
|
||||
"asset": "SOL",
|
||||
"timeframe": "5M",
|
||||
"total_windows": 1000,
|
||||
"total_trades": 115,
|
||||
"wins": 70,
|
||||
"losses": 45,
|
||||
"win_rate": 60.87,
|
||||
"total_pnl": 653.02,
|
||||
"avg_pnl": 5.68,
|
||||
"total_fees": 81.47,
|
||||
"total_volume": 11464.51,
|
||||
"profit_factor": 1.15,
|
||||
"sharpe_ratio": 0.72,
|
||||
"max_drawdown": 581.01,
|
||||
"best_trade": 75.94,
|
||||
"worst_trade": -100.0,
|
||||
"max_consecutive_losses": 4
|
||||
},
|
||||
{
|
||||
"mode": "synthetic",
|
||||
"asset": "SOL",
|
||||
"timeframe": "15M",
|
||||
"total_windows": 1000,
|
||||
"total_trades": 115,
|
||||
"wins": 70,
|
||||
"losses": 45,
|
||||
"win_rate": 60.87,
|
||||
"total_pnl": 577.82,
|
||||
"avg_pnl": 5.02,
|
||||
"total_fees": 156.67,
|
||||
"total_volume": 11464.51,
|
||||
"profit_factor": 1.13,
|
||||
"sharpe_ratio": 0.64,
|
||||
"max_drawdown": 595.86,
|
||||
"best_trade": 74.83,
|
||||
"worst_trade": -100.0,
|
||||
"max_consecutive_losses": 4
|
||||
}
|
||||
]
|
||||
20
config.toml
20
config.toml
@@ -7,10 +7,10 @@ starting_balance = 500.0
|
||||
|
||||
[strategy.temporal_arb]
|
||||
enabled = true
|
||||
min_price_move_pct = 0.03 # 낮춤: 0.03%만 움직여도 평가 (원래 0.15%)
|
||||
max_poly_entry_price = 0.65
|
||||
min_edge = 0.05 # 낮춤: 5% 엣지에서 진입 (원래 20%)
|
||||
exit_before_resolution_sec = 5
|
||||
min_price_move_pct = 0.08 # raised from 0.03 — filters low-quality signals
|
||||
max_poly_entry_price = 0.58 # lowered from 0.65 — lower entry = lower dynamic fees, higher edge
|
||||
min_edge = 0.03 # lowered from 0.05 — accurate dynamic fee model allows tighter threshold
|
||||
exit_before_resolution_sec = 8 # raised from 5 — more buffer for execution near resolution
|
||||
|
||||
[strategy.sum_to_one]
|
||||
enabled = true
|
||||
@@ -21,15 +21,17 @@ enabled = false
|
||||
spread_target = 0.04
|
||||
|
||||
[risk]
|
||||
max_position_per_market_usd = 5000
|
||||
max_total_exposure_usd = 20000
|
||||
max_daily_loss_usd = 2000
|
||||
kelly_fraction_cap = 0.25
|
||||
max_concurrent_positions = 6
|
||||
max_position_per_market_usd = 100 # lowered from 5000 — realistic for $500 account
|
||||
max_total_exposure_usd = 300 # lowered from 20000 — ~60% of starting balance
|
||||
max_daily_loss_usd = 50 # lowered from 2000 — 10% of starting balance
|
||||
kelly_fraction_cap = 0.20 # lowered from 0.25 — conservative for estimation uncertainty
|
||||
max_concurrent_positions = 4 # lowered from 6 — more focused capital allocation
|
||||
|
||||
[fees]
|
||||
taker_fee_5m = 0.0156
|
||||
taker_fee_15m = 0.03
|
||||
fee_rate = 0.045 # dynamic fee base rate
|
||||
fee_exponent = 1 # linear fee scaling
|
||||
|
||||
[exchange.binance]
|
||||
ws_url = "wss://stream.binance.com:9443/stream"
|
||||
|
||||
@@ -65,6 +65,8 @@ class RiskConfig:
|
||||
class FeesConfig:
|
||||
taker_fee_5m: float = 0.0156
|
||||
taker_fee_15m: float = 0.03
|
||||
fee_rate: float = 0.045
|
||||
fee_exponent: int = 1
|
||||
|
||||
def fee_for_timeframe(self, timeframe: str) -> float:
|
||||
"""Return the taker fee for a given timeframe string (e.g. '5M')."""
|
||||
@@ -76,6 +78,13 @@ class FeesConfig:
|
||||
raise ValueError(f"Unknown timeframe '{timeframe}'; expected one of {list(mapping)}")
|
||||
return mapping[timeframe]
|
||||
|
||||
def dynamic_fee(self, price: float, shares: int = 1) -> float:
|
||||
"""Compute Polymarket's dynamic taker fee for a given price and share count.
|
||||
|
||||
Formula: shares * price * fee_rate * (price * (1 - price)) ** fee_exponent
|
||||
"""
|
||||
return shares * price * self.fee_rate * (price * (1.0 - price)) ** self.fee_exponent
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BinanceConfig:
|
||||
|
||||
@@ -109,7 +109,8 @@ class TemporalArbStrategy:
|
||||
)
|
||||
|
||||
# 6. Edge calculation (after fees)
|
||||
taker_fee = self.fees.fee_for_timeframe(timeframe)
|
||||
# Use dynamic fee formula: fee per share / price = effective fee rate
|
||||
taker_fee = self.fees.dynamic_fee(poly_price, 1) / poly_price
|
||||
edge = estimated_prob - poly_price - taker_fee
|
||||
|
||||
if edge < self.arb.min_edge:
|
||||
@@ -118,7 +119,7 @@ class TemporalArbStrategy:
|
||||
# 7. Position sizing
|
||||
asset = Asset(symbol)
|
||||
size = self.calculate_kelly_size(
|
||||
edge=edge,
|
||||
estimated_prob=estimated_prob,
|
||||
price=poly_price,
|
||||
balance=self.balance,
|
||||
max_size=self.risk.max_position_per_market_usd,
|
||||
@@ -181,25 +182,25 @@ class TemporalArbStrategy:
|
||||
"""
|
||||
abs_change = abs(price_change_pct)
|
||||
|
||||
# Factor 1: Base probability from price magnitude
|
||||
# 0.15% → ~70%, 0.3% → ~82%, 0.5% → ~90%, 1.0%+ → ~95%
|
||||
base_prob = 0.55 + abs_change * 1.0 # 1.0 scaling factor
|
||||
base_prob = min(base_prob, 0.95)
|
||||
# Factor 1: Sigmoid base probability from price magnitude
|
||||
# k=18.0 steepness, inflection at 0.10% change
|
||||
# 0.03% → ~0.53, 0.10% → ~0.65, 0.20% → ~0.80, 0.50% → ~0.93
|
||||
k = 18.0
|
||||
threshold = 0.10
|
||||
sigmoid_val = 1.0 / (1.0 + math.exp(-k * (abs_change - threshold)))
|
||||
base_prob = 0.52 + sigmoid_val * 0.43 # maps [0,1] → [0.52, 0.95]
|
||||
|
||||
# Factor 2: Time decay — more time elapsed = more confirmation
|
||||
# If 80% of window has passed and price is still in this direction,
|
||||
# the probability of reversal is lower
|
||||
elapsed_fraction = max(0, 1.0 - (time_remaining / total_window_sec))
|
||||
# Sigmoid-like boost: ramps up in the last 40% of the window
|
||||
elapsed_fraction = 1.0 - (time_remaining / total_window_sec) if total_window_sec > 0 else 0.5
|
||||
# Ramps up in the last 40% of the window
|
||||
time_factor = 1.0 + 0.08 * max(0, elapsed_fraction - 0.6) / 0.4
|
||||
time_factor = min(time_factor, 1.08)
|
||||
|
||||
# Factor 3: Volatility / momentum strength
|
||||
# Very large moves (>0.5%) get extra confidence
|
||||
if abs_change > 0.5:
|
||||
vol_boost = min(0.05, (abs_change - 0.5) * 0.1)
|
||||
else:
|
||||
vol_boost = 0.0
|
||||
vol_boost = min(0.05, (abs_change - 0.5) * 0.1) if abs_change > 0.5 else 0.0
|
||||
|
||||
final_prob = base_prob * time_factor + vol_boost
|
||||
return min(0.95, max(0.50, final_prob))
|
||||
@@ -210,7 +211,7 @@ class TemporalArbStrategy:
|
||||
|
||||
def calculate_kelly_size(
|
||||
self,
|
||||
edge: float,
|
||||
estimated_prob: float,
|
||||
price: float,
|
||||
balance: float,
|
||||
max_size: float,
|
||||
@@ -224,7 +225,7 @@ class TemporalArbStrategy:
|
||||
return 0
|
||||
|
||||
b = (1.0 / price) - 1.0 # Payout odds
|
||||
p = edge + price # estimated_prob (edge = prob - price - fee)
|
||||
p = estimated_prob
|
||||
q = 1.0 - p
|
||||
|
||||
if b <= 0:
|
||||
|
||||
Reference in New Issue
Block a user