In this tutorial you will learn how to implement your own PercentagePriceChange insurance. It will guide you through the process of creating custom commands from scratch.
This custom command will resemble the exact same functionality as the built-in command.
Creating new script
First off, we will start by creating a new script in the script editor.
Select the Command type and name it "Percentage Price Change".
Command and input parameters
Define command
Now, let's continue by splitting the script into sections and defining our command:
local targetPrice =DefineParameter( NumberType,'targetPrice','The target price of the trade. Default is the current buy or sell price.',false,0,'Number, Input, BidPrices, AskPrices' )
positionId
Parameter type: StringType
Name: "positionId"
Description: "Unique identifier. Used when the bot is trading multiple positions at once."
IsRequired: False
Default value: ""
Input suggestions: "SessionGet, Load"
local positionId =DefineParameter( StringType,'positionId','Optional unique identifier. Required when the bot is trading multiple position at once.',false,'','SessionGet, Load' )
Section code summary
Great! Now our script should look something like this:
-- ---------------------------------------- Command-- --------------------------------------DefineCommand('PercentagePriceChange', -- Name'Custom insurance. Returns true if trade is allowed, otherwise false.' -- Description )-- ---------------------------------------- Parameters-- --------------------------------------local percentage =DefineParameter( NumberType,'percentage','Minimum percentage change before a trade is allowed.',true,0,'Input' )local targetPrice =DefineParameter( NumberType,'targetPrice','The target price of the trade. Default is the current buy or sell price.',false,0,'Number, Input, BidPrices, AskPrices' )local positionId =DefineParameter( StringType,'positionId','Optional unique identifier. Required when the bot is trading multiple position at once.',false,'','SessionGet, Load' )-- ---------------------------------------- Logic-- ---------------------------------------- code here...-- ---------------------------------------- Output-- ---------------------------------------- code here...
Adding logic
Internal variables
Right, so next we need to create the soul of this command. We will start off by defining some internal variables which we will use. What we need are position that is assigned with the position information and result which will be set to true if a trade would be allowed or otherwise false.
-- Internal variableslocal position =PositionContainer(positionId) -- Position informationlocal result =false-- Our result value
The PositionContainer() returns an object with accessible properties.
See: Commands -> Position Information -> PositionContainer
Simple optimization
Also we want to make sure that the input value percentage will always be a positive value.
percentage =Abs(percentage)
Now, I know the percentage is a required value, but what if it was set to zero? Wouldn't it be unnecessary to go through the entire logic if this was the case? To overcome that problem, we add a simple if-statement to only run our logic if the value is above zero.
if percentage >0then-- Run logic-- ...else-- Allow trade result =trueend
Great! This might not optimize much for this particular command, but it's for good practice.
Another way to optimize even further would be to use DefineIntervalOptimization().
Calculating result
Next we will want to separate Long and Short positions since they will have a slightly different calculations for determining the result. We can get this information from our position variable which we defined earlier. Let's do just that. First, we will check if the current position is Long (Bought) position and then calculate the result for it.
if position.isLong then result =AddPercentage(AverageEnterPrice(position.positionId), percentage) < targetPriceend
Okay, so now we will have result set to true whenever the targetPrice is bigger than the entry price. We also increase the entry price value by the percentage variable.
But... Weren't the targetPrice defined as a "not required" parameter? Oh yes, it was. And its description even mentioned about buy and sell prices! If we would use the default value of this parameter - which is zero - we would never get any trades through. Don't worry, there's always a solution. We will check if the targetPrice is set to zero and if it is, we simply set it to something else. In this case, we set it as the current sell price (top bid price). We will also have to take the position's market into account - otherwise this would not work in unmanaged trading with multi-market positions.
if position.isLong thenif targetPrice ==0then targetPrice =CurrentPrice(position.market).bidend result =AddPercentage(AverageEnterPrice(position.positionId), percentage) < targetPriceend
Nice! Now our targetPrice will never be zero and we don't even have to give it an input.
Let's do the same thing for Short positions now. But instead of using the sell price (bid), we will use the buy price (ask) and flip the logic.
Remember to save your work often! Saving wont only keep your work from disappearing, but will also compile the script and show possible errors as you go.
And that's that for the logic part. Simple, but effective!
Here's how the full script should look now:
-- ---------------------------------------- Command-- --------------------------------------DefineCommand('PercentagePriceChange', -- Name'Custom insurance. Returns true if trade is allowed, otherwise false.' -- Description )-- ---------------------------------------- Parameters-- --------------------------------------local percentage =DefineParameter( NumberType,'percentage','Minimum percentage change before a trade is allowed.',true,0,'Input' )local targetPrice =DefineParameter( NumberType,'targetPrice','The target price of the trade. Default is the current buy or sell price.',false,0,'Number, Input, BidPrices, AskPrices' )local positionId =DefineParameter( StringType,'positionId','Optional unique identifier. Required when the bot is trading multiple position at once.',false,'','SessionGet, Load' )-- ---------------------------------------- Logic-- ---------------------------------------- Internal variableslocal position =PositionContainer(positionId) -- Position informationlocal result =false-- Our result value-- Make sure percentage is properly setpercentage =Abs(percentage)if percentage >0then-- Simple optimization-- Run logicif position.isLong then-- Long positionif targetPrice ==0then targetPrice =CurrentPrice(position.market).bidend result =AddPercentage(AverageEnterPrice(position.positionId), percentage) < targetPriceelseif position.isShort then-- Short positionif targetPrice ==0then targetPrice =CurrentPrice(position.market).askend result =SubPercentage(AverageEntryPrice(position.positionId), percentage) > targetPriceendelse-- Allow trade result =trueend-- ---------------------------------------- Output-- ---------------------------------------- code here...
Command output
Okay, we are getting closer. In this last part all we will do is to define the output for the command. This is what the command will return when used. In our case, we will be returning the result variable as a parameter type BooleanType. I will be listing some output's suggestions that I think could be useful with our command.
There are plenty of other output types for you to use.
You can find these by typing ParameterEnums in the editor or checking out the Cheat Sheet.
DefineOutput(-- Output type: BooleanType,-- Output value: result,-- Description:'True if trade is allowed, otherwise false.',-- Output's suggestions:'InsuranceContainer, IfElse, And, Or')
Awesome! Simple as that! Now you have yourself a fully functioning insurance command that you can play around and do whatever you want with it!
Congratulations! Pat yourself on a shoulder - you've earned it!
Full script
Here are the full scripts of the tutorial; one with comments, one without.
With comments
-- ---------------------------------------- Command-- --------------------------------------DefineCommand('PercentagePriceChange', -- Name'Custom insurance. Returns true if trade is allowed, otherwise false.' -- Description )-- ---------------------------------------- Parameters-- --------------------------------------local percentage =DefineParameter( NumberType,'percentage','Minimum percentage change before a trade is allowed.',true,0,'Input' )local targetPrice =DefineParameter( NumberType,'targetPrice','The target price of the trade. Default is the current buy or sell price.',false,0,'Number, Input, BidPrices, AskPrices' )local positionId =DefineParameter( StringType,'positionId','Optional unique identifier. Required when the bot is trading multiple position at once.',false,'','SessionGet, Load' )-- ---------------------------------------- Logic-- ---------------------------------------- Internal variableslocal position =PositionContainer(positionId) -- Position informationlocal result =false-- Our result value-- Make sure percentage is properly setpercentage =Abs(percentage)if percentage >0then-- Simple optimization-- Run logicif position.isLong then-- Long positionif targetPrice ==0then targetPrice =CurrentPrice(position.market).bidend result =AddPercentage(AverageEnterPrice(position.positionId), percentage) < targetPriceelseif position.isShort then-- Short positionif targetPrice ==0then targetPrice =CurrentPrice(position.market).askend result =SubPercentage(AverageEntryPrice(position.positionId), percentage) > targetPriceendelse-- Allow trade result =trueend-- ---------------------------------------- Output-- --------------------------------------DefineOutput(-- Output type: BooleanType,-- Output value: result,-- Description:'True if trade is allowed, otherwise false.',-- Output's suggestions:'InsuranceContainer, IfElse, And, Or')
Compact without comments
-- ---------------------------------------- Command-- --------------------------------------DefineCommand('PercentagePriceChange', 'Custom insurance. Returns true if trade is allowed, otherwise false.')-- ---------------------------------------- Parameters-- --------------------------------------local percentage =DefineParameter(NumberType, 'percentage', 'Minimum percentage change before a trade is allowed.', true, 0, 'Input')local targetPrice =DefineParameter(NumberType, 'targetPrice', 'The target price of the trade. Default is the current buy or sell price.', false, 0, 'Number, Input, BidPrices, AskPrices')local positionId =DefineParameter(StringType, 'positionId', 'Optional unique identifier. Required when the bot is trading multiple position at once.', false, '', 'SessionGet, Load')-- ---------------------------------------- Logic-- --------------------------------------local position =PositionContainer(positionId)local result =falsepercentage =Abs(percentage)if percentage >0thenif position.isLong thenif targetPrice ==0then targetPrice =CurrentPrice(position.market).bidend result =AddPercentage(AverageEnterPrice(position.positionId), percentage) < targetPriceelseif position.isShort thenif targetPrice ==0then targetPrice =CurrentPrice(position.market).askend result =SubPercentage(AverageEntryPrice(position.positionId), percentage) > targetPriceendelse result =trueend-- ---------------------------------------- Output-- --------------------------------------DefineOutput(BooleanType, result, 'True if trade is allowed, otherwise false.', 'InsuranceContainer, IfElse, And, Or')
Testing the command
To test our custom command we will be creating a very, very basic scalper. It will use MFI and make a buy trade when MFI is below 20. This code snippet should be created and run on its own script, not in the insurance script.