//+------------------------------------------------------------------+ //| XTSFORGE A-VWAP Studio - Command Interface v2 Test Sender | //| Sends one bridge command, waits for ACK and prints result status | //+------------------------------------------------------------------+ // Property information #property copyright "© 2026 XTSFORGE" #property version "1.00" #property description "Developer sample for XTSFORGE A-VWAP Studio." #property description "This script is not a trading system and does not place, modify or close trades." #property script_show_inputs // Constants static const string GV_PREFIX = "INV_AVWAP"; static const string DATA_PREFIX = "XTSF:AVWAP:DATA"; static const ushort AVWAP_CUSTOM_EVENT_ID = 1001; // Must match the indicator's AVWAP_CMD enum enum ENUM_XTSF_AVWAP_TEST_CMD { CMD_NONE = 0, CMD_ADD_ANCHOR = 1, CMD_DEL_ANCHOR = 2, CMD_CLEAR_ALL = 3, CMD_SET_DAILY_VWAP = 4, CMD_SET_DAILY_HISTORY = 5, CMD_SET_DAILY_BAND = 6, CMD_SET_ANCHOR_BAND = 7, CMD_SET_WEEKLY_VWAP = 8, CMD_SET_MONTHLY_VWAP = 9, CMD_SET_ALERTS = 10, CMD_SET_ANCHOR_GLOBAL_VISIBILITY = 11, CMD_SET_ANCHOR_LOCK = 12, CMD_SET_ANCHOR_SLOT_TIME = 13, CMD_DEL_ANCHOR_SLOT = 14, CMD_SET_ANCHOR_SLOT_VISIBILITY = 15, CMD_SET_ANCHOR_SLOT_COLOR = 16, CMD_SET_ANCHOR_SLOT_BAND = 17, CMD_SET_ANCHOR_SLOT_LABEL_MODE = 18, CMD_SET_ANCHOR_SLOT_LABEL_TEXT = 19, CMD_SET_WEEKLY_HISTORY = 20, CMD_SET_MONTHLY_HISTORY = 21, CMD_SET_ALERT_CHANNEL_TERMINAL = 22, CMD_SET_ALERT_CHANNEL_PUSH = 23, CMD_SET_ALERT_CHANNEL_EMAIL = 24, CMD_SET_ALERT_TARGET_DAILY = 25, CMD_SET_ALERT_TARGET_WEEKLY = 26, CMD_SET_ALERT_TARGET_MONTHLY = 27, CMD_SET_ALERT_TARGET_ANCHORED = 28, CMD_SET_ALERT_TARGET_DAILY_BANDS = 29, CMD_SET_ALERT_TARGET_ANCHORED_BANDS = 30, CMD_SET_ALERT_TRIGGER_CROSS = 31, CMD_SET_ALERT_TRIGGER_BREAK = 32, CMD_SET_ALERT_TRIGGER_TOUCH = 33, CMD_SET_ALERT_TRIGGER_BAND_TOUCH = 34, CMD_SET_ALERT_DIRECTION = 35, CMD_SET_ALERT_EVALUATION_MODE = 36, CMD_SET_ALERT_ONCE_PER_BAR = 37, CMD_SET_ALERT_COOLDOWN = 38 }; // Defines how command timestamps are resolved enum ENUM_XTSF_TIME_MODE { TIME_FROM_BAR_SHIFT = 0, TIME_EXPLICIT = 1 }; // Inputs input ENUM_XTSF_AVWAP_TEST_CMD Command = CMD_SET_ALERT_COOLDOWN; // Command to send input int Slot = 2; // 1=A1, 2=A2, ... input double Value = 60.0; // Numeric command value input color ColorValue = clrOrange; // Used by CMD_SET_ANCHOR_SLOT_COLOR input ENUM_XTSF_TIME_MODE TimeMode = TIME_FROM_BAR_SHIFT; // Timestamp source input int BarShift = 20; // Used when TimeMode = TIME_FROM_BAR_SHIFT input datetime ExplicitTime = D'2026.01.01 00:00'; // Used when TimeMode = TIME_EXPLICIT input string TextValue = "test"; // Used by CMD_SET_ANCHOR_SLOT_LABEL_TEXT input bool SendCustomEvent = true; // Trigger immediate processing input bool WaitForAck = true; // Wait for indicator ACK after sending input int AckTimeoutMs = 3000; // ACK wait timeout in milliseconds input int AckPollMs = 100; // ACK polling interval in milliseconds input bool PrintKeys = true; // Print written command keys input bool PrintAck = true; // Print ACK keys after command input bool PrintDataMetaCommandInfo = true; // Print command info from Data META if available // Builds the same bridge key base as the indicator string KeyBase() { return StringFormat("%s:%s:%d:%I64d", GV_PREFIX, _Symbol, (int)_Period, (long)ChartID()); } // Returns the CMD_SEQ global variable key string KeySeq() { return KeyBase() + ":CMD_SEQ"; } // Returns the CMD_CODE global variable key string KeyCode() { return KeyBase() + ":CMD_CODE"; } // Returns the CMD_TIME global variable key string KeyTime() { return KeyBase() + ":CMD_TIME"; } // Returns the CMD_VALUE global variable key string KeyValue() { return KeyBase() + ":CMD_VALUE"; } // Returns the CMD_SLOT global variable key string KeySlot() { return KeyBase() + ":CMD_SLOT"; } // Returns the CMD_TEXT hidden object name string KeyText() { return KeyBase() + ":CMD_TEXT"; } // Returns the CMD_ACK_SEQ global variable key string KeyAckSeq() { return KeyBase() + ":CMD_ACK_SEQ"; } // Returns the CMD_ACK_CODE global variable key string KeyAckCode() { return KeyBase() + ":CMD_ACK_CODE"; } // Returns the CMD_ACK_CHANGED global variable key string KeyAckChanged() { return KeyBase() + ":CMD_ACK_CHANGED"; } // Returns the CMD_ACK_TIME global variable key string KeyAckTime() { return KeyBase() + ":CMD_ACK_TIME"; } // Returns the CMD_ACK_ERROR_CODE global variable key string KeyAckErrorCode() { return KeyBase() + ":CMD_ACK_ERROR_CODE"; } // Returns the CMD_ACK_STATUS hidden object name string KeyAckStatus() { return KeyBase() + ":CMD_ACK_STATUS"; } // Returns the CMD_ACK_ERROR hidden object name string KeyAckError() { return KeyBase() + ":CMD_ACK_ERROR"; } // Builds the Data Interface base object name for the current chart string CurrentChartDataBase() { return StringFormat("%s:%I64d", DATA_PREFIX, (long)ChartID()); } // Returns the Data Interface META object name for the current chart string DataMetaObjectName() { return CurrentChartDataBase() + ":META"; } // Returns one payload chunk object name string ChunkObjectName(const string baseName, const int chunkIndex) { return StringFormat("%s:PART:%03d", baseName, chunkIndex + 1); } // Returns one raw object string payload string ReadRawObjectPayload(const string objectName) { if(ObjectFind(ChartID(), objectName) < 0) return ""; const string tooltipPayload = ObjectGetString(ChartID(), objectName, OBJPROP_TOOLTIP); if(tooltipPayload != "") return tooltipPayload; return ObjectGetString(ChartID(), objectName, OBJPROP_TEXT); } // Returns one semicolon-separated payload field value string PayloadFieldValue(const string payload, const string key) { const string needleStart = key + "="; int pos = StringFind(payload, needleStart, 0); if(pos < 0) { pos = StringFind(payload, ";" + needleStart, 0); if(pos >= 0) pos++; } if(pos < 0) return ""; const int valueStart = pos + StringLen(needleStart); int valueEnd = StringFind(payload, ";", valueStart); if(valueEnd < 0) valueEnd = StringLen(payload); return StringSubstr(payload, valueStart, valueEnd - valueStart); } // Reads one hidden data payload and rebuilds chunked payloads if needed string ReadPayload(const string objectName) { if(ObjectFind(ChartID(), objectName) < 0) return ""; const string rawPayload = ReadRawObjectPayload(objectName); if(PayloadFieldValue(rawPayload, "type") != "chunked") { return rawPayload; } const int chunkCount = (int)StringToInteger(PayloadFieldValue(rawPayload, "chunks")); string rebuilt = ""; for(int chunk=0; chunk