@@ -102,37 +102,46 @@ def test_more_kwargs(self):
102
102
self .assertEqual (quiver , expected_quiver )
103
103
104
104
105
- class TestOHLC (TestCase ):
105
+ class TestFinanceCharts (TestCase ):
106
106
107
107
def test_unequal_ohlc_length (self ):
108
108
109
109
# check: PlotlyError if open, high, low, close are not the same length
110
- # for TraceFactory.ohlc_increase and TraceFactory.ohlc_decrease
110
+ # for TraceFactory.create_ohlc and TraceFactory.create_candlestick
111
111
112
112
kwargs = {'open' : [1 ], 'high' : [1 , 3 ],
113
113
'low' : [1 , 2 ], 'close' : [1 , 2 ],
114
114
'direction' : ['increasing' ]}
115
115
self .assertRaises (PlotlyError , tls .TraceFactory .create_ohlc , ** kwargs )
116
+ self .assertRaises (PlotlyError , tls .TraceFactory .create_candlestick ,
117
+ ** kwargs )
116
118
117
119
kwargs = {'open' : [1 , 2 ], 'high' : [1 , 2 , 3 ],
118
120
'low' : [1 , 2 ], 'close' : [1 , 2 ],
119
121
'direction' : ['decreasing' ]}
120
122
self .assertRaises (PlotlyError , tls .TraceFactory .create_ohlc , ** kwargs )
123
+ self .assertRaises (PlotlyError , tls .TraceFactory .create_candlestick ,
124
+ ** kwargs )
121
125
122
126
kwargs = {'open' : [1 , 2 ], 'high' : [2 , 3 ],
123
127
'low' : [0 ], 'close' : [1 , 3 ],
124
128
'direction' : ['increasing' ]}
125
129
self .assertRaises (PlotlyError , tls .TraceFactory .create_ohlc , ** kwargs )
130
+ self .assertRaises (PlotlyError , tls .TraceFactory .create_candlestick ,
131
+ ** kwargs )
126
132
127
133
kwargs = {'open' : [1 , 2 ], 'high' : [2 , 3 ],
128
134
'low' : [1 , 2 ], 'close' : [1 ],
129
135
'direction' : ['decreasing' ]}
130
136
self .assertRaises (PlotlyError , tls .TraceFactory .create_ohlc , ** kwargs )
137
+ self .assertRaises (PlotlyError , tls .TraceFactory .create_candlestick ,
138
+ ** kwargs )
131
139
132
140
def test_direction_arg (self ):
133
141
134
142
# check: PlotlyError if direction is not defined as "increasing" or
135
- # "decreasing"
143
+ # "decreasing" for TraceFactory.create_ohlc and
144
+ # TraceFactory.create_candlestick
136
145
137
146
kwargs = {'open' : [1 , 4 ], 'high' : [1 , 5 ],
138
147
'low' : [1 , 2 ], 'close' : [1 , 2 ],
@@ -141,6 +150,10 @@ def test_direction_arg(self):
141
150
"direction must be defined as "
142
151
"'increasing' or 'decreasing'" ,
143
152
tls .TraceFactory .create_ohlc , ** kwargs )
153
+ self .assertRaisesRegexp (PlotlyError ,
154
+ "direction must be defined as "
155
+ "'increasing' or 'decreasing'" ,
156
+ tls .TraceFactory .create_candlestick , ** kwargs )
144
157
145
158
kwargs = {'open' : [1 , 2 ], 'high' : [1 , 3 ],
146
159
'low' : [1 , 2 ], 'close' : [1 , 2 ],
@@ -149,6 +162,10 @@ def test_direction_arg(self):
149
162
"direction must be defined as "
150
163
"'increasing' or 'decreasing'" ,
151
164
tls .TraceFactory .create_ohlc , ** kwargs )
165
+ self .assertRaisesRegexp (PlotlyError ,
166
+ "direction must be defined as "
167
+ "'increasing' or 'decreasing'" ,
168
+ tls .TraceFactory .create_candlestick , ** kwargs )
152
169
153
170
def test_high_highest_value (self ):
154
171
@@ -168,13 +185,21 @@ def test_high_highest_value(self):
168
185
"is entered in O-H-L-C order" ,
169
186
tls .TraceFactory .create_ohlc ,
170
187
** kwargs )
188
+ self .assertRaisesRegexp (PlotlyError , "Oops! Looks like some of "
189
+ "your high values are less "
190
+ "the corresponding open, "
191
+ "low, or close values. "
192
+ "Double check that your data "
193
+ "is entered in O-H-L-C order" ,
194
+ tls .TraceFactory .create_candlestick ,
195
+ ** kwargs )
171
196
172
197
def test_low_lowest_value (self ):
173
198
174
199
# check: PlotlyError if the "low" value is greater than the
175
200
# corresponding open, high, or close value because if the "low" value
176
201
# is not the lowest (or equal) then the data may have been entered
177
- # incorrectly
202
+ # incorrectly.
178
203
179
204
# create_ohlc_increase
180
205
kwargs = {'open' : [2 , 3 ], 'high' : [4 , 6 ],
@@ -189,6 +214,15 @@ def test_low_lowest_value(self):
189
214
"is entered in O-H-L-C order" ,
190
215
tls .TraceFactory .create_ohlc ,
191
216
** kwargs )
217
+ self .assertRaisesRegexp (PlotlyError ,
218
+ "Oops! Looks like some of "
219
+ "your low values are greater "
220
+ "than the corresponding high"
221
+ ", open, or close values. "
222
+ "Double check that your data "
223
+ "is entered in O-H-L-C order" ,
224
+ tls .TraceFactory .create_candlestick ,
225
+ ** kwargs )
192
226
193
227
def test_one_ohlc_increase (self ):
194
228
@@ -322,3 +356,203 @@ def test_ohlc_increase_and_decrease(self):
322
356
323
357
self .assertEqual (ohlc_data , expected_ohlc_data )
324
358
359
+ def test_one_candlestick_increase (self ):
360
+
361
+ # This should create one "increase" (i.e. close > open) candlestick
362
+
363
+ candl_inc = tls .TraceFactory .create_candlestick (open = [33.0 ],
364
+ high = [33.2 ],
365
+ low = [32.7 ],
366
+ close = [33.1 ],
367
+ direction = "increasing" )
368
+
369
+ expected_candl_inc = [
370
+ {'name' : 'Increasing' ,
371
+ 'x' : [0.8 , 0.8 , None ],
372
+ 'y' : (33.1 , 33.0 , None ),
373
+ 'type' : 'scatter' ,
374
+ 'showlegend' : False ,
375
+ 'mode' : 'lines' ,
376
+ 'legendgroup' : 'Increasing' ,
377
+ 'line' : {'color' : 'rgb(44, 160, 44)' }},
378
+ {'name' : 'Increasing' ,
379
+ 'x' : [1.2 , 1.2 , None ],
380
+ 'y' : (33.1 , 33.0 , None ),
381
+ 'type' : 'scatter' ,
382
+ 'fill' : 'tonextx' ,
383
+ 'showlegend' : False ,
384
+ 'line' : {'color' : 'rgb(44, 160, 44)' },
385
+ 'legendgroup' : 'Increasing' ,
386
+ 'mode' : 'lines' },
387
+ {'name' : 'Increasing' ,
388
+ 'x' : [1 , 1 , None , 1.2 , 0.8 , None , 0.8 , 1.2 , None ],
389
+ 'y' : [33.2 , 32.7 , None , 33.1 , 33.1 , None , 33.0 , 33.0 , None ],
390
+ 'text' : ('High' , 'Low' , None ,
391
+ 'Close' , 'Close' , None ,
392
+ 'Open' , 'Open' , None ),
393
+ 'type' : 'scatter' ,
394
+ 'mode' : 'lines' ,
395
+ 'legendgroup' : 'Increasing' ,
396
+ 'line' : {'color' : 'rgb(44, 160, 44)' }}
397
+ ]
398
+ self .assertEqual (candl_inc , expected_candl_inc )
399
+
400
+ def test_one_candlestick_decrease (self ):
401
+
402
+ # This should create one "decrease" (i.e. close < open) ohlc stick
403
+
404
+ candl_dec = tls .TraceFactory .create_candlestick (open = [33.3 ],
405
+ high = [33.3 ],
406
+ low = [32.7 ],
407
+ close = [32.9 ],
408
+ direction = "decreasing" )
409
+
410
+ expected_candl_dec = [
411
+ {'name' : 'Decreasing' ,
412
+ 'x' : [0.8 , 0.8 , None ],
413
+ 'y' : (32.9 , 33.3 , None ),
414
+ 'type' : 'scatter' ,
415
+ 'showlegend' : False ,
416
+ 'mode' : 'lines' ,
417
+ 'legendgroup' : 'Decreasing' ,
418
+ 'line' : {'color' : 'rgb(214, 39, 40)' }},
419
+ {'name' : 'Decreasing' ,
420
+ 'x' : [1.2 , 1.2 , None ],
421
+ 'y' : (32.9 , 33.3 , None ),
422
+ 'type' : 'scatter' ,
423
+ 'fill' : 'tonextx' ,
424
+ 'showlegend' : False ,
425
+ 'line' : {'color' : 'rgb(214, 39, 40)' },
426
+ 'legendgroup' : 'Decreasing' , 'mode' : 'lines' },
427
+ {'name' : 'Decreasing' ,
428
+ 'x' : [1 , 1 , None , 1.2 , 0.8 , None , 0.8 , 1.2 , None ],
429
+ 'y' : [33.3 , 32.7 , None , 32.9 , 32.9 , None , 33.3 , 33.3 , None ],
430
+ 'text' : ('High' , 'Low' , None ,
431
+ 'Close' , 'Close' , None ,
432
+ 'Open' , 'Open' , None ),
433
+ 'type' : 'scatter' ,
434
+ 'mode' : 'lines' ,
435
+ 'legendgroup' : 'Decreasing' ,
436
+ 'line' : {'color' : 'rgb(214, 39, 40)' }}]
437
+ self .assertEqual (candl_dec , expected_candl_dec )
438
+
439
+ def test_candlestick_increase_and_decrease (self ):
440
+
441
+ # This should add multiple increasing and decreasing candlesticks
442
+ # and check that what we expect (i.e. the data and kwargs)
443
+ # is resulting from data = candl_inc data.extend(candl_dec)
444
+
445
+ o = [3.3 , 4 , 9.3 , 8.9 , 4.9 , 9 , 2.9 , 5 ]
446
+ h = [7 , 6.4 , 10 , 10 , 10 , 14.6 , 12 , 7 ]
447
+ l = [3 , 2 , 7 , 3 , 2 , 2 , 1.1 , 2.3 ]
448
+ c = [3.3 , 6.3 , 10 , 9 , 9.2 , 3 , 2.9 , 6.1 ]
449
+
450
+ candl_inc = tls .TraceFactory .create_candlestick (o , h , l , c ,
451
+ direction = 'increasing' ,
452
+ name = 'positive' )
453
+ candl_dec = tls .TraceFactory .create_candlestick (o , h , l , c ,
454
+ direction = 'decreasing' ,
455
+ name = 'negative' )
456
+ candl_data = candl_inc
457
+ candl_data .extend (candl_dec )
458
+
459
+ expected_candl_data = [
460
+ {'name' : 'positive' , 'x' : [1.8 , 1.8 , None ],
461
+ 'y' : (6.3 , 4 , None ), 'type' : 'scatter' , 'showlegend' : False ,
462
+ 'mode' : 'lines' , 'legendgroup' : 'Increasing' ,
463
+ 'line' : {'color' : 'rgb(44, 160, 44)' }},
464
+ {'name' : 'positive' , 'x' : [2.2 , 2.2 , None ], 'y' : (6.3 , 4 , None ),
465
+ 'type' : 'scatter' , 'fill' : 'tonextx' , 'showlegend' : False ,
466
+ 'line' : {'color' : 'rgb(44, 160, 44)' },
467
+ 'legendgroup' : 'Increasing' , 'mode' : 'lines' },
468
+ {'name' : 'positive' , 'x' : [2.8 , 2.8 , None ], 'y' : (10 , 9.3 , None ),
469
+ 'type' : 'scatter' , 'showlegend' : False , 'mode' : 'lines' ,
470
+ 'legendgroup' : 'Increasing' ,
471
+ 'line' : {'color' : 'rgb(44, 160, 44)' }},
472
+ {'name' : 'positive' , 'x' : [3.2 , 3.2 , None ], 'y' : (10 , 9.3 , None ),
473
+ 'type' : 'scatter' , 'fill' : 'tonextx' , 'showlegend' : False ,
474
+ 'line' : {'color' : 'rgb(44, 160, 44)' },
475
+ 'legendgroup' : 'Increasing' , 'mode' : 'lines' },
476
+ {'name' : 'positive' , 'x' : [3.8 , 3.8 , None ], 'y' : (9 , 8.9 , None ),
477
+ 'type' : 'scatter' , 'showlegend' : False , 'mode' : 'lines' ,
478
+ 'legendgroup' : 'Increasing' ,
479
+ 'line' : {'color' : 'rgb(44, 160, 44)' }},
480
+ {'name' : 'positive' , 'x' : [4.2 , 4.2 , None ], 'y' : (9 , 8.9 , None ),
481
+ 'type' : 'scatter' , 'fill' : 'tonextx' , 'showlegend' : False ,
482
+ 'line' : {'color' : 'rgb(44, 160, 44)' },
483
+ 'legendgroup' : 'Increasing' , 'mode' : 'lines' },
484
+ {'name' : 'positive' , 'x' : [4.8 , 4.8 , None ], 'y' : (9.2 , 4.9 , None ),
485
+ 'type' : 'scatter' , 'showlegend' : False , 'mode' : 'lines' ,
486
+ 'legendgroup' : 'Increasing' ,
487
+ 'line' : {'color' : 'rgb(44, 160, 44)' }},
488
+ {'name' : 'positive' , 'x' : [5.2 , 5.2 , None ], 'y' : (9.2 , 4.9 , None ),
489
+ 'type' : 'scatter' , 'fill' : 'tonextx' , 'showlegend' : False ,
490
+ 'line' : {'color' : 'rgb(44, 160, 44)' },
491
+ 'legendgroup' : 'Increasing' , 'mode' : 'lines' },
492
+ {'name' : 'positive' , 'x' : [7.8 , 7.8 , None ], 'y' : (6.1 , 5 , None ),
493
+ 'type' : 'scatter' , 'showlegend' : False , 'mode' : 'lines' ,
494
+ 'legendgroup' : 'Increasing' ,
495
+ 'line' : {'color' : 'rgb(44, 160, 44)' }},
496
+ {'name' : 'positive' , 'x' : [8.2 , 8.2 , None ], 'y' : (6.1 , 5 , None ),
497
+ 'type' : 'scatter' , 'fill' : 'tonextx' , 'showlegend' : False ,
498
+ 'line' : {'color' : 'rgb(44, 160, 44)' },
499
+ 'legendgroup' : 'Increasing' , 'mode' : 'lines' },
500
+ {'name' : 'positive' ,
501
+ 'x' : [2 , 2 , None , 2.2 , 1.8 , None , 1.8 , 2.2 , None , 3 , 3 , None , 3.2 ,
502
+ 2.8 , None , 2.8 , 3.2 , None , 4 , 4 , None , 4.2 , 3.8 , None , 3.8 ,
503
+ 4.2 , None , 5 , 5 , None , 5.2 , 4.8 , None , 4.8 , 5.2 , None , 8 , 8 ,
504
+ None , 8.2 , 7.8 , None , 7.8 , 8.2 , None ],
505
+ 'y' : [6.4 , 2 , None , 6.3 , 6.3 , None , 4 , 4 , None , 10 , 7 , None , 10 ,
506
+ 10 , None , 9.3 , 9.3 , None , 10 , 3 , None , 9 , 9 , None , 8.9 , 8.9 ,
507
+ None , 10 , 2 , None , 9.2 , 9.2 , None , 4.9 , 4.9 , None , 7 , 2.3 ,
508
+ None , 6.1 , 6.1 , None , 5 , 5 , None ],
509
+ 'text' : ('High' , 'Low' , None , 'Close' , 'Close' , None ,
510
+ 'Open' , 'Open' , None , 'High' , 'Low' , None ,
511
+ 'Close' , 'Close' , None , 'Open' , 'Open' , None ,
512
+ 'High' , 'Low' , None , 'Close' , 'Close' , None ,
513
+ 'Open' , 'Open' , None , 'High' , 'Low' , None ,
514
+ 'Close' , 'Close' , None , 'Open' , 'Open' , None ,
515
+ 'High' , 'Low' , None , 'Close' , 'Close' , None ,
516
+ 'Open' , 'Open' , None ),
517
+ 'type' : 'scatter' , 'mode' : 'lines' , 'legendgroup' : 'Increasing' ,
518
+ 'line' : {'color' : 'rgb(44, 160, 44)' }},
519
+ {'name' : 'negative' , 'x' : [0.8 , 0.8 , None ], 'y' : (3.3 , 3.3 , None ),
520
+ 'type' : 'scatter' , 'showlegend' : False , 'mode' : 'lines' ,
521
+ 'legendgroup' : 'Decreasing' ,
522
+ 'line' : {'color' : 'rgb(214, 39, 40)' }},
523
+ {'name' : 'negative' , 'x' : [1.2 , 1.2 , None ], 'y' : (3.3 , 3.3 , None ),
524
+ 'type' : 'scatter' , 'fill' : 'tonextx' , 'showlegend' : False ,
525
+ 'line' : {'color' : 'rgb(214, 39, 40)' },
526
+ 'legendgroup' : 'Decreasing' , 'mode' : 'lines' },
527
+ {'name' : 'negative' , 'x' : [5.8 , 5.8 , None ], 'y' : (3 , 9 , None ),
528
+ 'type' : 'scatter' , 'showlegend' : False , 'mode' : 'lines' ,
529
+ 'legendgroup' : 'Decreasing' ,
530
+ 'line' : {'color' : 'rgb(214, 39, 40)' }},
531
+ {'name' : 'negative' , 'x' : [6.2 , 6.2 , None ], 'y' : (3 , 9 , None ),
532
+ 'type' : 'scatter' , 'fill' : 'tonextx' , 'showlegend' : False ,
533
+ 'line' : {'color' : 'rgb(214, 39, 40)' },
534
+ 'legendgroup' : 'Decreasing' , 'mode' : 'lines' },
535
+ {'name' : 'negative' , 'x' : [6.8 , 6.8 , None ], 'y' : (2.9 , 2.9 , None ),
536
+ 'type' : 'scatter' , 'showlegend' : False , 'mode' : 'lines' ,
537
+ 'legendgroup' : 'Decreasing' ,
538
+ 'line' : {'color' : 'rgb(214, 39, 40)' }},
539
+ {'name' : 'negative' , 'x' : [7.2 , 7.2 , None ], 'y' : (2.9 , 2.9 , None ),
540
+ 'type' : 'scatter' , 'fill' : 'tonextx' , 'showlegend' : False ,
541
+ 'line' : {'color' : 'rgb(214, 39, 40)' },
542
+ 'legendgroup' : 'Decreasing' , 'mode' : 'lines' },
543
+ {'name' : 'negative' ,
544
+ 'x' : [1 , 1 , None , 1.2 , 0.8 , None , 0.8 , 1.2 , None , 6 , 6 , None ,
545
+ 6.2 , 5.8 , None , 5.8 , 6.2 , None , 7 , 7 , None , 7.2 , 6.8 , None ,
546
+ 6.8 , 7.2 , None ],
547
+ 'y' : [7 , 3 , None , 3.3 , 3.3 , None , 3.3 , 3.3 , None , 14.6 , 2 , None ,
548
+ 3 , 3 , None , 9 , 9 , None , 12 , 1.1 , None , 2.9 , 2.9 , None , 2.9 ,
549
+ 2.9 , None ],
550
+ 'text' : ('High' , 'Low' , None , 'Close' , 'Close' , None ,
551
+ 'Open' , 'Open' , None , 'High' , 'Low' , None ,
552
+ 'Close' , 'Close' , None , 'Open' , 'Open' , None ,
553
+ 'High' , 'Low' , None , 'Close' , 'Close' , None ,
554
+ 'Open' , 'Open' , None ), 'type' : 'scatter' ,
555
+ 'mode' : 'lines' , 'legendgroup' : 'Decreasing' ,
556
+ 'line' : {'color' : 'rgb(214, 39, 40)' }}]
557
+ self .assertEqual (candl_data , expected_candl_data )
558
+
0 commit comments