These scripts are the hotkeys I use in DAS Trader for active, discretionary day trading. They focus on fast, repeatable order entry with guard rails and are designed around a single active symbol at a time. I treat the ice breaker (Buy IB) entries as the first test of a trade thesis; while DAS allows multiple positions, these hotkeys assume one symbol and may behave unpredictably otherwise.
These scripts are designed for LONG positions only. Shorting is not supported.
Repository structure: the hotkeys/ folder contains the .das hotkey scripts, keymap.yaml defines the key bindings and metadata, and other scripts/ contains support scripts like the timer. A .das file is plain text you can paste into the DAS Trader Script Editor. The keymap.yaml can be compiled into a Hotkey.htk using the DAS Hotkey Tools VS Code extension, or you can skip the compiler and copy the scripts manually.
These scripts assume you have a primary montage window named Primary_OE (Primary Order Entry). If that montage name does not exist, many scripts will fail or behave incorrectly. You can reference my DAS Trader desktop and chart settings here: https://github.com/madiver/DASTraderConfig
Regardless of the method you choose, the timer script must be installed manually in DAS Trader under "Timer Event Scripts," and the chart script must be installed manually under the chart "Scripting" section (see details below). I also recommend adding ExecHotKey("Set Global Variables"); to your Desktop Load Scripts so globals are initialized every time DAS starts.
- Build or import hotkeys:
- Use the DAS Hotkey Tools VS Code extension to compile
keymap.yamlintoHotkey.htk, then load it in DAS, or - Copy/paste the
.dasscripts into DAS manually.
- Use the DAS Hotkey Tools VS Code extension to compile
- If you use the VS Code extension, set these settings first:
dasHotkeyTools.outputPath(required).dasHotkeyTools.liveAccountanddasHotkeyTools.simulatedAccountfor%%LIVE%%/%%SIMULATED%%substitution.- Optional:
dasHotkeyTools.placeholders.failOnMissingto block builds when placeholders are unresolved.
- Ensure your montage is named
Primary_OE, the timer scriptother scripts/timer.dasis installed under Timer Event Scripts, and the chart scriptother scripts/chart_1m.dasis installed as a 1-minute Chart Script. - Run
switch_to_sim.dasorswitch_to_live.dasto set the montage account and filters. - Run
set_global_variables.dasto initialize globals. - Use
show_config.dasto confirm account mode, defaults, and guard states.
Important: update $TRSIM and $LIVEACT in hotkeys/set_global_variables.das with your actual account identifiers if they are not already populated (they are shown in the config display for reference). $applyLiveGuardsToSim controls whether the live-only guards (hijack, rehab) also apply in SIM; it defaults to 1. Set it to 0 if you want those guards to run only in LIVE. Also verify that any %%SIMULATED%% and %%LIVE%% placeholders have been replaced in the SIM/LIVE switch scripts (the VS Code extension handles this during build; if you copy scripts manually, you must replace them yourself).
By default ($useTimerArming = 1), a buy hotkey sends the limit order, records entry context, and returns immediately. A timer-driven handler then waits for a fill and arms stop loss / take profit on subsequent 1-second ticks. If position size increases on later ticks, the handler cancels existing sell orders, re-arms the stop, and only re-arms TP when the TP reset conditions are met. If no fill appears within $entryMaxTicks, the handler cancels the working buy order and clears the pending state. If $useTimerArming = 0, the buy hotkey polls for a fill up to $maxPolls * $pollMs; if nothing fills, the order is canceled and the script exits without arming any protection. If a partial fill meets $minFillShares, the remainder is canceled (when enabled) and the scripts proceed as if the trade is active, using the average entry price for subsequent calculations.
Stops are placed as STOP/SLP orders routed to the broker, which means the stop logic lives on the broker side once submitted. Take-profit is implemented with DAS alerts that fire when price reaches the configured R target and then execute the Take Profit hotkey; those alerts are client-side and require DAS to remain open with live data.
All core settings live in hotkeys/set_global_variables.das. If you change a
value, rerun "Set Global Variables" so the globals refresh in DAS.
Variables by category:
Runtime counters and modes:
$oneSecondScriptCnt: internal counter used byother scripts/timer.das.$rehab: enables rehab mode to block scale-ins and larger entries in LIVE (and SIM when$applyLiveGuardsToSim = 1).$HIJACKED_LOCKED: runtime lock set when hijack protection triggers.$singlePositionSymbol: runtime symbol tracked by the single-position guard.$trade_ok: runtime flag set byCheck Global Guardsfor buy hotkeys.$testMode: when set to 1, buy hotkeys exit after non-market guards (no order sent).
Feature toggles and entry guards:
$useSlippageMargin: enables the stop-vs-bid margin check in buy scripts.$slipTicksMin: minimum tick margin for slippage checks.$slipSpreadFrac: fraction of spread added to the slippage margin.$acceptPartial: allows partial fills within the polling window.$minFillShares: minimum shares to accept when partial fills are allowed.$cancelRemainderOnPartial: cancels the unfilled remainder before arming stops.$usePerTradeRiskCap: blocks entries if projected net risk to the planned stop exceeds$riskCapDollars.$useSpreadCheck: enables spread-vs-R safety checks before entries.$pegToBid: when enabled, BE limit sells can peg to bid instead of AvgCost.$hijackProtection: enables the position-size hijack backstop (LIVE, and SIM when$applyLiveGuardsToSim = 1).$applyLiveGuardsToSim: when set to 1 (default), apply hijack and rehab guards in SIM.$singlePositionGuard: when set to 1 (default), block new entries on a different symbol (script-tracked).$useAutoStop: toggles auto stop placement.$useTakeProfit: toggles take-profit alerts/executor behavior.$resetStopOnCancel: re-arms the stop aftercancel_all.dasif long.$useTimerArming: uses timer-based entry arming (1) or inline polling (0).
Risk and execution:
$entryOffset: bid/ask offset for the "plus" entry scripts.$exitOffset: bid offset for Bid- sells and non-dynamic stop-limit offsets.$orderRoute: limit order route for entries/exits (buys/sells/TP/BE). Default isARCAL.FREELis the free route for ST Global Market/Open Ocean.$stopLossTrigger: fixed 1R risk per share (used when dynamic stops are off).$takeProfitFactor: R multiple for take-profit alerts.$takeProfitSize: fraction of the position to sell on a TP trigger.$takeProfitSizeRehab: TP fraction when rehab is active (LIVE; SIM when$applyLiveGuardsToSim = 1).
Dynamic stop settings (buy_ib only):
$stopMode: selects stop logic ("FIXED", "DYNAMIC", or "STRUCTURED").$dynamicStop: enables spread-based R for buy IB entries.$dynamicStopMult: multiplier for the spread-based R.$dynamicStopActive: runtime flag set when a dynamic trade is active.$dynamicStopR: stored dynamic R used for stops and TP during the trade.
Structured stop settings (buy_ib only):
$structuredMaxLookback: max bars to scan for the impulse.$structuredMaxPullback: max bars to evaluate the pullback.$structuredBuffer: stop buffer below the rejection/pullback low.$structuredMaxStop: max allowed stop distance (R).$structuredMinImpulse: minimum impulse body size.$structuredMinClearance: minimum clearance above stop.$structuredMicroTolPct: micro pullback tolerance (fraction of impulse body).$structuredMicroTolMax: cap for micro tolerance (absolute).$structuredMicroExt: max extension above impulse high before abort.$structuredOk: last structured validation result (1=pass, 0=fail).$structuredReason: last structured failure code.$structuredReasonText: last structured failure reason string.$structuredType:"MICROPB"or"STDPB"on pass.$structuredStop: last structured stop price.$structuredR: last structured R distance.$structuredSymbol: symbol used for the last structured check.
Account tokens:
$TRSIM: SIM account identifier.$LIVEACT: LIVE account identifier.
Sizing and risk limits:
$qtyMult: position size multiplier.$maxPositionSize: maximum total position size in shares.$riskCapDollars: maximum projected net risk per trade in dollars.
Order fill polling:
$pollMs: polling interval in milliseconds.$maxPolls: maximum number of polls before canceling an unfilled order. These are used when$useTimerArming = 0.
Timer-based entry arming (runtime):
$entryPending,$entryStage,$entryTicks,$entryMaxTicks: timer state and timeout for arming stops/TP after fills. When the timeout is reached, the handler cancels the working buy order.$entrySymbol,$entryPosBefore,$entryAvgBefore,$entryScaleIn,$entryDynR: captured entry context used by the timer handler.$entryRefPx: entry reference price used as a fallback for stop placement when AvgCost lags.$entryWatch,$entryLastPos: track position size changes so the handler can re-arm stops/TP when size increases.
Defaults are pulled from hotkeys/set_global_variables.das and reflect the
baseline values when you run "Set Global Variables."
| Category | Variable | Default |
|---|---|---|
| Runtime | $oneSecondScriptCnt |
0 |
| Runtime | $rehab |
0 |
| Runtime | $useTimerArming |
1 |
| Runtime | $timerMode |
1 |
| Runtime | $entryPending |
0 |
| Runtime | $entryStage |
0 |
| Runtime | $entryTicks |
0 |
| Runtime | $entryMaxTicks |
10 |
| Runtime | $entryPosBefore |
0 |
| Runtime | $entryAvgBefore |
0 |
| Runtime | $entryScaleIn |
0 |
| Runtime | $entryDynR |
0 |
| Runtime | $entrySymbol |
"" |
| Runtime | $tpSymbol |
"" |
| Runtime | $entryRefPx |
0 |
| Runtime | $HIJACKED_LOCKED |
0 |
| Runtime | $singlePositionSymbol |
"" |
| Runtime | $trade_ok |
1 |
| Runtime | $testMode |
0 |
| Runtime | $entryWatch |
0 |
| Runtime | $entryLastPos |
0 |
| Toggles | $useSlippageMargin |
1 |
| Toggles | $slipTicksMin |
2 |
| Toggles | $slipSpreadFrac |
0.25 |
| Toggles | $acceptPartial |
1 |
| Toggles | $minFillShares |
1 |
| Toggles | $cancelRemainderOnPartial |
1 |
| Toggles | $usePerTradeRiskCap |
1 |
| Toggles | $useSpreadCheck |
1 |
| Toggles | $pegToBid |
0 |
| Toggles | $hijackProtection |
1 |
| Toggles | $applyLiveGuardsToSim |
1 |
| Toggles | $singlePositionGuard |
1 |
| Toggles | $useAutoStop |
"Yes" |
| Toggles | $useTakeProfit |
"Yes" |
| Toggles | $resetStopOnCancel |
"Yes" |
| Risk | $entryOffset |
0.03 |
| Risk | $exitOffset |
0.10 |
| Risk | $orderRoute |
"ARCAL" |
| Risk | $stopLossTrigger |
0.10 |
| Risk | $takeProfitFactor |
1.0 |
| Risk | $takeProfitSize |
0.25 |
| Risk | $takeProfitSizeRehab |
0.50 |
| Dynamic stop | $dynamicStop |
0 |
| Dynamic stop | $stopMode |
"FIXED" |
| Dynamic stop | $dynamicStopMult |
2 |
| Dynamic stop | $dynamicStopActive |
0 |
| Dynamic stop | $dynamicStopR |
0 |
| Structured stop | $structuredMaxLookback |
5 |
| Structured stop | $structuredMaxPullback |
3 |
| Structured stop | $structuredBuffer |
0.01 |
| Structured stop | $structuredMaxStop |
0.40 |
| Structured stop | $structuredMinImpulse |
0.15 |
| Structured stop | $structuredMinClearance |
0.05 |
| Structured stop | $structuredMicroTolPct |
0.25 |
| Structured stop | $structuredMicroTolMax |
0.10 |
| Structured stop | $structuredMicroExt |
0.10 |
| Structured stop | $structuredOk |
0 |
| Structured stop | $structuredReason |
0 |
| Structured stop | $structuredReasonText |
"" |
| Structured stop | $structuredType |
"" |
| Structured stop | $structuredStop |
0 |
| Structured stop | $structuredR |
0 |
| Structured stop | $structuredSymbol |
"" |
| Accounts | $TRSIM |
"%%SIMULATED%%" |
| Accounts | $LIVEACT |
"%%LIVE%%" |
| Sizing | $qtyMult |
6 |
| Sizing | $maxPositionSize |
500 |
| Limits | $riskCapDollars |
100.00 |
| Polling | $pollMs |
100 |
| Polling | $maxPolls |
20 |
Test mode: set $testMode = 1 to run buy hotkeys through non-market guard
checks only (no order is sent). Use this for off-hours validation of lock
states and guard logic. Test mode and the test toggles are SIM-only.
Use "Show Config" to view the current runtime values.
Key bindings are sourced from keymap.yaml. I primarily use these with a
Stream Deck, so bindings can be arbitrarily long because the Stream Deck lets
me send complex keystrokes with a single button press. If you are using a
keyboard, you will almost certainly want to modify the bindings to your
liking. "Unbound" means the script is not assigned to a hotkey in the current
map, and those entries are primarily intended for internal use by other
scripts rather than direct invocation.
| Key binding | Script | Description |
|---|---|---|
Ctrl+Shift+Q |
hotkeys/cancel_all.das |
Cancel orders, clear TP alerts, re-arm stops. |
Alt+Ctrl+Q |
hotkeys/gtfo.das |
Emergency exit: cancel orders, sell full at bid-0.50. |
Ctrl+, |
hotkeys/set_global_variables.das |
Load default globals. |
Alt+Ctrl+S |
hotkeys/switch_to_sim.das |
Switch montage and filters to SIM. |
Alt+Ctrl+L |
hotkeys/switch_to_live.das |
Switch montage and filters to LIVE. |
Alt+Ctrl+. |
hotkeys/show_config.das |
Show current globals, account mode, guard states. |
| Unbound | hotkeys/check_global_guards.das |
Run guard checks and set $trade_ok. |
| Unbound | hotkeys/cancel_all_no_stops.das |
Cancel orders and TP alerts without re-arming stops. |
Alt+Ctrl+Shift+Win+0 |
hotkeys/buy_mib_bid_plus_sl.das |
Micro ice breaker buy at bid + offset with auto stop/TP. |
Ctrl+Shift+1 |
hotkeys/buy_ib_bid_plus_sl.das |
Ice breaker buy at bid + offset with auto stop/TP. |
Ctrl+Shift+2 |
hotkeys/buy_25_bid_plus_sl.das |
Half-clip buy at bid + offset with auto stop/TP. |
Ctrl+Shift+3 |
hotkeys/buy_50_bid_plus_sl.das |
Full-clip buy at bid + offset with auto stop/TP. |
Alt+Ctrl+0 |
hotkeys/buy_mib_bid_sl.das |
Micro ice breaker buy at bid with auto stop/TP. |
Alt+Ctrl+1 |
hotkeys/buy_ib_bid_sl.das |
Ice breaker buy at bid with auto stop/TP. |
Alt+Ctrl+2 |
hotkeys/buy_25_bid_sl.das |
Half-clip buy at bid with auto stop/TP. |
Alt+Ctrl+3 |
hotkeys/buy_50_bid_sl.das |
Full-clip buy at bid with auto stop/TP. |
Alt+Shift+0 |
hotkeys/buy_mib_ask_sl.das |
Micro ice breaker buy at ask with auto stop/TP. |
Alt+Shift+1 |
hotkeys/buy_ib_ask_sl.das |
Ice breaker buy at ask with auto stop/TP. |
Alt+Shift+2 |
hotkeys/buy_25_ask_sl.das |
Half-clip buy at ask with auto stop/TP. |
Alt+Shift+3 |
hotkeys/buy_50_ask_sl.das |
Full-clip buy at ask with auto stop/TP. |
Alt+Ctrl+Shift+0 |
hotkeys/buy_mib_ask_plus_sl.das |
Micro ice breaker buy at ask + offset with auto stop/TP. |
Alt+Ctrl+Shift+1 |
hotkeys/buy_ib_ask_plus_sl.das |
Ice breaker buy at ask + offset with auto stop/TP. |
Alt+Ctrl+Shift+2 |
hotkeys/buy_25_ask_plus_sl.das |
Half-clip buy at ask + offset with auto stop/TP. |
Alt+Ctrl+Shift+3 |
hotkeys/buy_50_ask_plus_sl.das |
Full-clip buy at ask + offset with auto stop/TP. |
Ctrl+A |
hotkeys/sell_1_1_ask.das |
Sell full position at ask. |
Ctrl+S |
hotkeys/sell_1_2_ask.das |
Sell half position at ask. |
Ctrl+D |
hotkeys/sell_1_4_ask.das |
Sell quarter position at ask. |
Ctrl+Z |
hotkeys/sell_1_1_bid.das |
Sell full position at bid minus offset. |
Ctrl+X |
hotkeys/sell_1_2_bid.das |
Sell half position at bid minus offset. |
Ctrl+C |
hotkeys/sell_1_4_bid.das |
Sell quarter position at bid minus offset. |
Ctrl+Shift+S |
hotkeys/set_auto_stop.das |
Place 1R stop-limit for full position. |
Ctrl+Shift+B |
hotkeys/set_auto_stop_be_1_1.das |
Breakeven stop/limit for full position. |
| Unbound | hotkeys/set_auto_stop_be_scale_1_1.das |
Scale-in BE stop/limit for full position. |
Alt+Ctrl+Win+- |
hotkeys/set_0_10_stop.das |
Set 1R stop-loss trigger to $0.10. |
Alt+Ctrl+Win+[ |
hotkeys/set_0_20_stop.das |
Set 1R stop-loss trigger to $0.20. |
| Unbound | hotkeys/structured_stop_validate.das |
Structured stop validation (internal). |
Alt+Ctrl+B |
hotkeys/set_auto_stop_be_1_2.das |
Breakeven stop/limit for half position. |
Ctrl+Shift+T |
hotkeys/set_take_profit.das |
Create R-based take-profit alert. |
| Unbound | hotkeys/take_profit_executor.das |
Execute TP partial when alert fires. |
Alt+Ctrl+Win+1 |
hotkeys/select_primary_order_entry.das |
Focus the Primary_OE montage. |
Alt+Ctrl+Win+P |
hotkeys/toggle_position_window.das |
Toggle Positions windows AlwaysOnTop. |
Alt+Ctrl+Win+] |
hotkeys/toggle_stp_feature.das |
Toggle auto stop-loss feature. |
Alt+Ctrl+Win+/ |
hotkeys/toggle_tp_feature.das |
Toggle take-profit alerts. |
Alt+Ctrl+Win+' |
hotkeys/toggle_spread_check_feature.das |
Toggle spread safety guard. |
Ctrl+Alt+Win+D |
hotkeys/enable_dynamic_stop_mode.das |
Enable dynamic stop mode (Buy IB/MIB only). |
Ctrl+Alt+Win+F |
hotkeys/enable_standard_stop_mode.das |
Enable fixed stop mode. |
Alt+Ctrl+Win+S |
hotkeys/enable_structured_stop_mode.das |
Enable structured stop mode (IB/MIB only). |
Alt+Ctrl+Win+G |
hotkeys/toggle_apply_live_guards_to_sim.das |
Toggle live-only guards in SIM. |
Alt+Ctrl+Win+2 |
hotkeys/set_order_route_arcal.das |
Set limit order route to ARCAL. |
Alt+Ctrl+Win+3 |
hotkeys/set_order_route_freel.das |
Set limit order route to FREEL (free route for ST Global Market/Open Ocean). |
Alt+Ctrl+Win+M |
hotkeys/toggle_single_position_guard.das |
Toggle single-symbol entry guard. |
Alt+Ctrl+Win+T |
hotkeys/toggle_test_mode.das |
Toggle test mode (no order sends). |
Alt+Ctrl+Shift+Win+2 |
hotkeys/toggle_test_hijack_guard.das |
Toggle hijack guard test. |
Alt+Ctrl+Shift+Win+3 |
hotkeys/toggle_test_single_position_guard.das |
Toggle single-position guard test. |
Alt+Ctrl+Shift+Win+4 |
hotkeys/toggle_test_pending_entry_guard.das |
Toggle pending-entry guard test. |
Alt+Ctrl+Shift+Win+5 |
hotkeys/toggle_test_max_position_guard.das |
Toggle max-position guard test. |
Alt+Ctrl+Win+H |
hotkeys/enable_rehab_mode.das |
Toggle rehab mode (YES to disable). |
| Unbound | hotkeys/hijack_exit.das |
Hijack guard exit/lock enforcement (timer-only). |
| Unbound | hotkeys/timer_entry_handler.das |
Timer-driven stop/TP arming for entries. |
Sizing philosophy: start small to probe the trade, add only when it is working, and cap exposure with hard limits. Base sizing is a 50-share clip multiplied by $qtyMult. Buy 25 uses half of that clip, Buy 50 uses the full clip, Buy IB (ice breaker) uses roughly one quarter of the 50-share clip, and Buy MIB (micro ice breaker) uses roughly one twentieth of the 50-share clip (all rounded to 5-share lots). This keeps the sizing deterministic and proportional to your 1R risk. In rehab mode ($rehab = 1), trading is restricted to ice breaker entries and scale-ins are blocked in LIVE and SIM when $applyLiveGuardsToSim = 1.
Rehab mode is a safety throttle for live trading. When enabled ($rehab = 1), the scripts block scale-ins and prevent larger clip entries in live accounts, forcing you to trade only ice breaker size while you reset discipline or reduce risk after a drawdown. The same restrictions apply in SIM when $applyLiveGuardsToSim = 1 (default). You can set the default by changing $rehab in hotkeys/set_global_variables.das and re-running "Set Global Variables" (or restarting DAS), or toggle it for the current session using the Toggle Rehab Mode hotkey. Disabling rehab requires typing YES to confirm.
- Buy MIB scripts are the micro ice breaker entries. They size at roughly one
twentieth of the 50-share base clip after applying
$qtyMultand then round to 5-share lots with a 5-share minimum. In formula form:mibShares = round5(50 * $qtyMult / 20). MIB entries are treated like IB for dynamic/structured gating. - Buy IB scripts are the ice breaker entries. They size at roughly one quarter
of the 50-share base clip after applying
$qtyMultand then round to 5-share lots with a 5-share minimum. In formula form:ibShares = round5(50 * $qtyMult * 0.25). - Buy 25 uses
25 * $qtyMultshares; Buy 50 uses50 * $qtyMultshares. These are the base clip sizes for normal entries and adds. - All buy scripts enforce
$maxPositionSizeand$riskCapDollarsbefore sending an order. - "Plus" versions use
$entryOffsetto price above bid or ask.
Scaling in means adding shares after an initial entry once the trade is working and risk is reduced. These scripts only allow scale-ins when the existing position has moved at least 1R in your favor.
- The profit gate is measured as
BID - AvgCost >= Rfor longs. R is$stopLossTriggerfor normal trades. Buy IB uses dynamic R when enabled; buy_25/buy_50 use dynamic R only whendynamicStop = 1anddynamicStopActive = 1, otherwise$stopLossTrigger. - When adding to a position, the scripts arm the scale-in BE stop
(
Set Auto Stop BE Scale 1/1) so the combined position is protected. - Rehab mode (
$rehab = 1) blocks scale-ins entirely in LIVE and SIM when$applyLiveGuardsToSim = 1. - Entries are rejected if
$maxPositionSizeor the net risk to the planned stop would exceed$riskCapDollarsafter the add. - Spread safety checks and slippage margins guard entries before an order is sent.
When $singlePositionGuard = 1 (default), buy hotkeys only allow one active
symbol at a time. If $singlePositionSymbol is set, new entries on a different
symbol are blocked. The guard also blocks when $entryPending = 1 for another
symbol (timer staging), so you cannot start a second entry while a buy is still
waiting to fill. The pending-entry block clears when the pending entry times
out/cancels, or when the original symbol is back in Primary_OE and the position
is flat. If you switch the montage to a different symbol while an entry is
pending, the timer cancels the working buy and clears the pending state to
avoid unprotected fills.
Sell hotkeys are designed for manual partials and exits on long positions. They cancel existing orders for the symbol to avoid conflicting routes, then send a limit order. Partial sell hotkeys re-arm stops/TP after a full fill so the remaining position stays protected.
- Ask sells place a limit order at the current Ask (price first).
- Bid- sells place a limit order at Bid minus
$exitOffset(fill priority). - Bid- prices are snapped to valid tick sizes and clamped to non-negative values.
- After a full fill on partial sells, the scripts re-arm
Set Auto StopandSet Take Profitif those features are enabled.
Break-even (BE) scripts move protection to breakeven once a position is working.
They do not check $useAutoStop, so BE hotkeys (and TP-driven BE adjustments)
still work even when automatic stops are disabled.
- For the standard BE scripts (1/1 and 1/2), if price has not reached the BE
trigger (currently
$0.03above avg cost), they place a BE limit sell. - Once price clears the trigger, those scripts place a stop-limit above breakeven (stop at avg + offset, limit at avg).
- The scale-in BE script uses a stop-limit even before the trigger (stop at avg cost), then moves to a stop above BE once the trigger is cleared.
- Variants protect the full position or a fraction (1/1, 1/2, or scale-in
versions), and they honor
$useAutoStop.
Set Auto Stop places a stop-limit order at 1R below avg cost for long
positions. R is $stopLossTrigger when dynamic stops are inactive. The script
uses the montage average cost when available and falls back to the entry
reference price ($entryRefPx) or last price if AvgCost is lagging. It cancels
existing sell orders for the symbol before placing the new stop, except when
invoked in timer mode ($timerMode) where cancels are skipped.
When dynamic stops are inactive, the stop-limit offset uses $exitOffset. The
order is snapped to valid tick sizes and sent as a STOP/SLP order.
Dynamic stops are only supported for Buy IB/MIB entries due to the
added risk of spread-based sizing, and they only activate when
$dynamicStop == 1. They are intended for parabolic movers where spreads and
intraday swings expand sharply as price accelerates.
The stop engine now uses $stopMode ("FIXED", "DYNAMIC", or "STRUCTURED") as
the selector; enable_dynamic_stop_mode.das and
enable_standard_stop_mode.das keep $stopMode in sync with $dynamicStop.
STRUCTURED uses the structured stop price ($structuredStop) and distance
($structuredR) when present.
- R is computed once at order send:
R = spread * $dynamicStopMult. - R is fixed for the life of the trade and reused for scale-ins.
- The stop trigger uses the dynamic R.
- Adaptive stop-limit offsets are used only when a dynamic stop is active; the offset is derived from the live spread at stop placement and capped by an internal maximum.
- When
$dynamicStop = 1, initial entries must use Buy IB;buy_25_*andbuy_50_*only allow scale-ins. - Dynamic state is cleared when flat by the timer script.
Structured stops are enabled when $stopMode = "STRUCTURED"
and require the Chart_1m window running other scripts/chart_1m.das so live
candle values are available. The structured validator computes a stop price
from a 1-minute impulse/pullback pattern and stores it in $structuredStop.
- Only Buy IB/MIB entries can open a new position in structured mode.
- Buy 25/50 hotkeys are allowed only for scale-ins (and require
$structuredR). - If structured data is missing at entry time, the entry is aborted.
- The stop engine uses
$structuredStop, and TP distance uses$structuredR. Mechanics summary: - The validator first looks for a bullish impulse on the prior 1-minute bar
(bar -1), requiring a green candle with body >=
$structuredMinImpulseand dominance vs the previous bar (body > bar -2 body). - If a valid impulse is found, it attempts a MICROPB pullback using live
$CURR_*values: price must not dip below the impulse high by more than the bounded tolerance ($structuredMicroTolPctcapped by$structuredMicroTolMax) and must not extend above the impulse high by more than$structuredMicroExt. The stop is anchored to the live rejection low minus$structuredBuffer. - If the micro conditions fail, the validator falls back to a STDPB pullback:
it scans back up to
$structuredMaxLookbackbars for a bullish impulse that dominates the next$structuredMaxPullbackbars, then sets the stop below the lowest pullback low (minus$structuredBuffer). - The candidate stop is rejected if price is already below it, clearance is
below
$structuredMinClearance, or the stop distance exceeds$structuredMaxStop.
Take-profit is implemented as a DAS price alert that triggers an execution hotkey. It is not a resting broker-side order.
Set Take Profit builds the alert using an R-based distance:
- Distance is
R * $takeProfitFactor. - R is
$stopLossTriggerfor normal trades or dynamic R when active. - The alert watches last sale and fires above the target for longs.
When the alert fires, Take Profit Executor:
- Cancels existing sell orders for the symbol.
- Sells a partial position sized by
$takeProfitSize(or$takeProfitSizeRehabwhen rehab is active in LIVE, and in SIM when$applyLiveGuardsToSim = 1). - Re-arms stops and (if needed) re-establishes the TP alert after the fill.
Stale take-profit alerts are cleaned up by the timer script a few seconds after the position is flat.
These controls help prevent low-quality fills and oversized risk.
- Spread checks: reject entries when spread is too large relative to R
(
$useSpreadCheck). - Slippage margin: requires the planned stop to sit below bid by a minimum
tick/spread buffer (
$useSlippageMargin,$slipTicksMin,$slipSpreadFrac). - Hijack protection: if the position size exceeds
$maxPositionSize(LIVE, and SIM when$applyLiveGuardsToSim = 1), the timer triggers GTFO, locks all montage order buttons, and sets$HIJACKED_LOCKEDto block new buys. The lock clears only after restarting DAS or re-runningSet Global Variables, and montage unlock is manual. - Single-position guard: when
$singlePositionGuard = 1, buy hotkeys block entries on a different symbol once a position is tracked. This is script-tracked using the Primary_OE montage; if you close a position while on another symbol, the lock clears when you return to the original symbol or re-runSet Global Variables. Positions opened or closed outside the hotkeys may not be detected until the montage returns to the active symbol. - Per-trade risk cap: blocks entries when projected risk exceeds
$riskCapDollars($usePerTradeRiskCap).
SIM vs LIVE: hijack protection and rehab gating apply in LIVE and SIM when
$applyLiveGuardsToSim = 1 (default). Set $applyLiveGuardsToSim = 0 to keep
those guards live-only. All other guard rails apply in both SIM and LIVE.
This is a strict discipline backstop. It is enabled by default via
$hijackProtection = 1 and continuously compares your position size to
$maxPositionSize using the Primary_OE montage. It applies to LIVE and to
SIM when $applyLiveGuardsToSim = 1 (default).
If the timer detects a position larger than $maxPositionSize, it:
- Triggers
GTFOto flatten. - Locks all montage order buttons via
LockAllMontage Lock. - Sets
$HIJACKED_LOCKEDto block new buys. - Plays a brief voice alert.
Reset behavior:
$HIJACKED_LOCKEDclears only after restarting DAS or re-runningSet Global Variables.- Montage lock must be manually cleared (UI lock icon or
LockAllMontage Unlock).
other scripts/timer.das does three things:
- Enforces hijack protection on position size (LIVE, and SIM when
$applyLiveGuardsToSim = 1). - Runs
Timer Entry Handlereach tick to arm stops/TP after fills when$useTimerArming = 1. - Clears take-profit alerts and dynamic/structured stop state when flat.
Installation: add this script to DAS Trader's timer so it runs every second.
It is not installed automatically by the hotkey build. Ensure
hotkeys/timer_entry_handler.das is included in your keymap because the timer
calls it via ExecHotkey.
other scripts/chart_1m.das captures the current 1-minute candle's live values
and exposes them as globals for other scripts. It is not installed automatically
by the hotkey build.
Installation: add this script to DAS Trader's chart "Scripting" section and bind it to a 1-minute chart that follows your active symbol (only one chart should run it at a time).
These scripts handle configuration, safety toggles, and convenience actions. The SIM/LIVE mode hotkeys read the account from the Primary_OE montage and set your account context accordingly so your entries and guards apply to the correct account. Use them at the start of a session (and when switching environments) to avoid sending orders to the wrong account.
Safety toggles:
toggle_stp_feature.dasandtoggle_tp_feature.dasenable/disable auto stops and take-profit alerts.toggle_spread_check_feature.dasenables/disables the spread safety guard.enable_dynamic_stop_mode.dassets dynamic R for Buy IB/MIB entries (and disables fixed mode).enable_standard_stop_mode.dassets fixed R stops and disables dynamic mode.enable_structured_stop_mode.dassets structured stop mode (IB/MIB only).toggle_apply_live_guards_to_sim.dastoggles whether live-only guards also apply in SIM ($applyLiveGuardsToSim).set_order_route_arcal.dassets$orderRoutetoARCAL.set_order_route_freel.dassets$orderRoutetoFREEL(free route for ST Global Market/Open Ocean).toggle_single_position_guard.dastoggles the single-position guard ($singlePositionGuard).toggle_test_mode.dastoggles test mode ($testMode) for off-hours guard checks.toggle_test_hijack_guard.dastoggles a hijack-guard test by loweringmaxPositionSize(requires$testMode = 1and an open position).toggle_test_single_position_guard.dastoggles a simulated active symbol for the single-position guard (requires$testMode = 1).toggle_test_pending_entry_guard.dastoggles a simulated pending entry for the guard (requires$testMode = 1and a flat position).toggle_test_max_position_guard.dastoggles a max-position guard test by settingmaxPositionSizeto the current position (requires$testMode = 1and an open position).enable_rehab_mode.dastoggles rehab mode on/off; disabling requires typingYES.
Account and session:
set_global_variables.dasrefreshes all global settings.switch_to_sim.dasandswitch_to_live.dasset the Primary_OE account.
Order control:
cancel_all.dascancels working orders and re-arms stops;cancel_all_no_stops.dascancels without re-arming.gtfo.dasattempts an aggressive limit exit for the full position.
UI and convenience:
show_config.dasdisplays current globals and account mode.select_primary_order_entry.dasfocuses the Primary_OE montage.toggle_position_window.dastoggles AlwaysOnTop for the DAS Position windows.
Fast entry and exit are important to my strategy, so reducing latency matters.
These scripts still introduce small delays because they wait to confirm fills
and enforce guard rails. With $useTimerArming = 1, entry hotkeys return
immediately, but stops/TP are armed on the next timer tick, so there can be a
brief unprotected window (up to ~1 second plus DAS processing). Set
$useTimerArming = 0 and tune $pollMs and $maxPolls if you prefer inline
polling and more immediate protection.
When $useTimerArming = 1, the timer handler waits for a position to appear
before arming stops/TP. If position size increases on later ticks, the handler
cancels existing sell orders, re-arms the stop, and only re-arms TP when the TP
reset conditions are met. If no fill appears within $entryMaxTicks, the handler
cancels the working buy order and clears pending state. When $useTimerArming = 0,
buy orders poll for fills and can accept partials based on $acceptPartial and
$minFillShares. If the fill criteria are not met in time, the order is canceled
and the script exits without arming stops.
Both modes intentionally wait for a fill before arming protection to avoid mismatched AvgCost. Bypassing the fill check risks placing protection against a position that does not exist yet, or against a partial fill that later changes your average cost. The fill check avoids racing conditions between the order, the montage position, and AvgCost updates.
Current stop scripts use STOP route and SLP (stop-limit) orders. DAS behavior for stops outside regular hours can vary by broker. If your broker supports LIMITP (price-triggered limit orders outside regular hours), it can be an important safety feature because it allows stop logic to function in the pre-market and after-hours session, where volatility can be high and liquidity thin. This is especially relevant for gap moves, news catalysts, and parabolic setups that can reverse quickly outside the main session.
These scripts submit STOP/SLP orders; whether those behave as LIMITP in pre-market or after-hours depends on your broker and DAS configuration. If you trade outside regular hours, verify your broker's behavior and consider a LIMITP-based workflow tailored to your setup.