[pshaiCmd] SuperInput

stable
By pshai in Miscellaneous Published November 2020 👁 1,527 views 💬 7 comments

Description

Creates an input field and monitors changes in value. A handy way to monitor values and/or optimize calculations. Requires: https://www.haasscripts.com/t/pshaicmd-superinputsettings/ Example:
EnableHighSpeedUpdates()
--
local settings = CC_SuperInputSettings('some default value', 'a tool-tip', 'a group!', 2)
local someVar = CC_SuperInput('Input', 'Some Input', settings)
--
if someVar.FieldChanged then
    LogWarning('some setting was changed, recalculate AI...')
else
    local value = someVar.FieldValue -- get value from input field
end
HaasScript
DefineCommand('SuperInput', 'Creates an input field and monitors changes in value')

local supportedInputs = {}
supportedInputs['Input'] = Input
supportedInputs['InputAccount'] = InputAccount
supportedInputs['InputAccountMarket'] = InputAccountMarket
supportedInputs['InputCdlTypes'] = InputCdlTypes
supportedInputs['InputConstant'] = InputConstant
supportedInputs['InputInterval'] = InputInterval
supportedInputs['InputLrTypes'] = InputLrTypes
supportedInputs['InputMaTypes'] = InputMaTypes
supportedInputs['InputMarket'] = InputMarket
supportedInputs['InputOptions'] = InputOptions
supportedInputs['InputOrderType'] = InputOrderType
supportedInputs['InputPriceSource'] = InputPriceSource
supportedInputs['InputPriceSourceMarket'] = InputPriceSourceMarket
supportedInputs['InputSignalManagement'] = InputSignalManagement
supportedInputs['InputSignalTypes'] = InputSignalTypes
supportedInputs['InputTable'] = InputTable

local print = function(prefix, type, msg)
    msg = '[' .. prefix .. '] ' .. msg
    
    if type == 0 then
        Log(msg)
    elseif type == 1 then
        LogWarning(msg)
    elseif type == 2 then
        LogError(msg)
    end
end

local stringFormat = function(msg, ...)
    local args = {...}
    local count = #args

    for i = 1, count do
        local arg = args[i]
        local id = '{'..i..'}'

        if arg != nil and arg != '' and StringContains(msg, id) then
            local pos = StringIndexOf(msg, id)
            local temp1 = SubString(msg, 0, pos)
            local temp2 = SubString(msg, pos+4, #msg)
            
            if temp1 != nil then
                msg = temp1 .. arg
            end
            
                if temp2 != nil and #temp2 > 0 and temp2 != '' then
                msg = temp1 .. arg .. temp2
            end
        end
    end

    return msg
end

local cmd_name = DefineParameter(StringType, 'cmd_name', 'Input command name', true, 'InputLrTypes')
local label = DefineParameter(StringType, 'label', 'Input label', true, 'Input label text', 'Text, StringJoin, SessionGet')
local settings = DefineParameter(ListDynamicType, 'settings', 'Settings for input. For example, {defaultValue = "default"}', true, {defaultValue = LR_Intercept, tooltip = 'a tool tip', group = 'a group!', logType = '-v-m'}, 'NewList, NewArray, SessionGet')

local input_value = supportedInputs[cmd_name] (label, {defaultValue = settings.defaultValue, tooltip = settings.tooltip, group = settings.group})
local prev_value = Load('prev_value', input_value)
local input_changed = input_value != prev_value

-- save new value
Save('prev_value', input_value)

if settings.logType != nil and settings.logType != '' then
    local verbose = false
    local log = false

    if StringContains(settings.logType, '-v') then
        verbose = true 
    end

    if StringContains(settings.logType, '-m') then
        log = true
    end

    local prefix = cmd_name .. ' - ' .. label

    if log then
        print(prefix, 0, stringFormat('input_value: {1} (prev: {2})', input_value, prev_value))
    end
    
    if verbose and input_changed then
        print(prefix, 1, stringFormat('input value "' .. label .. '" changed to "' .. input_value .. '"'))
    end
end

local obj = {
        FieldValue = input_value,
        FieldChanged = input_changed
    }

DefineOutput(ListDynamicType, obj)

DefineOutputIndex(1, DynamicType, 'FieldValue', 'Value from the input field', '')
DefineOutputIndex(2, BooleanType, 'FieldChanged', 'True if input value has been changed on-the-fly, false if not', '')

7 Comments

Sign in to leave a comment.

F
Firetron over 5 years ago

Can you provide some more details or use cases of how to benefit?

P
pshai over 5 years ago

The idea was to be able to make scripts more optimized. There could be something you need to calculate based on some inputs you get, but is slowing down your script execution. But if those inputs stay the same (like they probably will for quite some time), it could be better to re-calculate those heavy-values _only_ when you change the values.

Hope this helps.

K
Kobalt over 5 years ago

Is there a way to check if a CC or calculation in some part of your script is slowing down execution or resources used per command dependency.
To find things SuperInputs would improve, or to avoid in general or any other way avoid sluggish execution?

Maybe there are common bad practices an optimisation check script could detect.
[These are more inspirational than straight questions. I assume something like this doesn't yet exist. Unless I'm over complicating this and theres a check list or simple way to do this..:)]

Your example makes me curious what might benefit here, can you give an obvious/notorious example? (Interval, VWAP reset loopback those kind of things?)
And SuperInput works in running HaasBots so can maybe help people running 50+ scripts?

P
pshai over 5 years ago

Your example makes me curious what might benefit here, can you give an obvious/notorious example? (Interval, VWAP reset loopback those kind of things?)
And SuperInput works in running HaasBots so can maybe help people running 50+ scripts?

Yes, these are the kind of things I mean. If you can find something that doesn't need to be re-calculated unless the input values have changed, you can use this to detect that.

You could do the same for every input in your script by saving/loading and comparing the current input value to previously saved value, but I would argue that this makes it a little bit easier. :P

K
Kobalt over 5 years ago

Ok just to drain the regular folks talk out of you | show how little I know | try to bridge the gap between:

what is obvious to you and is still very vague territory to many...
Would using this instead for every Input make sense?
In the sense: Can't hurt to always use SuperInput vs regular Input.

if SuperInput "only makes things faster never slower" then
Upgrade the default Input command: to enhanced (super)Input.
Input=SuperInput
end
return Input
else
If super is not always better then
Log [array content}

Please list some Inputs everyone uses: [categorise or label as I, Input or SI, SuperInput]
So users who are not the king, tron or the wizard.
Get a still not set in stone but better idea which "stuff" calculates and whatever magics..
And may or may not qualify for using SuperInput over regular Input.

P
pshai over 4 years ago

Well, one good example would be a daily moving average that is using closed prices only. You would only have to calculate that ONCE every 1440 minutes, right? But, in case the user changes the length or type of this moving average, you might want to recalculate it immediately vs wait until the next calculation occurs. This is the kind of case where this command (or any logic that tracks changes in input values) comes in handy.

K
Kobalt over 4 years ago

Right I see, (really I think it just got a lot clearer) Cool!

Maybe.. just maybe this has more potential as an enhancement feature to post on Trello??
(I'd say "keep it in the back of your head", but fear that many insignificant to you but potentially much greater things reside)

This one haas the : "A small step for pshai, but a leap for all HaasHoles" potential too.

I'm going to spitball here:

1: upgrade the Input command by default with the optimization option for (Super log) as a general tick box for all Inputs or an optional boolean parameter to add in each that either defaults false if left blank or if specified, true for Super. (I like the on off tick-box option better)

I'm going here because I'm assuming that: These/there are more than a couple of typical scenarios (like your MA example would otherwise go 'unfettered' lol what a word)
Operations with no Return.. etc that later on perhaps we can find a way to collect, identify, detect, extract, correct adjust or optimize....

2: Not just when if a script is slow to enable Super scan for detection of (potentially) unnecessary recalculations..

3: A script tuner similar to HaasLab only for detecting obsolete or problematic lines of code.. you can try and commit or discard / undo to:
Tune for efficiency and reliability. (and educate)

Ideally (and since the singularity is accelerating, perhaps sooner and with less effort than we think;) this could evolve into:

4. Some intelligent scan heuristics and what not.. analysis/safety net (on running scripts that seem to be on the. verge of 'trouble' in the back end for *all running scripts in the cloud..
*everyone may opt in or out...etc. (unless it's super basic stupid foolproof trouble avoidance only and has zero chance of. false positives)

Greets