NexusFi: Find Your Edge


Home Menu

 





Tradestation Chart Setup


Discussion in TradeStation

Updated
    1. trending_up 105 views
    2. thumb_up 0 thanks given
    3. group 3 followers
    1. forum 0 posts
    2. attach_file 0 attachments




 
Search this Thread
  #1 (permalink)
 Duviuvi 
Sydney NSW
 
Experience: Intermediate
Platform: TradeStation
Trading: Futures
Posts: 2 since Oct 2023
Thanks Given: 0
Thanks Received: 0

Hi everyone,I’m working on a script to automate my TradeStation chart setup end‑to‑end by reading in the multiwalk text strategy file and the setting up the following commands:[list=1]

New Workspace
New Chart (symbol, interval, session)
Walk‑forward strategy insertion
Chart settings (date range, time zone, bar‑build method, volume source)
Strategy settings (slippage, commission, MaxBarsBack, LIBB, pyramiding)

I’ve had partial success using the Chart Analysis command‑line (e.g. .NewWorkspace, .NewChart, .FirstDate, .LastDate, .BarBuildingMethod, .ForVolume, and .InsertStrategy "<name>"). However, I’ve hit a wall:

No .Slippage or .Commission commands in Chart Analysis
No .MaxBarsBack, .LIBB or .Pyramiding commands exposed via CLI
Strategy settings aren’t available until a strategy is on the chart
I’ve resorted to inserting a dummy strategy first and then using UI automation for the rest, but it’s… clunky

Has anyone:

Built a robust EasyLanguage/Chart Analysis macro or Python+AutoGUI script to fully automate chart+strategy setup?
Discovered undocumented command‑line actions or registry tweaks to expose strategy properties?
Created a more elegant UI‑automation sequence to open Format Strategy → Properties, set slippage, MaxBarsBack, etc., and then insert your walk‑forward strategy?
Any code snippets, PowerShell scripts, or TradeStation extensions you can share?

I’d really appreciate any pointers, examples, or shared tools that can help streamline this process. Thanks in advance for your insights!


Code so far....

import sys
import time
import re
import pyperclip
import pyautogui
import keyboard
import tkinter as tk
from tkinter import filedialog, messagebox

def select_el_file():
root = tk.Tk()
root.withdraw()
return filedialog.askopenfilename(
title="Select ELCode.txt",
filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")]
)

def parse_el_file(path):
settings = {}
try:
with open(path, 'r') as f:
for line in f:
line = line.strip()
if not line.startswith('//'):
continue
content = line[2:].strip()
if ':' not in content:
continue
key, val = map(str.strip, content.split(':', 1))
settings[key] = val
except Exception as e:
messagebox.showerror("Error", f"Reading file failed:\n{e}")
sys.exit(1)

symbol_series = []
for i in range(1, 5):
key = f'Symbol/Interval/Session Data{i}'
if settings.get(key):
symbol_series.append(settings[key])
if not symbol_series:
messagebox.showerror("Error", "No symbol settings (Data1–Data4) found.")
sys.exit(1)

def convert_date(d):
if not d:
return ''
parts = d.split('-')
if len(parts) != 3:
messagebox.showerror("Error", f"Invalid date format: {d}")
sys.exit(1)
m, da, y = parts
return f"{m}/{da}/{y}"

return {
'symbol_series': symbol_series,
'begin': convert_date(settings.get('Begin Date (mm-dd-yyyy)', '')),
'end': convert_date(settings.get('End Date (mm-dd-yyyy)', '')),
'bar_method': settings.get('Bar Building Method', ''),
'volume_use': settings.get('For Volume, Use', ''),
'slippage': settings.get('Slippage', ''),
'commission': settings.get('Commission', ''),
'fill_assumption': settings.get('Limit Order Fill Assumption', ''),
'max_bars': settings.get('Maximum number of bars (MaxBarsBack)', ''),
'libb': settings.get('Look-Inside-Bar Backtesting (LIBB)', ''),
'pyramiding': settings.get('Multiple position/pyramiding enabled', ''),
'wf_name': settings.get('Walkforward Strategy Name', '')
}


def generate_commands(p):
"""
1) .NewWorkspace
2) .NewChart
3) Insert dummy strategy (must already exist in TS)
4) All your chart & strategy settings
5) Insert real strategy (quoted)
6) The rest (dates, time zone, bar method, volume)
"""

cmds = [
'.NewWorkspace',
'.NewChart',
# 3) Dummy strategy to unlock settings:
'.InsertStrategy "_DummyInitialise"'
]

# 4) Apply all your settings now that 'something' is on the chart:
if p['slippage']:
cmds.append(f'.Slippage {p["slippage"]}')
if p['commission']:
cmds.append(f'.Commission {p["commission"]}')
if p['fill_assumption']:
cmds.append(f'.LimitOrderFillAssumption {p["fill_assumption"]}')
if p['max_bars']:
cmds.append(f'.MaxBarsBack {p["max_bars"]}')
if p['libb']:
cmds.append(f'.LIBB {p["libb"]}')
if p['pyramiding']:
cmds.append(f'.Pyramiding {p["pyramiding"]}')

# 5) Now insert the real walk‑forward strategy, quoted to handle spaces/brackets:
if p['wf_name']:
cmds.append(f'.InsertStrategy "{p["wf_name"]}"')

# 6) Finally, symbol streams, sessions, and dates/ranges:
for s in p['symbol_series']:
m = re.match(r'([^()]+)\(([^)]+)\)', s)
if m:
sym_int = m.group(1).strip().replace('min', ' min')
sess = m.group(2).strip()
cmds += [sym_int, f'.Session {sess}']
else:
cmds.append(s)

if p['begin']:
cmds.append(f'.FirstDate {p["begin"]}')
if p['end']:
cmds.append(f'.LastDate {p["end"]}')

# And any remaining chart‑level commands:
if p['bar_method']:
cmds.append(f'.BarBuildingMethod {p["bar_method"]}')
if p['volume_use']:
cmds.append(f'.ForVolume {p["volume_use"]}')

return cmds

def send_commands_to_ts(commands):
messagebox.showinfo("Ready", "Switch to TradeStation now. Sending in 3 seconds... (Press ESC to abort)")
time.sleep(3)
for cmd in commands:
if keyboard.is_pressed('esc'):
messagebox.showwarning("Aborted", "ESC detected — aborting paste.")
return
pyperclip.copy(cmd)
pyautogui.hotkey('ctrl', 'v')
pyautogui.press('enter')
time.sleep(2)
for _ in range(20):
if keyboard.is_pressed('esc'):
messagebox.showwarning("Aborted", "ESC detected — aborting paste.")
return
time.sleep(0.1)
messagebox.showinfo("Done", "All commands sent successfully!")

def main():
path = select_el_file()
if not path:
return
parsed = parse_el_file(path)
cmds = generate_commands(parsed)
preview = "\n".join(cmds)
tk.Tk().withdraw()
messagebox.showinfo("Commands Preview", preview)
if not messagebox.askokcancel("Proceed", "Ready to send commands?"):
return
send_commands_to_ts(cmds)

if __name__ == "__main__":
main()


Started this thread Reply With Quote




Last Updated on April 18, 2025


© 2025 NexusFi®, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
All information is for educational use only and is not investment advice. There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Downloads - Top
no new posts