NexusFi: Find Your Edge


Home Menu

 





AutoHotkey Scripts


Discussion in NinjaTrader

Updated
      Top Posters
    1. looks_one monpere with 23 posts (98 thanks)
    2. looks_two traderap101 with 13 posts (12 thanks)
    3. looks_3 trendisyourfriend with 12 posts (0 thanks)
    4. looks_4 perryg with 6 posts (2 thanks)
      Best Posters
    1. looks_one monpere with 4.3 thanks per post
    2. looks_two traderap101 with 0.9 thanks per post
    3. looks_3 SilverFut with 0.7 thanks per post
    4. looks_4 perryg with 0.3 thanks per post
    1. trending_up 36,224 views
    2. thumb_up 115 thanks given
    3. group 35 followers
    1. forum 64 posts
    2. attach_file 10 attachments




 
Search this Thread

AutoHotkey Scripts

  #61 (permalink)
traderap101
London UK
 
Posts: 18 since Jul 2022
Thanks Given: 3
Thanks Received: 16

Use V1.2 which I have just posted. Change XTools := 300 for NT 8.0.28.0. This should be the only change needed to get it to work on your version of NinjaTrader. (I installed NT 8.0.28.0 on a virtual machine, ran the script and it was working correctly for me with XTools := 300 change) Let me know how you get on.


trendisyourfriend View Post
I found the problem thid morning with fresh eyes.

I needed to update this line:


Reply With Quote
Thanked by:

Can you help answer these questions
from other members on NexusFi?
Better Renko Gaps
The Elite Circle
REcommedations for programming help
Sierra Chart
Quantum physics & Trading dynamics
The Elite Circle
What broker to use for trading palladium futures
Commodities
MC PL editor upgrade
MultiCharts
 
  #62 (permalink)
traderap101
London UK
 
Posts: 18 since Jul 2022
Thanks Given: 3
Thanks Received: 16

Yes its possible to AutoHotkey script the download of other historical data (Intervals of Tick/Minute/Days abd Data Type of Ask/Bid/Last) for the fields Instrument, Start Date and End Date. I will have a look at this soon once I have resolved any other issues with the current script for market replay data.


trendisyourfriend View Post
Do you think you could adapt your script to download historical datas ?

Ideally, here is what i would need:

Given a defined list of instruments, i need to download data from a specific date in the past to now using a 1 minute chart.

Then, once the minute data have been downloaded, we repeat the process but this time using a 500 tick chart.


Historical Data Window

Reply With Quote
Thanked by:
  #63 (permalink)
 
trendisyourfriend's Avatar
 trendisyourfriend 
Quebec Canada
Market Wizard
 
Experience: Intermediate
Platform: NinjaTrader
Broker: AMP/CQG
Trading: ES, NQ, YM
Frequency: Daily
Duration: Minutes
Posts: 4,527 since Oct 2009
Thanks Given: 4,176
Thanks Received: 6,020



traderap101 View Post
Yes its possible to AutoHotkey script the download of other historical data (Intervals of Tick/Minute/Days abd Data Type of Ask/Bid/Last) for the fields Instrument, Start Date and End Date. I will have a look at this soon once I have resolved any other issues with the current script for market replay data.




Historical Data Window

I do not use this dialog to load historical datas as it uses the Trading hours defined in the instrument which may not be the template which contains the extended trading hours. The way i proceed is like this:

I empty the cache then...

1) i open a chart say the ES and open the data series window
2) i set the 1 minute interval
3) i set the custom range of the period to load (usually from a date in history to today)

Once the chart is loaded, i force a reload by right clicking on the chart background and select "Reload All Historical Data". This way if there has been corrections applied to the data they will be replaced in the local DB.

Next i proceed with the next instrument

I repeat this process with tick data as well.

For the autoHotKey script, i would not mind creating the chart and setting the initial range and interval manually. The rest could be done by the autohotkey script, ie, changing instrument and forcing a "Reload All Historical Data".

Reply With Quote
  #64 (permalink)
traderap101
London UK
 
Posts: 18 since Jul 2022
Thanks Given: 3
Thanks Received: 16

V1.3 Market Replay & Historical Download for Multi-Instrument and Multi-Date Range

Here is V1.3 of the AutoHotkey script to automate historical data downloads for multi date range and multi-instrument. The main changes in this version are:
  1. Functionality added to download Tick/Minute/Day intervals for Ask/Bid/Last using the Historical Data download window from Control Center
  2. User parameters are slightly different to previous version

User Parameters
The most likely parameters that a user may need to modify are between the sections Start and End of User Parameters :


/* Start of User Parameters */

/* Only one of these parameters should be true for a single script invocation */
DownloadMktReplay := false ; Set to true for Market Replay Download
DownloadHistoricalData := true ; Set to true for Historical Data Download

/* Download progress status window toggle */
ShowProgressWindow := false ; Set to true for a Progress Window

/* Comma separated instrument list to download. Make sure you type in the correct name without any extraneous spaces or characters. */
InstrumentList := "MNQ 09-23,MES 09-23"

/* Start & End date range to download in YYYYMMDD format */
StartDate := 20230601
EndDate := 20230616

/* Skip Days */
SkipSaturday := true ; Set to true if Saturday data should be skipped
SkipSunday := false ; Set to true if Sunday data should be skipped

/* Download Data Intervals */
TickInterval := true ; Set to true if you want to download Tick data
MinuteInterval := true ; Set to true if you want to download Minute data
DayInterval := true ; Set to true if you want to download Day data

/* Download Data Types */
Ask := true ; Set to true if you want to download Ask Data
Bid := true ; Set to true if you want to download Bid Data
Last := true ; Set to true if you want to download Last Data

/* Position of Tools menu on Control Center window */
/* Change XTools to 300 for Ninja Trader 8.0.28.0 */
/* Use C:\Program Files\AutoHotkey\WindowSpy.ahk (AutoHotkey Window Spy) */
/* to identify these positions if script does not work */

XTools := 250
YTools := 10

/* Number of millseconds to wait between keystroke/mouse actions on windows */
SleepBetweenActions := 400 ; Should not need to change unless you have a slow PC

/* End of User Parameters */

Usage
  1. Download Version V2 of https://www.autohotkey.com/
  2. Copy this code into a file with a .ahk extension e.g. Data Downloader.ahk
  3. Make sure you have started NinjaTrader and Windows Control Center is active
  4. From Windows Explorer just double click the script (No need to have AutoHotkey running as windows knows how to execute .ahk files after installation
  5. If you need to abort the script then close the Historical Data window
  6. Do NOT bring any other window into active focus whilst script is running as it may send mouse clicks / keystrokes into the wrong window and cause issues with those windows.
  7. For NinjaTrader 8.0.28.0 change XTools := 300 as x-axis location of the Tools menu position in the Control Center window is different to NinjaTrader 8.1.1.1

Tested
NinjaTrader Versions = NinjaTrader 8.0.28.0 and NinjaTrader 8.1.1.1
Broker = Rithmic

Not tested with any other version or broker.

Limitations
Use at your own risk, as the script performs keystroke and mouse emulation. It has defensive checks built in but may not have been tested exhaustively.

Post any issues you encounter including NinjaTrader Version number you are running and I will look at them as time permits.

 
Code
/*

Written by Trader AP
Use at your own risk

V1.0 - 10 June 2023 - Original Version
V1.1 - 10 June 2023 - Amended to resize Historical Window to specific size/position in order to
                      mouseclick and detect download button in the right position
V1.2 - 12 June 2023 - Added a Status Window to see progress of script.  Tested on NT 8.0.28.0 64-bit which requires slightly different parameters for XTools = 300
V1.3 - 18 June 2023 - Added functionality to download historical data type (bid, ask, last) for intervals (tick, minute, day)
*/

#SingleInstance Force

/********************************************* Start of User Parameters *********************************************/

DownloadMktReplay := false
DownloadHistoricalData := true

/* Download progress status window toggle */
ShowProgressWindow := false

/* Comma separated instrument list to download.  Make sure you type in the correct name without any extraneous spaces or characters. */
InstrumentList := "MNQ 09-23"

/* Start & End date range to download in YYYYMMDD format */
StartDate := 20230601
EndDate := 20230616

/* Skip Days */
SkipSaturday := true
SkipSunday := false

/* Download Data Intervals */
TickInterval := true
MinuteInterval := true
DayInterval := true

/* Download Data Types */
Ask := true
Bid := true
Last := true

/* Position of Tools menu on Control Center window */
/* Change XTools to 300 for Ninja Trader 8.0.28.0 */
/* Use C:\Program Files\AutoHotkey\WindowSpy.ahk (AutoHotkey Window Spy) */
/* to identify these positions if script does not work */

XTools := 250
YTools := 10

/* Number of millseconds to wait between keystroke/mouse actions on windows */
SleepBetweenActions := 400

/********************************************* End of User Parameters *********************************************/

/* Today's date in YYYYMMDD format */
TodaysDate := A_YYYY A_MM A_DD

/* Window Title Names */
ControlCenterWindow := "Control Center"
HistDataWindow := "Historical Data"
ProgessWindow := "Download Progress"

/* Size of Download progress window */
ProgessWindowSize := "W400 H30 cgreen vMyProgress"

/* Resize Historical Data window to the following whilst processing mouse clicks and getting button status */
XFixedSizeHDWindow := 1
YFixedSizeHDWindow := 1
WFixedSizeHDWindow := 750
HFixedSizeHDWindow := 650

/* Position of rotating triangle for Get Market Replay data in Historical Data window */
XMktReplayRotatingTriangle := 35
YMktReplayRotatingTriangle := 630

/* Position of Market Replay Instrument field in Historical Data window */
XMktReplayInstrument := 30
YMktReplayInstrument := 625

/* Position of Market Replay download button in Historical Data window */
XMktReplayDownloadButton := 645
YMktReplayDownloadButton := 625

/* Position of rotating triangle for "Download" data in Historical Data window */
XDownloadRotatingTriangle := 35
YDownloadRotatingTriangle := 565

/* Position of "Download" Instrument field in Historical Data window */
XDownloadInstrument := 30
YDownloadInstrument := 510

/* Position of "Download" button in Historical Data window */
XDownloadDownloadButton := 645
YDownloadDownloadButton := 565

/* Create a progress window with status bar */
if (ShowProgressWindow) {
    MyGui := Gui(, ProgessWindow)
    MyProgress := MyGui.Add("Progress", ProgessWindowSize)
    MyProgressStatusBar := MyGui.Add("StatusBar", , "")
    MyGui.Show
}

/* Function for formatted debug & status bar messages */
MyDebug(MessagePrefix, Message, ShowMessageBox := false, ShowStatusOnBar := false)
{
    if (ShowProgressWindow && ShowStatusOnBar && WinExist(ProgessWindow)) {
        MyProgressStatusBar.SetText(FormatTime(A_Now, "ShortDate") " " A_Hour ":" A_Min ":" A_Sec " " Format("{1:-12}", MessagePrefix ": ") Message)
    }

    OutputDebug FormatTime(A_Now, "ShortDate") " " A_Hour ":" A_Min ":" A_Sec " " Format("{1:-12}", MessagePrefix ": ") Message "`n"

    if ShowMessageBox {
        MsgBox(Message, MessagePrefix, MessagePrefix == "Error" ? "Icon!" : "Iconi")
    }
}

MyExit() {

    /* Close download progress window */
    if (ShowProgressWindow && WinExist(ProgessWindow)) {
        MyGui.Destroy
    }

    ExitApp -1
}

/* A few defensive checks on user parameters */
if (StrLen(InstrumentList) = 0) {
    MyDebug("Error", "InstrumentList is blank in script settings.", true)

    MyExit()
}

if (StrLen(StartDate) != 8 || StrLen(FormatTime(StartDate, "ShortDate")) == 0) {
    MyDebug("Error", "StartDate is not in the right format in script settings.", true)

    MyExit()
}

if (StrLen(EndDate) != 8 || StrLen(FormatTime(EndDate, "ShortDate")) == 0) {
    MyDebug("Error", "EndDate is not in the right format in script settings.", true)

    MyExit()
}

if (DateDiff(TodaysDate, StartDate, "days") < 0) {
    MyDebug("Error", "StartDate " FormatTime(StartDate, "ShortDate") " is greater than today's date in script settings.", true, true)

    MyExit()
}

/* Check only one of DownloadHistoricalData and DownloadMktReplay settings is true */
if ( not (DownloadMktReplay ^ DownloadHistoricalData)) {
    MyDebug("Error", "Only one of DownloadMktReplay & DownloadHistoricalData should be true in script settings.", true, true)

    MyExit()
}

/* Check that at least 1 interval has been set to true */
if ( not (TickInterval || MinuteInterval || DayInterval)) {
    MyDebug("Error", "At least one of TickInterval, MinuteInterval, DayInterval should be true in script settings.", true, true)

    MyExit()
}

/* Check that at least 1 interval has been set to true */
if ( not (Ask || Bid || Last)) {
    MyDebug("Error", "At least one of Ask, Bid, Last should be true in script settings.", true, true)

    MyExit()
}

/* End Date cannot exceed today's system date */
EndDate := Min(EndDate, TodaysDate)

/* Calculate number of download days */
NumberofDaysToDownload := DateDiff(EndDate, StartDate, "days") + 1

/* Calculate the number of items to download */
TotalDownloadItems := 0
Loop Parse, InstrumentList, "," {
    TotalDownloadItems += 1
}
TotalDownloadItems := TotalDownloadItems * NumberofDaysToDownload

/* Start the mouse and keystroke emulation */
MyDebug("Message", "Starting " (DownloadMktReplay ? "Market Replay" : "Historical") " Data Download for " NumberofDaysToDownload " day" (NumberofDaysToDownload == 1 ? "" : "s"), false)
MyDebug("Message", "Total Number of Downloads across all Instruments is " TotalDownloadItems)

if (WinExist(HistDataWindow)) {
    MyDebug("Message", "Closing existing open " HistDataWindow " window", false, false)
    WinClose(HistDataWindow)
    Sleep SleepBetweenActions
}

if (WinExist(ControlCenterWindow)) {
    MyDebug("Message", "Found " ControlCenterWindow " window", false, false)

    WinActivate
    Sleep SleepBetweenActions / 2

    /* Click Tools menu item */
    MouseClick("Left", XTools, YTools)
    Sleep SleepBetweenActions

    /* Select Historical Data menu item */
    SendInput "{Down}{Down}{Down}{Down}{Down}{Enter}"

    if (WinWait(HistDataWindow, , 5)) {
        MyDebug("Message", "Opened " HistDataWindow " window", false, false)
        WinActivate

        /* Get current Historical Data window size and position */
        WinGetPos(&XCurrentHDWindow, &YCurrentHDWindow, &WCurrentHDWindow, &HCurrentHDWindow, HistDataWindow)

        /* Resize Historical Data window to fixed values to ensure correct mouse click positions */
        WinMove(XFixedSizeHDWindow, YFixedSizeHDWindow, WFixedSizeHDWindow, HFixedSizeHDWindow, HistDataWindow)

        if (DownloadMktReplay) {
            /* Expand the rotating triangle for Get Market Replay data */
            MouseClick("Left", XMktReplayRotatingTriangle, YMktReplayRotatingTriangle)
        }
        else {
            /* Expand the rotating triangle for Get Market Replay data */
            MouseClick("Left", XDownloadRotatingTriangle, YDownloadRotatingTriangle)
        }

        Sleep SleepBetweenActions

        /* Loop through instruments */
        Loop Parse, InstrumentList, "," {

            Instrument := A_LoopField                   ; Process each instrument in list
            ProcessDate := StartDate                    ; Start date to be processed for each instrument
            LoopCnt := NumberofDaysToDownload           ; Number of days to download for each instrument

            if (DownloadMktReplay) {
                /* Loop through download dates for each instrument */
                While (LoopCnt > 0) {

                    ; Skip weekend days based on user configuration
                    if ((SkipSaturday and !StrCompare(FormatTime(ProcessDate, "WDAY"), "7")) or (SkipSunday and !StrCompare(FormatTime(ProcessDate, "WDAY"), "1"))) {
                        MyDebug("Skipping", Instrument " for date " FormatTime(ProcessDate, "ShortDate") " as it is a weekend skip date", false, true)
                        ProcessDate := DateAdd(ProcessDate, 1, "Days")
                        if (ShowProgressWindow) {
                            MyProgress.Value += 100 / TotalDownloadItems
                        }
                        LoopCnt -= 1
                        continue
                    }

                    if (WinExist(HistDataWindow)) {
                        WinActivate

                        MyDebug("Processing", Instrument " for date " FormatTime(ProcessDate, "ShortDate"), false, true)

                        /* Select Instrument Field */
                        MouseClick("Left", XMktReplayInstrument, YMktReplayInstrument)

                        /* Clear Instrument and Date fields and then fill them in */
                        SendInput "^a{Del}" Instrument "{Tab}^a{Del}" FormatTime(ProcessDate, "ShortDate")

                        /* Get colour of a download button pixel before presssing enter as this pixel color will be checked to see if download has finished */
                        BeforeDownloadButtonPressColor := PixelGetColor(XMktReplayDownloadButton, YMktReplayDownloadButton)

                        SendInput "{Tab}{Enter}"

                        Sleep SleepBetweenActions * 6

                        if (WinExist("Error")) {
                            WinActivate
                            SendInput "{Enter}"
                            MyDebug("Error", Instrument " for date " FormatTime(ProcessDate, "ShortDate") " NinjaTrader responded with an Error window", false, true)

                            Sleep SleepBetweenActions
                        }
                        else {
                            loop {
                                Sleep SleepBetweenActions * 10
                                if WinExist(HistDataWindow)
                                    WinActivate(HistDataWindow)
                                else {
                                    MyDebug("Error", "Exiting script as Historical Data window closed", true, true)

                                    MyExit()
                                }
                            } Until (!StrCompare(BeforeDownloadButtonPressColor, PixelGetColor(XMktReplayDownloadButton, YMktReplayDownloadButton)))
                        }

                        ProcessDate := DateAdd(ProcessDate, 1, "Days")
                        if (ShowProgressWindow) {
                            MyProgress.Value += 100 / TotalDownloadItems
                        }
                        LoopCnt -= 1
                    }
                    else {
                        MyDebug("Message", "Closing " HistDataWindow " window", false)
                    }
                } ; Loop Instruments
            }
            else {

                if (WinExist(HistDataWindow)) {
                    WinActivate

                    MyDebug("Processing", Instrument " for date " FormatTime(StartDate, "ShortDate") " to " FormatTime(EndDate, "ShortDate"), false, true)

                    /* Select Instrument Field */
                    MouseClick("Left", XDownloadInstrument, YDownloadInstrument)

                    /* Clear Instrument and Date fields and then fill them in */
                    SendInput "^a{Del}"

                    InstrumentFieldColour := PixelGetColor(XDownloadInstrument, YDownloadInstrument)

                    SendInput Instrument "{Tab}^a{Del}" FormatTime(StartDate, "ShortDate") "{Tab}^a{Del}" FormatTime(EndDate, "ShortDate") "{Tab}"

                    /* Set/Unset checkboxes based on whether window already has them selected and user script setting */
                    SendInput ((!StrCompare(InstrumentFieldColour, PixelGetColor(30, 560)) ^ TickInterval)) ? "{Tab}" : " {Tab}"

                    SendInput ((!StrCompare(InstrumentFieldColour, PixelGetColor(75, 560)) ^ MinuteInterval)) ? "{Tab}" : " {Tab}"

                    SendInput ((!StrCompare(InstrumentFieldColour, PixelGetColor(140, 560)) ^ DayInterval)) ? "{Tab}" : " {Tab}"

                    SendInput ((!StrCompare(InstrumentFieldColour, PixelGetColor(270, 560)) ^ Ask)) ? "{Tab}" : " {Tab}"

                    SendInput ((!StrCompare(InstrumentFieldColour, PixelGetColor(315, 560)) ^ Bid)) ? "{Tab}" : " {Tab}"

                    SendInput ((!StrCompare(InstrumentFieldColour, PixelGetColor(355, 560)) ^ Last)) ? "{Tab}" : " {Tab}"

                    /* Get colour of a download button pixel before presssing enter as this pixel color will be checked to see if download has finished */
                    BeforeDownloadButtonPressColor := PixelGetColor(XDownloadDownloadButton, YDownloadDownloadButton)

                    SendInput "{Enter}"

                    Sleep SleepBetweenActions * 6

                    if (WinExist("Error")) {
                        WinActivate
                        SendInput "{Enter}"
                        MyDebug("Error", Instrument " for date " FormatTime(ProcessDate, "ShortDate") " NinjaTrader responded with an Error window", false, true)

                        Sleep SleepBetweenActions
                    }
                    else {
                        loop {
                            Sleep SleepBetweenActions * 10
                            if WinExist(HistDataWindow)
                                WinActivate(HistDataWindow)
                            else {
                                MyDebug("Error", "Exiting script as Historical Data window closed", true, true)

                                MyExit()
                            }
                        } Until (!StrCompare(BeforeDownloadButtonPressColor, PixelGetColor(XDownloadDownloadButton, YDownloadDownloadButton)))
                    }
                }
            }
        } ; Loop InstrumentList

        /* Close download progress window */
        if (ShowProgressWindow && WinExist(ProgessWindow)) {
            MyGui.Destroy
        }

        if (WinExist(HistDataWindow)) {
            /* Revert to original Historical Window size and position */
            WinMove(XCurrentHDWindow, YCurrentHDWindow, WCurrentHDWindow, HCurrentHDWindow, HistDataWindow)

            MyDebug("Message", "Closing " HistDataWindow " window", false, false)

            WinClose(HistDataWindow)
        }
    }
    else {
        MyDebug("Error", "Could not find " HistDataWindow " window", true, false)

        MyExit()
    }
}
else {
    MyDebug("Error", "Could not find " ControlCenterWindow " window", true, false)

    MyExit()
}

MyDebug("Complete", "Script " (DownloadMktReplay ? "Market Replay" : "Historical") " Data Download Finished", true, false)

ExitApp 0

Reply With Quote
  #65 (permalink)
traderap101
London UK
 
Posts: 18 since Jul 2022
Thanks Given: 3
Thanks Received: 16

See V1.3 that I have just posted. It now allows download of either Market Replay Data or Historical Data. I have tested this on a clean install of NinjaTrader 8.0.28.0 and it correctly downloads multiple intervals (Minute, Tick, Day) for multiple data types (Ask, Bid, Last) for the date range defined in the script. So I don't think you need to do the process you described by opening a chart window. Try it out and you can verify that it has all the data by going to the Historical Window to see what it has downloaded (subject to your market data provider having this information to download). I did not find that the Historical Data Window uses the "Trading hours defined in the instrument" as it downloaded extended hours even though instrument settings were for regular hours.


trendisyourfriend View Post
I do not use this dialog to load historical datas as it uses the Trading hours defined in the instrument which may not be the template which contains the extended trading hours. The way i proceed is like this:

I empty the cache then...

1) i open a chart say the ES and open the data series window
2) i set the 1 minute interval
3) i set the custom range of the period to load (usually from a date in history to today)

Once the chart is loaded, i force a reload by right clicking on the chart background and select "Reload All Historical Data". This way if there has been corrections applied to the data they will be replaced in the local DB.

Next i proceed with the next instrument

I repeat this process with tick data as well.

For the autoHotKey script, i would not mind creating the chart and setting the initial range and interval manually. The rest could be done by the autohotkey script, ie, changing instrument and forcing a "Reload All Historical Data".


Reply With Quote
Thanked by:




Last Updated on June 18, 2023


© 2024 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 - Privacy Policy - Downloads - Top
no new posts