11# Name: ts2os.py
2- # Version: 1.0 - 2024/08/05
2+ # Version: 1.1 - 2024/08/29
33# Description: Run with python ./ts2os.py, when the prompt comes up, copy and paste the lines from the trade steward bot log for the fill.
4- # E.g. Leg 1: Sell To Open SPXW 07/18/24 5650P @ $21.13 (21.20/21.50); 49.4 Delta
5- # Leg 2: Buy To Open SPXW 07/18/24 5620P @ $10.35 (10.40/10.70); 29.3 Delta
6- # Leg 3: Buy To Open SPXW 07/16/24 5620P @ $2.67 (2.70/2.80); 16.9 Delta
4+ # E.g. Leg 1: Sell to Open -1x SPXW 08/29/24 5545P @ $4.25 (4.20/4.30); 12.8 Delta
5+ # Leg 2: Buy to Open 1x SPXW 08/30/24 5545P @ $7.12 (7.00/7.10); 16.7 Delta
6+ # Leg 3: Sell to Open -1x SPXW 08/29/24 5685C @ $4.55 (4.50/4.60); 14.5 Delta
7+ # Leg 4: Buy to Open 1x SPXW 08/30/24 5685C @ $8.08 (8.00/8.20); 19.6 Delta
78#
89# Once input is done, press enter on an empty line. There's no error checking. Quick and dirty...
10+ #
11+ # Changelog:
12+ # V 1.1 - 2024/08/29
13+ # - Added number of legs per option
14+ #
15+ # V 1.0 - 2024/08/05
16+ # - Initial release
917import re
18+ import math
1019
1120class Option :
1221 def __init__ (self , stringInput ):
@@ -16,38 +25,45 @@ def __init__ (self, stringInput):
1625 self .quantity = 0
1726 self .ticker = None
1827 self .premium = None
28+ self .gcd = 1
1929 self .processString (stringInput )
2030
2131 def processString (self , stringInput ):
2232 # Parse a string from TradeSteward's bot log
23- reResult = re .search (r'\w+: (Sell|Buy) To Open (\w+) (\d+[/]\d+[/]\d+) (\d+)(C|P) [@] [$](\d+[.]?\d+)' , stringInput )
24- if "Sell" in ( reResult [ 1 ]):
25- self . quantity = - 1
26- elif "Buy" in reResult [1 ]:
27- self .quantity = 1
33+ reResult = re .search (r'\w+: (Sell|Buy) to Open ([-]*\d+)x (\w+) (\d+[/]\d+[/]\d+) (\d+)(C|P) [@] [$](\d+[.]?\d+)' , stringInput )
34+
35+ # Quantity
36+ self . quantity = int ( reResult [2 ])
37+ print ( "Quantity is: " , reResult [ 2 ], " Processed:" , self .quantity )
2838
2939 # Ticker
30- self .ticker = reResult [2 ]
40+ self .ticker = reResult [3 ]
3141
3242 # Date
33- dateArray = re .search (r'(\d+)[/](\d+)[/](\d+)' , reResult [3 ])
43+ dateArray = re .search (r'(\d+)[/](\d+)[/](\d+)' , reResult [4 ])
3444 dateString = dateArray [3 ]+ dateArray [1 ]+ dateArray [2 ]
3545 self .expiration = dateString
3646
3747 # Strike
38- self .strike = reResult [4 ]
48+ self .strike = reResult [5 ]
3949
4050 # Type
41- self .type = reResult [5 ]
51+ self .type = reResult [6 ]
4252
4353 # Premium
44- self .premium = reResult [6 ]
54+ self .premium = reResult [7 ]
55+
56+ def getQuantity (self ):
57+ return self .quantity
58+
59+ def setQuantityDivisor (self , gcd ):
60+ self .gcd = gcd
4561
4662 def getOSString (self ):
4763 stringOut = ""
4864 if (self .quantity < 0 ):
4965 stringOut = "-"
50- stringOut = stringOut + "." + self .ticker + self .expiration + self .type + self .strike + "x" + str (abs (self .quantity ))+ "@" + self .premium
66+ stringOut = stringOut + "." + self .ticker + self .expiration + self .type + self .strike + "x" + str (int ( abs (self .quantity ) / self . gcd ))+ "@" + self .premium
5167 return stringOut
5268
5369
@@ -68,9 +84,16 @@ def getOSString(self):
6884 baseURL = "https://optionstrat.com/build/custom/" + baseTicker [baseTicker .lastindex ] + "/"
6985 fullURL = baseURL
7086 optCount = 0
87+ gcdList = []
88+ for opt in options :
89+ gcdList .append (abs (opt .getQuantity ()))
90+
91+ gcd = math .gcd (* gcdList )
92+
7193 for opt in options :
7294 if optCount > 0 :
7395 fullURL = fullURL + ","
96+ opt .setQuantityDivisor (gcd )
7497 fullURL = fullURL + opt .getOSString ()
7598 optCount = optCount + 1
7699
0 commit comments