Create Function that Calculates a Value Relative to Original Price and Also Constructs a Price Ladder

censo

Board Regular
Joined
Dec 25, 2015
Messages
161
Office Version
  1. 2013
Platform
  1. Windows
PREFACE

In options trading, a price ladder shows how much profit or loss (percent & dollar) is realized relative to current contract price. These figures are calculated by comparing the new price of a contract to the "base" or entry price.

Note: If the details below are too wordy or TL;DR, I provided a link to an explainer video with visual examples.


BACKGROUND

- New price is the point at which a trade is closed (this can be positive or negative, depending on how the trade went relative to the entry price).

- If new price is higher than original price, a profit is realized.

- If new price is lower than original price, a loss is realized.

- Contract prices are always multiplied by 100.

- The entire cost of a trade is calculated in this manner: contract price x 100 x quantity of contracts.

- On a price ladder, contract price moves up or down based on a user selected drop down cell (D2) (meaning, values go up or down by either .01 or .10)

- The values of the "P/L OPEN %" and "P/L OPEN $" on the price ladder are created based on the entry price (the key value from which all calculations are derived).

- As part of risk management, a stop loss prevents a trade from experiencing a loss greater than what is planned in the event the trade goes in the negative direction.


EXAMPLES

Original or "entry" contract price = $7.50 (x100) = $750

Qty contracts = 5

Total contract cost = 750*5 = $3,750


New or "exit" contract price = $8.30

Dollar Profit = ((8.30-7.50)*100)*5 = $400

Percent Profit = (8.30/7.5)-1 = 10.67%


Regarding stop loss, although the planned Stop Loss amount in C2 is $457, the correct contract price for this stop loss amount is 6.60 (A89) because it is okay to be below that amount ($450 in cell C89), not over it.

For example the contract price of 6.50 would exceed the stop loss because at that level, the loss would be $500 (C90) and that exceeds the stop loss amount of $457.



THE PROBLEM

The price ladder has to be created manually and sometimes I may not want to refer to an actual price ladder but rather, have the information I need automatically populated with a mathematical formula.



REQUESTED SOLUTIONS

#1 - To serve as a visual aid, create a function that when values A2:C2 are provided, a price ladder is automatically created (100% to the positive and 100% to the negative, as shown). The solution must account for the user defined input D2 (this value determines how the prices increase or decrease. In the example shown, price increases or decreases every $0.10 but if $0.01 is chosen from the dropdown, then the price ladder should reflect accordingly).

#1a - Since I want the population of the price ladder to be optional to the user, the formula must look for a TRUE value by way of a checkbox (E2). If the checkbox is ticked, populate the price ladder. If the checkbox is empty, do not populate the price ladder.

#1b - On the actual price ladder, the original (entry) price would have conditional formatting of YELLOW (as found in cell A2, which correlates to cell A80 in this example).

#1c - On the actual price ladder, the stop loss price would have conditional formatting of RED (as found in cell G2, which correlates to cell A89 in this example).


#2 - When values A2:C2 are provided, a contract price representing a stop loss level is populated in cell G2. This formula should be independent of the price ladder, meaning, If the price ladder is not present (no vertical or other type of lookup functions), the value would be derived mathematically.



EXPLAINER VIDEO

ONLINE SHEETS VERSION

EXCEL VERSION

Price Ladder.xlsx
ABCDEFGHIJ
1Contract Price (x 100)QTYPlanned Stop LossIncrement / DecrementDisplay Price Ladder?Position SizeContract Price Stop LossLegend
2750.0054570.13,750.00Entry Price
3Stop Loss
4Contract PriceP/L Open %P/L Open $
515.00100.00%3750
614.9098.67%3700
714.8097.33%3650
814.7096.00%3600
914.6094.67%3550
1014.5093.33%3500
1114.4092.00%3450
1214.3090.67%3400
1314.2089.33%3350
1414.1088.00%3300
1514.0086.67%3250
1613.9085.33%3200
1713.8084.00%3150
1813.7082.67%3100
1913.6081.33%3050
2013.5080.00%3000
2113.4078.67%2950
2213.3077.33%2900
2313.2076.00%2850
2413.1074.67%2800
2513.0073.33%2750
2612.9072.00%2700
2712.8070.67%2650
2812.7069.33%2600
2912.6068.00%2550
3012.5066.67%2500
3112.4065.33%2450
3212.3064.00%2400
3312.2062.67%2350
3412.1061.33%2300
3512.0060.00%2250
3611.9058.67%2200
3711.8057.33%2150
3811.7056.00%2100
3911.6054.67%2050
4011.5053.33%2000
4111.4052.00%1950
4211.3050.67%1900
4311.2049.33%1850
4411.1048.00%1800
4511.0046.67%1750
4610.9045.33%1700
4710.8044.00%1650
4810.7042.67%1600
4910.6041.33%1550
5010.5040.00%1500
5110.4038.67%1450
5210.3037.33%1400
5310.2036.00%1350
5410.1034.67%1300
5510.0033.33%1250
569.9032.00%1200
579.8030.67%1150
589.7029.33%1100
599.6028.00%1050
609.5026.67%1000
619.4025.33%950
629.3024.00%900
639.2022.67%850
649.1021.33%800
659.0020.00%750
668.9018.67%700
678.8017.33%650
688.7016.00%600
698.6014.67%550
708.5013.33%500
718.4012.00%450
728.3010.67%400
738.209.33%350
748.108.00%300
758.006.67%250
767.905.33%200
777.804.00%150
787.702.67%100
797.601.33%50
807.500.00%0
817.40-1.33%-50
827.30-2.67%-100
837.20-4.00%-150
847.10-5.33%-200
857.00-6.67%-250
866.90-8.00%-300
876.80-9.33%-350
886.70-10.67%-400
896.60-12.00%-450
906.50-13.33%-500
916.40-14.67%-550
926.30-16.00%-600
936.20-17.33%-650
946.10-18.67%-700
956.00-20.00%-750
965.90-21.33%-800
975.80-22.67%-850
985.70-24.00%-900
995.60-25.33%-950
1005.50-26.67%-1000
1015.40-28.00%-1050
1025.30-29.33%-1100
1035.20-30.67%-1150
1045.10-32.00%-1200
1055.00-33.33%-1250
1064.90-34.67%-1300
1074.80-36.00%-1350
1084.70-37.33%-1400
1094.60-38.67%-1450
1104.50-40.00%-1500
1114.40-41.33%-1550
1124.30-42.67%-1600
1134.20-44.00%-1650
1144.10-45.33%-1700
1154.00-46.67%-1750
1163.90-48.00%-1800
1173.80-49.33%-1850
1183.70-50.67%-1900
1193.60-52.00%-1950
1203.50-53.33%-2000
1213.40-54.67%-2050
1223.30-56.00%-2100
1233.20-57.33%-2150
1243.10-58.67%-2200
1253.00-60.00%-2250
1262.90-61.33%-2300
1272.80-62.67%-2350
1282.70-64.00%-2400
1292.60-65.33%-2450
1302.50-66.67%-2500
1312.40-68.00%-2550
1322.30-69.33%-2600
1332.20-70.67%-2650
1342.10-72.00%-2700
1352.00-73.33%-2750
1361.90-74.67%-2800
1371.80-76.00%-2850
1381.70-77.33%-2900
1391.60-78.67%-2950
1401.50-80.00%-3000
1411.40-81.33%-3050
1421.30-82.67%-3100
1431.20-84.00%-3150
1441.10-85.33%-3200
1451.00-86.67%-3250
1460.90-88.00%-3300
1470.80-89.33%-3350
1480.70-90.67%-3400
1490.60-92.00%-3450
1500.50-93.33%-3500
1510.40-94.67%-3550
1520.30-96.00%-3600
1530.20-97.33%-3650
1540.10-98.67%-3700
1550.00-100.00%-3750
Sheet1
Cell Formulas
RangeFormula
B5:B155B5=A5/$A$80-1
C5:C155C5=((A5-$A$80)*100)*$B$2
 

Excel Facts

Difference between two dates
Secret function! Use =DATEDIF(A2,B2,"Y")&" years"&=DATEDIF(A2,B2,"YM")&" months"&=DATEDIF(A2,B2,"MD")&" days"
Hi censo. You can trial this. Seems to work with my limited testing. Unfortunately, the math part of the stop loss is not included (#2 above). HTH. Dave
Code:
Sub OptionTest()
Dim RowAmt As Integer, LastRow As Integer
'clean up previous
With Sheets("Sheet1")
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).ClearContents
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).Interior.ColorIndex = xlColorIndexNone
End With
'determine iterations
RowAmt = (((Sheets("sheet1").Range("A2") / 100) / Sheets("sheet1").Range("D2")) * 2)
'set initial values
Sheets("sheet1").Range("A" & RowAmt + 5) = 0
Sheets("sheet1").Range("B" & RowAmt + 5) = -100
Sheets("sheet1").Range("B" & RowAmt + 5).NumberFormat = "0.00%"
Sheets("sheet1").Range("C" & RowAmt + 5) = ((0 - (Sheets("sheet1").Range("A2") / 100)) * 100) * Sheets("sheet1").Range("B2")
'create ladder
For cnt = (RowAmt + 4) To 5 Step -1
Sheets("sheet1").Range("A" & cnt) = Sheets("sheet1").Range("A" & (cnt + 1)) + Sheets("sheet1").Range("D2")
Sheets("sheet1").Range("A" & cnt).NumberFormat = "##0.00"
Sheets("sheet1").Range("B" & cnt) = Round((Sheets("sheet1").Range("A" & cnt) / (Sheets("sheet1").Range("A2") / 100) - 1), 2)
Sheets("sheet1").Range("B" & cnt).NumberFormat = "0.00%"
Sheets("sheet1").Range("C" & cnt) = ((Sheets("sheet1").Range("A" & cnt) - _
                                      (Sheets("sheet1").Range("A2") / 100)) * 100) * Sheets("sheet1").Range("B2")
'mark price yellow
If Round(Sheets("sheet1").Range("A" & cnt), 2) = Sheets("sheet1").Range("A2") / 100 Then
Sheets("sheet1").Range("A" & cnt).Interior.ColorIndex = 6
Sheets("sheet1").Range("C" & cnt) = 0
End If
'mark stop loss red
If (-Sheets("sheet1").Range("C" & cnt) = -(Sheets("sheet1").Range("C2"))) Or _
(Sheets("sheet1").Range("C" & cnt + 1) < -(Sheets("sheet1").Range("C2"))) And _
                ((Sheets("sheet1").Range("C" & cnt) > -(Sheets("sheet1").Range("C2")))) Then
Sheets("sheet1").Range("A" & cnt).Interior.ColorIndex = 3
Sheets("sheet1").Range("G2") = Sheets("sheet1").Range("A" & cnt)
Sheets("sheet1").Range("G2").NumberFormat = "##0.00"
End If
Next cnt
End Sub
 
Upvote 0
Hi censo. You can trial this. Seems to work with my limited testing. Unfortunately, the math part of the stop loss is not included (#2 above). HTH. Dave

Excellent work Dave. The construction of the price ladder is EXACTLY what I was looking for. However, there are some tweaks I'm hoping you can help me make:

- The code only appears to work when an existing price ladder is already in place. To discover this, I deleted all of the values beginning on row 5 and below, ran the macro and the ladder did not populate. What modification can be done to the code to fix this?

- In column B, percentages for all amounts should round only to the hundredths position (2 places to the right of the decimal). As an example, using the same figures in the sample table provided in my original post, the percentage for B72 should read 10.67% vs. 11%.

- Is it possible to snap to the section on the spreadsheet where the entry price is highlighted? (saves user from having to scroll down to find it)

- Since we went the VBA route, can you include a separate Sub that I can use to clear the results? That way I can configure 'Execute' & 'Clear' macro buttons to make the ladder appear and disappear on command.

Thanks in advance.
 
Last edited:
Upvote 0
A few tweeks. I changed the sub to a function which now allows you to just update G2(stop loss price) without displaying the ladder. I have no idea how to create a "snap to the highlighted price section. Perhaps others may help with that one. Everything else seems to be resolved as you requested. HTH. Dave
Code:
Function OptionTest(ShowLadder As Boolean)
Dim RowAmt As Integer, LastRow As Integer
'ShowLadder = true to show Ladder
'Showladder = false to Not show ladder ie. only update G2(stop loss price)

Application.ScreenUpdating = False
'clean up previous
With Sheets("Sheet1")
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
If LastRow < 5 Then
LastRow = 5
End If
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).ClearContents
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).Interior.ColorIndex = xlColorIndexNone
End With
'determine iterations
RowAmt = (((Sheets("sheet1").Range("A2") / 100) / Sheets("sheet1").Range("D2")) * 2)
'set initial values
Sheets("sheet1").Range("A" & RowAmt + 5) = 0
Sheets("sheet1").Range("B" & RowAmt + 5) = -0.01
Sheets("sheet1").Range("B" & RowAmt + 5).NumberFormat = "0.00%"
Sheets("sheet1").Range("C" & RowAmt + 5) = ((0 - (Sheets("sheet1").Range("A2") / 100)) * 100) * Sheets("sheet1").Range("B2")
'create ladder
For cnt = (RowAmt + 4) To 5 Step -1
Sheets("sheet1").Range("A" & cnt) = Sheets("sheet1").Range("A" & (cnt + 1)) + Sheets("sheet1").Range("D2")
Sheets("sheet1").Range("A" & cnt).NumberFormat = "##0.00"
Sheets("sheet1").Range("B" & cnt) = (Sheets("sheet1").Range("A" & cnt) / (Sheets("sheet1").Range("A2") / 100) - 1)
Sheets("sheet1").Range("B" & cnt).NumberFormat = "0.00%"
Sheets("sheet1").Range("C" & cnt) = ((Sheets("sheet1").Range("A" & cnt) - _
                                      (Sheets("sheet1").Range("A2") / 100)) * 100) * Sheets("sheet1").Range("B2")
'mark price yellow
If Round(Sheets("sheet1").Range("A" & cnt), 2) = Sheets("sheet1").Range("A2") / 100 Then
Sheets("sheet1").Range("A" & cnt).Interior.ColorIndex = 6
Sheets("sheet1").Range("C" & cnt) = 0
End If
'mark stop loss red
If (-Sheets("sheet1").Range("C" & cnt) = -(Sheets("sheet1").Range("C2"))) Or _
(Sheets("sheet1").Range("C" & cnt + 1) < -(Sheets("sheet1").Range("C2"))) And _
                ((Sheets("sheet1").Range("C" & cnt) > -(Sheets("sheet1").Range("C2")))) Then
Sheets("sheet1").Range("A" & cnt).Interior.ColorIndex = 3
Sheets("sheet1").Range("G2") = Sheets("sheet1").Range("A" & cnt)
Sheets("sheet1").Range("G2").NumberFormat = "##0.00"
End If
Next cnt
If Not ShowLadder Then
With Sheets("Sheet1")
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).ClearContents
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).Interior.ColorIndex = xlColorIndexNone
End With
End If
Application.ScreenUpdating = False
End Function
To operate....
Code:
Call OptionTest(True) ' show ladder
Call OptionTest(False) 'don't show ladder. Update stop loss price only
To clear the Ladder only...
Code:
Sub ClearLadder()
'clean up previous
With Sheets("Sheet1")
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
If LastRow < 5 Then
LastRow = 5
End If
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).ClearContents
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).Interior.ColorIndex = xlColorIndexNone
End With
End Sub
 
Upvote 0
A bit more testing. I hadn't trialed when the stop loss price was equal to a "C" value. This works. Dave
Code:
Function OptionTest(ShowLadder As Boolean)
Dim RowAmt As Integer, LastRow As Integer, Flag As Boolean
'ShowLadder = true to show Ladder
'Showladder = false to Not show ladder ie. only update G2(stop loss price)
Flag = False
Application.ScreenUpdating = False
'clean up previous
With Sheets("Sheet1")
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
If LastRow < 5 Then
LastRow = 5
End If
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).ClearContents
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).Interior.ColorIndex = xlColorIndexNone
End With
'determine iterations
RowAmt = (((Sheets("sheet1").Range("A2") / 100) / Sheets("sheet1").Range("D2")) * 2)
'set initial values
Sheets("sheet1").Range("A" & RowAmt + 5) = 0
Sheets("sheet1").Range("B" & RowAmt + 5) = -0.01
Sheets("sheet1").Range("B" & RowAmt + 5).NumberFormat = "0.00%"
Sheets("sheet1").Range("C" & RowAmt + 5) = ((0 - (Sheets("sheet1").Range("A2") / 100)) * 100) * Sheets("sheet1").Range("B2")
'create ladder
For cnt = (RowAmt + 4) To 5 Step -1
Sheets("sheet1").Range("A" & cnt) = Sheets("sheet1").Range("A" & (cnt + 1)) + Sheets("sheet1").Range("D2")
Sheets("sheet1").Range("A" & cnt).NumberFormat = "##0.00"
Sheets("sheet1").Range("B" & cnt) = (Sheets("sheet1").Range("A" & cnt) / (Sheets("sheet1").Range("A2") / 100) - 1)
Sheets("sheet1").Range("B" & cnt).NumberFormat = "0.00%"
Sheets("sheet1").Range("C" & cnt) = ((Sheets("sheet1").Range("A" & cnt) - _
                                      (Sheets("sheet1").Range("A2") / 100)) * 100) * Sheets("sheet1").Range("B2")
'mark price yellow
If Round(Sheets("sheet1").Range("A" & cnt), 2) = Sheets("sheet1").Range("A2") / 100 Then
Sheets("sheet1").Range("A" & cnt).Interior.ColorIndex = 6
Sheets("sheet1").Range("C" & cnt) = 0
End If
'mark stop loss red
If Not Flag Then
If (Round(Sheets("sheet1").Range("C" & cnt)) = Round(-Sheets("sheet1").Range("C2"))) Or _
(Sheets("sheet1").Range("C" & cnt + 1) < -(Sheets("sheet1").Range("C2"))) And _
                ((Sheets("sheet1").Range("C" & cnt) > -(Sheets("sheet1").Range("C2")))) Then
Sheets("sheet1").Range("A" & cnt).Interior.ColorIndex = 3
Sheets("sheet1").Range("G2") = Sheets("sheet1").Range("A" & cnt)
Sheets("sheet1").Range("G2").NumberFormat = "##0.00"
Flag = True
End If
End If
Next cnt
If Not ShowLadder Then
With Sheets("Sheet1")
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).ClearContents
.Range(.Cells(5, "A"), .Cells(LastRow, "C")).Interior.ColorIndex = xlColorIndexNone
End With
End If
Application.ScreenUpdating = False
End Function
 
Upvote 1
Solution
A bit more testing. I hadn't trialed when the stop loss price was equal to a "C" value. This works. Dave
Thanks for providing an update. How does the function different from the sub? If I understand correctly, entering a value in G2 activates the function?

If so, G2 is a value I need the solution to provide (like your first contribution, works beautifully). The updated one you provided with the function I couldn't get it to do anything, even with the revised one. Am I doing something wrong?

What I did was created a separate .xlsm version of the original, ALT+F11, replaced the existing code with the new one, closed the VBA editor, saved the Excel file, and then what do I do next? I entered values into cells A2:D2 and nothing happened.

One thing I want to note, I manually deleted the existing ladder information that was there previously. Does it need to be present in order to work properly? Otherwise, how do I activate the function?
 
Upvote 0
I have no idea how to create a "snap to the highlighted price section.
Perhaps I may have used the wrong terminology. But whenever the correct contract price for the stop loss amount is found (which you've successfully achieved), it would be the equivalent of 'clicking' on it to move the view to that section of the spreadsheet, something similar to like:

Code:
Range("A97").Select
 
Upvote 0
A function is similar to a sub. The output is in G2. Enter the input data as previous and....
Code:
Call OptionTest(True) ' show ladder
'OR
Call OptionTest(False) 'don't show ladder. Update stop loss price only
So, if you have a command button, place the Call code in the command button code and select the command button.

You can trial adding this line for the "snap"...
Code:
'mark price yellow
If Round(Sheets("sheet1").Range("A" & cnt), 2) = Sheets("sheet1").Range("A2") / 100 Then
Sheets("sheet1").Range("A" & cnt).Interior.ColorIndex = 6
Sheets("sheet1").Range("C" & cnt) = 0
Sheets("sheet1").Range("A" & cnt).Select'****new code
End If
Dave
 
Upvote 0
A function is similar to a sub. The output is in G2. Enter the input data as previous and....
Marvelous solution, Dave.

I struggled at first because I did not realize I had to add new Subs to the original module in order to get the 'show ladder' and 'don't show ladder' command buttons to work. Once I entered them below your existing code and assigned them to buttons, everything worked beautifully.

.... welllll, with the exception of the 'snap to' feature. The code correctly highlights the cell, but if the user's cursor is at the top of the spreadsheet where data was entered (A2:D2) the new code doesn't actually move the spreadsheet to that location.

Beggars can't be choosers. I'm excited about the solution and I wholeheartedly thank you for your effort. Greatly appreciate you.


1688141123135.png
 

Attachments

  • 1688141074560.png
    1688141074560.png
    23.6 KB · Views: 14
Upvote 0

Forum statistics

Threads
1,224,816
Messages
6,181,138
Members
453,021
Latest member
Justyna P

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top