Option FanaticOptions, stock, futures, and system trading, backtesting, money management, and much more!

Backtester Development (Part 1)

This mini-series will be a chronicle of backtester development activities. Because so many things are a Python learning experience for me, I think it’s worth documenting them for later review.

I want to start by revisiting the problem I was having with data type conversion. I noted ignorance as to why the problem occurs. My partner filled me in:

     > I think this is an excel issue. Do a right click on the file and use the “open
     > with” option. Use Notepad. You will see that everything is displayed as float…
     > When you open either file with excel, excel creates what looks like an integer.

In other words, this is not actually a problem. Excel makes things look nice, which in this case created an unintentional headache. Having to reformat data from a commercialized vendor source to serve my own purpose should not be surprising.

In the post linked above, I also presented some additional lines to record program duration in a log file. I couldn’t understand why the output data separated by commas was not printing to separate cells in the Excel .csv.

The explanation is the difference between the following two lines:

The commas in L305 are visible only to the Python program. In order to be visible to the application displaying the .csv file, I need to include quotation marks around the commas as if I were printing them (L307).

I enclosed the entire program in a while loop with a new variable timing_count in order to have the program run three times and log multiple elapsed times.

I then assigned current_date in find_long and reset the variable as part of the else block in L77. These were suggestions from Part 11. The program output appears unchanged. Run duration appears consistent and relatively unchanged (as best as I can tell when comparing two sets of three elapsed times each).

The next step is to add the check_second flag (discussed in Part 5), which ended up as a total mess because subsequent debugging took over two hours to seek out a “stupid mistake” (grade-school math terminology) I made in the process.

To refresh your memory especially with regard to the DTE criterion, see second paragraph of Part 6.

My approach to the check_second flag is as follows:

  1. The previous find_long block is split in two: check_second == False and ELSE (implies check_second == True).
  2. False includes a nested if statement that checks DTE criterion (ELSE CONTINUE), 10-multiple criterion, then strike price and 10-multiple (redundant) criteria followed by complete variable assignment including flipping check_second to True.
  3. True (ELSE block) includes a nested if statement that checks for a change in DTE (ELSE CONTINUE), DTE criterion, 10-multiple criterion, then strike price and 10-multiple (redundant) criteria followed by partial variable assignment (SPX price and strike price already assigned), resetting of check_second, assigning find_short to control_flag, and CONTINUE.
  4. The DTE criterion of True has ELSE block that includes: check_second reset, control_flag = find_short, and CONTINUE.

I will resume next time.